| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Options: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * USE_COLOR: use glColor for diffuse colors | 
					
						
							|  |  |  |  * USE_TEXTURE: use texture for diffuse colors | 
					
						
							| 
									
										
										
										
											2016-06-08 05:39:22 +10:00
										 |  |  |  * USE_TEXTURE_RECTANGLE: use GL_TEXTURE_RECTANGLE instead of GL_TEXTURE_2D | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  |  * 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-25 22:57:50 +01:00
										 |  |  | /* Keep these in sync with GPU_basic_shader.h */ | 
					
						
							|  |  |  | #define STIPPLE_HALFTONE                               0 | 
					
						
							|  |  |  | #define STIPPLE_QUARTTONE                              1 | 
					
						
							|  |  |  | #define STIPPLE_CHECKER_8PX                            2 | 
					
						
							|  |  |  | #define STIPPLE_HEXAGON                                3 | 
					
						
							|  |  |  | #define STIPPLE_DIAG_STRIPES                           4 | 
					
						
							|  |  |  | #define STIPPLE_DIAG_STRIPES_SWAP                      5 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-26 21:19:23 -04:00
										 |  |  | #ifndef NO_SPECULAR | 
					
						
							|  |  |  | uniform mat4 ProjectionMatrix; | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | #if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING) | 
					
						
							| 
									
										
										
										
											2016-05-16 11:13:21 +03:00
										 |  |  | #if defined(USE_FLAT_NORMAL) | 
					
						
							|  |  |  | varying vec3 eyespace_vert_pos; | 
					
						
							|  |  |  | #else | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | varying vec3 varying_normal; | 
					
						
							| 
									
										
										
										
											2016-05-16 11:13:21 +03:00
										 |  |  | #endif | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | #ifndef USE_SOLID_LIGHTING | 
					
						
							|  |  |  | varying vec3 varying_position; | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_COLOR | 
					
						
							|  |  |  | varying vec4 varying_vertex_color; | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef USE_TEXTURE | 
					
						
							| 
									
										
										
										
											2016-06-08 05:39:22 +10:00
										 |  |  | #ifdef USE_TEXTURE_RECTANGLE | 
					
						
							|  |  |  | #define sampler2D_default sampler2DRect | 
					
						
							|  |  |  | #define texture2D_default texture2DRect | 
					
						
							|  |  |  | #else | 
					
						
							|  |  |  | #define sampler2D_default sampler2D | 
					
						
							|  |  |  | #define texture2D_default texture2D | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | varying vec2 varying_texture_coord; | 
					
						
							| 
									
										
										
										
											2016-06-08 05:39:22 +10:00
										 |  |  | uniform sampler2D_default texture_map; | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-25 22:57:50 +01:00
										 |  |  | #ifdef USE_STIPPLE | 
					
						
							|  |  |  | uniform int stipple_id; | 
					
						
							| 
									
										
										
										
											2016-04-08 10:58:40 +03:00
										 |  |  | #if defined(DRAW_LINE) | 
					
						
							| 
									
										
										
										
											2016-09-27 21:05:48 +02:00
										 |  |  | varying float t; | 
					
						
							| 
									
										
										
										
											2016-04-08 10:58:40 +03:00
										 |  |  | uniform int stipple_pattern; | 
					
						
							|  |  |  | #endif | 
					
						
							| 
									
										
										
										
											2015-12-25 22:57:50 +01:00
										 |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | void main() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-12-25 22:57:50 +01:00
										 |  |  | #if defined(USE_STIPPLE) | 
					
						
							| 
									
										
										
										
											2016-04-08 10:58:40 +03:00
										 |  |  | #if defined(DRAW_LINE) | 
					
						
							| 
									
										
										
										
											2016-05-23 19:56:50 +10:00
										 |  |  | 	/* GLSL 1.3 */ | 
					
						
							|  |  |  | 	if (!bool((1 << int(mod(t, 16))) & stipple_pattern)) | 
					
						
							|  |  |  | 		discard; | 
					
						
							| 
									
										
										
										
											2016-04-08 10:58:40 +03:00
										 |  |  | #else | 
					
						
							| 
									
										
										
										
											2016-05-23 19:56:50 +10:00
										 |  |  | 	/* We have to use mod function and integer casting. | 
					
						
							|  |  |  | 	 * This can be optimized further with the bitwise operations | 
					
						
							|  |  |  | 	 * when GLSL 1.3 is supported. */ | 
					
						
							| 
									
										
										
										
											2017-01-09 17:58:13 +01:00
										 |  |  | 	if (stipple_id == STIPPLE_HALFTONE) { | 
					
						
							| 
									
										
										
										
											2016-05-23 19:56:50 +10:00
										 |  |  | 		int result = int(mod(gl_FragCoord.x + gl_FragCoord.y, 2)); | 
					
						
							|  |  |  | 		bool dis = result == 0; | 
					
						
							|  |  |  | 		if (dis) | 
					
						
							|  |  |  | 			discard; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (stipple_id == STIPPLE_QUARTTONE) { | 
					
						
							|  |  |  | 		int mody = int(mod(gl_FragCoord.y, 4)); | 
					
						
							|  |  |  | 		int modx = int(mod(gl_FragCoord.x, 4)); | 
					
						
							|  |  |  | 		if (mody == 0) { | 
					
						
							|  |  |  | 			if (modx != 2) | 
					
						
							|  |  |  | 				discard; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (mody == 2) { | 
					
						
							|  |  |  | 			if (modx != 0) | 
					
						
							|  |  |  | 				discard; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			discard; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (stipple_id == STIPPLE_CHECKER_8PX) { | 
					
						
							| 
									
										
										
										
											2016-05-26 18:46:12 +10:00
										 |  |  | 		int result = int(mod(int(gl_FragCoord.x) / 8 + int(gl_FragCoord.y) / 8, 2)); | 
					
						
							| 
									
										
										
										
											2016-05-23 19:56:50 +10:00
										 |  |  | 		if (result != 0) | 
					
						
							|  |  |  | 			discard; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (stipple_id == STIPPLE_DIAG_STRIPES) { | 
					
						
							|  |  |  | 		int mody = int(mod(gl_FragCoord.y, 16)); | 
					
						
							|  |  |  | 		int modx = int(mod(gl_FragCoord.x, 16)); | 
					
						
							|  |  |  | 		if ((16 - modx > mody && mody > 8 - modx) || mody > 24 - modx) | 
					
						
							|  |  |  | 			discard; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (stipple_id == STIPPLE_DIAG_STRIPES_SWAP) { | 
					
						
							|  |  |  | 		int mody = int(mod(gl_FragCoord.y, 16)); | 
					
						
							|  |  |  | 		int modx = int(mod(gl_FragCoord.x, 16)); | 
					
						
							|  |  |  | 		if (!((16 - modx > mody && mody > 8 - modx) || mody > 24 - modx)) | 
					
						
							|  |  |  | 			discard; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (stipple_id == STIPPLE_HEXAGON) { | 
					
						
							|  |  |  | 		int mody = int(mod(gl_FragCoord.y, 2)); | 
					
						
							|  |  |  | 		int modx = int(mod(gl_FragCoord.x, 4)); | 
					
						
							|  |  |  | 		if (mody != 0) { | 
					
						
							|  |  |  | 			if (modx != 1) | 
					
						
							|  |  |  | 				discard; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			if (modx != 3) | 
					
						
							|  |  |  | 				discard; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-04-08 10:58:40 +03:00
										 |  |  | #endif /* !DRAW_LINE */ | 
					
						
							|  |  |  | #endif /* USE_STIPPLE */ | 
					
						
							| 
									
										
										
										
											2015-12-25 22:57:50 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | #if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING) | 
					
						
							|  |  |  | 	/* compute normal */ | 
					
						
							| 
									
										
										
										
											2016-05-16 11:13:21 +03:00
										 |  |  | #if defined(USE_FLAT_NORMAL) | 
					
						
							|  |  |  | 	vec3 N = normalize(cross(dFdx(eyespace_vert_pos), dFdy(eyespace_vert_pos))); | 
					
						
							|  |  |  | #else | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | 	vec3 N = normalize(varying_normal); | 
					
						
							| 
									
										
										
										
											2016-05-16 11:13:21 +03:00
										 |  |  | #endif | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #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); | 
					
						
							| 
									
										
										
										
											2016-05-26 18:46:12 +10:00
										 |  |  | 		L_diffuse += light_diffuse * diffuse_bsdf; | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #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); | 
					
						
							| 
									
										
										
										
											2016-05-26 18:46:12 +10:00
										 |  |  | 		L_specular += light_specular * specular_bsdf; | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | #endif | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #else | 
					
						
							|  |  |  | 	/* all 8 lights, makes no assumptions, potentially slow */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef NO_SPECULAR | 
					
						
							|  |  |  | 	/* view vector computation, depends on orthographics or perspective */ | 
					
						
							| 
									
										
										
										
											2017-03-26 21:19:23 -04:00
										 |  |  | 	vec3 V = (ProjectionMatrix[3][3] == 0.0) ? normalize(varying_position) : vec3(0.0, 0.0, -1.0); | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | #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 + | 
					
						
							| 
									
										
										
										
											2016-05-26 18:46:12 +10:00
										 |  |  | 			             gl_LightSource[i].linearAttenuation * distance + | 
					
						
							|  |  |  | 			             gl_LightSource[i].quadraticAttenuation * distance * distance; | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* diffuse light */ | 
					
						
							|  |  |  | 		vec3 light_diffuse = gl_LightSource[i].diffuse.rgb; | 
					
						
							|  |  |  | 		float diffuse_bsdf = max(dot(N, light_direction), 0.0); | 
					
						
							| 
									
										
										
										
											2016-05-26 18:46:12 +10:00
										 |  |  | 		L_diffuse += light_diffuse * diffuse_bsdf * intensity; | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #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); | 
					
						
							| 
									
										
										
										
											2016-05-26 18:46:12 +10:00
										 |  |  | 		L_specular += light_specular * specular_bsdf * intensity; | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | #endif | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* compute diffuse color, possibly from texture or vertex colors */ | 
					
						
							|  |  |  | 	float alpha; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(USE_TEXTURE) && defined(USE_COLOR) | 
					
						
							| 
									
										
										
										
											2016-06-08 05:39:22 +10:00
										 |  |  | 	vec4 texture_color = texture2D_default(texture_map, varying_texture_coord); | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	L_diffuse *= texture_color.rgb * varying_vertex_color.rgb; | 
					
						
							|  |  |  | 	alpha = texture_color.a * varying_vertex_color.a; | 
					
						
							|  |  |  | #elif defined(USE_TEXTURE) | 
					
						
							| 
									
										
										
										
											2016-06-08 05:39:22 +10:00
										 |  |  | 	vec4 texture_color = texture2D_default(texture_map, varying_texture_coord); | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	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 | 
					
						
							| 
									
										
										
										
											2016-05-26 18:46:12 +10:00
										 |  |  | 	L += L_specular * gl_FrontMaterial.specular.rgb; | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* write out fragment color */ | 
					
						
							|  |  |  | 	gl_FragColor = vec4(L, alpha); | 
					
						
							|  |  |  | #else | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* no lighting */ | 
					
						
							|  |  |  | #if defined(USE_TEXTURE) && defined(USE_COLOR) | 
					
						
							| 
									
										
										
										
											2016-06-08 05:39:22 +10:00
										 |  |  | 	gl_FragColor = texture2D_default(texture_map, varying_texture_coord) * varying_vertex_color; | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | #elif defined(USE_TEXTURE) | 
					
						
							| 
									
										
										
										
											2016-06-08 05:39:22 +10:00
										 |  |  | 	gl_FragColor = texture2D_default(texture_map, varying_texture_coord); | 
					
						
							| 
									
										
										
										
											2013-02-26 00:49:42 +00:00
										 |  |  | #elif defined(USE_COLOR) | 
					
						
							|  |  |  | 	gl_FragColor = varying_vertex_color; | 
					
						
							|  |  |  | #else | 
					
						
							|  |  |  | 	gl_FragColor = gl_FrontMaterial.diffuse; | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | } |