170 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			GLSL
		
	
	
	
	
	
			
		
		
	
	
			170 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			GLSL
		
	
	
	
	
	
 | 
						|
/* Options:
 | 
						|
 *
 | 
						|
 * USE_COLOR: use glColor for diffuse colors
 | 
						|
 * USE_TEXTURE: use texture for diffuse colors
 | 
						|
 * USE_SCENE_LIGHTING: use lights (up to 8)
 | 
						|
 * USE_SOLID_LIGHTING: assume 3 directional lights for solid draw mode
 | 
						|
 * USE_TWO_SIDED: flip normal towards viewer
 | 
						|
 * NO_SPECULAR: use specular component
 | 
						|
 */
 | 
						|
 | 
						|
#define NUM_SOLID_LIGHTS 3
 | 
						|
#define NUM_SCENE_LIGHTS 8
 | 
						|
 | 
						|
#if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING)
 | 
						|
varying vec3 varying_normal;
 | 
						|
 | 
						|
#ifndef USE_SOLID_LIGHTING
 | 
						|
varying vec3 varying_position;
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef USE_COLOR
 | 
						|
varying vec4 varying_vertex_color;
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef USE_TEXTURE
 | 
						|
varying vec2 varying_texture_coord;
 | 
						|
uniform sampler2D texture_map;
 | 
						|
#endif
 | 
						|
 | 
						|
void main()
 | 
						|
{
 | 
						|
#if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING)
 | 
						|
	/* compute normal */
 | 
						|
	vec3 N = normalize(varying_normal);
 | 
						|
 | 
						|
#ifdef USE_TWO_SIDED
 | 
						|
	if (!gl_FrontFacing)
 | 
						|
		N = -N;
 | 
						|
#endif
 | 
						|
 | 
						|
	/* compute diffuse and specular lighting */
 | 
						|
	vec3 L_diffuse = vec3(0.0);
 | 
						|
#ifndef NO_SPECULAR
 | 
						|
	vec3 L_specular = vec3(0.0);
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef USE_SOLID_LIGHTING
 | 
						|
	/* assume 3 directional lights */
 | 
						|
	for (int i = 0; i < NUM_SOLID_LIGHTS; i++) {
 | 
						|
		vec3 light_direction = gl_LightSource[i].position.xyz;
 | 
						|
 | 
						|
		/* diffuse light */
 | 
						|
		vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
 | 
						|
		float diffuse_bsdf = max(dot(N, light_direction), 0.0);
 | 
						|
		L_diffuse += light_diffuse*diffuse_bsdf;
 | 
						|
 | 
						|
#ifndef NO_SPECULAR
 | 
						|
		/* specular light */
 | 
						|
		vec3 light_specular = gl_LightSource[i].specular.rgb;
 | 
						|
		vec3 H = gl_LightSource[i].halfVector.xyz;
 | 
						|
 | 
						|
		float specular_bsdf = pow(max(dot(N, H), 0.0), gl_FrontMaterial.shininess);
 | 
						|
		L_specular += light_specular*specular_bsdf;
 | 
						|
#endif
 | 
						|
	}
 | 
						|
#else
 | 
						|
	/* all 8 lights, makes no assumptions, potentially slow */
 | 
						|
 | 
						|
#ifndef NO_SPECULAR
 | 
						|
	/* view vector computation, depends on orthographics or perspective */
 | 
						|
	vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(varying_position): vec3(0.0, 0.0, -1.0);
 | 
						|
#endif
 | 
						|
 | 
						|
	for (int i = 0; i < NUM_SCENE_LIGHTS; i++) {
 | 
						|
		/* todo: this is a slow check for disabled lights */
 | 
						|
		if (gl_LightSource[i].specular.a == 0.0)
 | 
						|
			continue;
 | 
						|
 | 
						|
		float intensity = 1.0;
 | 
						|
		vec3 light_direction;
 | 
						|
 | 
						|
		if (gl_LightSource[i].position.w == 0.0) {
 | 
						|
			/* directional light */
 | 
						|
			light_direction = gl_LightSource[i].position.xyz;
 | 
						|
		}
 | 
						|
		else {
 | 
						|
			/* point light */
 | 
						|
			vec3 d = gl_LightSource[i].position.xyz - varying_position;
 | 
						|
			light_direction = normalize(d);
 | 
						|
 | 
						|
			/* spot light cone */
 | 
						|
			if (gl_LightSource[i].spotCutoff < 90.0) {
 | 
						|
				float cosine = max(dot(light_direction, -gl_LightSource[i].spotDirection), 0.0);
 | 
						|
				intensity = pow(cosine, gl_LightSource[i].spotExponent);
 | 
						|
				intensity *= step(gl_LightSource[i].spotCosCutoff, cosine);
 | 
						|
			}
 | 
						|
 | 
						|
			/* falloff */
 | 
						|
			float distance = length(d);
 | 
						|
 | 
						|
			intensity /= gl_LightSource[i].constantAttenuation +
 | 
						|
				gl_LightSource[i].linearAttenuation * distance +
 | 
						|
				gl_LightSource[i].quadraticAttenuation * distance * distance;
 | 
						|
		}
 | 
						|
 | 
						|
		/* diffuse light */
 | 
						|
		vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
 | 
						|
		float diffuse_bsdf = max(dot(N, light_direction), 0.0);
 | 
						|
		L_diffuse += light_diffuse*diffuse_bsdf*intensity;
 | 
						|
 | 
						|
#ifndef NO_SPECULAR
 | 
						|
		/* specular light */
 | 
						|
		vec3 light_specular = gl_LightSource[i].specular.rgb;
 | 
						|
		vec3 H = normalize(light_direction - V);
 | 
						|
 | 
						|
		float specular_bsdf = pow(max(dot(N, H), 0.0), gl_FrontMaterial.shininess);
 | 
						|
		L_specular += light_specular*specular_bsdf*intensity;
 | 
						|
#endif
 | 
						|
	}
 | 
						|
#endif
 | 
						|
 | 
						|
	/* compute diffuse color, possibly from texture or vertex colors */
 | 
						|
	float alpha;
 | 
						|
 | 
						|
#if defined(USE_TEXTURE) && defined(USE_COLOR)
 | 
						|
	vec4 texture_color = texture2D(texture_map, varying_texture_coord);
 | 
						|
 | 
						|
	L_diffuse *= texture_color.rgb * varying_vertex_color.rgb;
 | 
						|
	alpha = texture_color.a * varying_vertex_color.a;
 | 
						|
#elif defined(USE_TEXTURE)
 | 
						|
	vec4 texture_color = texture2D(texture_map, varying_texture_coord);
 | 
						|
 | 
						|
	L_diffuse *= texture_color.rgb;
 | 
						|
	alpha = texture_color.a;
 | 
						|
#elif defined(USE_COLOR)
 | 
						|
	L_diffuse *= varying_vertex_color.rgb;
 | 
						|
	alpha = varying_vertex_color.a;
 | 
						|
#else
 | 
						|
	L_diffuse *= gl_FrontMaterial.diffuse.rgb;
 | 
						|
	alpha = gl_FrontMaterial.diffuse.a;
 | 
						|
#endif
 | 
						|
 | 
						|
	/* sum lighting */
 | 
						|
	vec3 L = gl_FrontLightModelProduct.sceneColor.rgb + L_diffuse;
 | 
						|
 | 
						|
#ifndef NO_SPECULAR
 | 
						|
	L += L_specular*gl_FrontMaterial.specular.rgb;
 | 
						|
#endif
 | 
						|
 | 
						|
	/* write out fragment color */
 | 
						|
	gl_FragColor = vec4(L, alpha);
 | 
						|
#else
 | 
						|
 | 
						|
	/* no lighting */
 | 
						|
#if defined(USE_TEXTURE) && defined(USE_COLOR)
 | 
						|
	gl_FragColor = texture2D(texture_map, varying_texture_coord) * varying_vertex_color;
 | 
						|
#elif defined(USE_TEXTURE)
 | 
						|
	gl_FragColor = texture2D(texture_map, varying_texture_coord);
 | 
						|
#elif defined(USE_COLOR)
 | 
						|
	gl_FragColor = varying_vertex_color;
 | 
						|
#else
 | 
						|
	gl_FragColor = gl_FrontMaterial.diffuse;
 | 
						|
#endif
 | 
						|
 | 
						|
#endif
 | 
						|
}
 | 
						|
 |