 5ed5ed59c3
			
		
	
	5ed5ed59c3
	
	
	
		
			
			This does not address stapling shader in 2.8, though the solution can be similar (own shader, not polutting interlace shader). part of T49043 Reviewers: merwin Differential Revision: https://developer.blender.org/D2440
		
			
				
	
	
		
			263 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			GLSL
		
	
	
	
	
	
			
		
		
	
	
			263 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			GLSL
		
	
	
	
	
	
| 
 | |
| /* Options:
 | |
|  *
 | |
|  * USE_COLOR: use glColor for diffuse colors
 | |
|  * USE_TEXTURE: use texture for diffuse colors
 | |
|  * USE_TEXTURE_RECTANGLE: use GL_TEXTURE_RECTANGLE instead of GL_TEXTURE_2D
 | |
|  * 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
 | |
| 
 | |
| /* 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
 | |
| 
 | |
| #if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING)
 | |
| #if defined(USE_FLAT_NORMAL)
 | |
| varying vec3 eyespace_vert_pos;
 | |
| #else
 | |
| varying vec3 varying_normal;
 | |
| #endif
 | |
| #ifndef USE_SOLID_LIGHTING
 | |
| varying vec3 varying_position;
 | |
| #endif
 | |
| #endif
 | |
| 
 | |
| #ifdef USE_COLOR
 | |
| varying vec4 varying_vertex_color;
 | |
| #endif
 | |
| 
 | |
| #ifdef USE_TEXTURE
 | |
| #ifdef USE_TEXTURE_RECTANGLE
 | |
| #define sampler2D_default sampler2DRect
 | |
| #define texture2D_default texture2DRect
 | |
| #else
 | |
| #define sampler2D_default sampler2D
 | |
| #define texture2D_default texture2D
 | |
| #endif
 | |
| 
 | |
| varying vec2 varying_texture_coord;
 | |
| uniform sampler2D_default texture_map;
 | |
| #endif
 | |
| 
 | |
| #ifdef USE_STIPPLE
 | |
| uniform int stipple_id;
 | |
| #if defined(DRAW_LINE)
 | |
| varying float t;
 | |
| uniform int stipple_pattern;
 | |
| #endif
 | |
| #endif
 | |
| 
 | |
| void main()
 | |
| {
 | |
| #if defined(USE_STIPPLE)
 | |
| #if defined(DRAW_LINE)
 | |
| 	/* GLSL 1.3 */
 | |
| 	if (!bool((1 << int(mod(t, 16))) & stipple_pattern))
 | |
| 		discard;
 | |
| #else
 | |
| 	/* We have to use mod function and integer casting.
 | |
| 	 * This can be optimized further with the bitwise operations
 | |
| 	 * when GLSL 1.3 is supported. */
 | |
| 	if (stipple_id == STIPPLE_HALFTONE) {
 | |
| 		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) {
 | |
| 		int result = int(mod(int(gl_FragCoord.x) / 8 + int(gl_FragCoord.y) / 8, 2));
 | |
| 		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;
 | |
| 		}
 | |
| 	}
 | |
| #endif /* !DRAW_LINE */
 | |
| #endif /* USE_STIPPLE */
 | |
| 
 | |
| #if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING)
 | |
| 	/* compute normal */
 | |
| #if defined(USE_FLAT_NORMAL)
 | |
| 	vec3 N = normalize(cross(dFdx(eyespace_vert_pos), dFdy(eyespace_vert_pos)));
 | |
| #else
 | |
| 	vec3 N = normalize(varying_normal);
 | |
| #endif
 | |
| 
 | |
| #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_default(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_default(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_default(texture_map, varying_texture_coord) * varying_vertex_color;
 | |
| #elif defined(USE_TEXTURE)
 | |
| 	gl_FragColor = texture2D_default(texture_map, varying_texture_coord);
 | |
| #elif defined(USE_COLOR)
 | |
| 	gl_FragColor = varying_vertex_color;
 | |
| #else
 | |
| 	gl_FragColor = gl_FrontMaterial.diffuse;
 | |
| #endif
 | |
| 
 | |
| #endif
 | |
| }
 | |
| 
 |