diff options
Diffstat (limited to 'source/blender/gpu/shaders/gpu_shader_basic_frag.glsl')
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_basic_frag.glsl | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/source/blender/gpu/shaders/gpu_shader_basic_frag.glsl b/source/blender/gpu/shaders/gpu_shader_basic_frag.glsl new file mode 100644 index 00000000000..94c73d9e248 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_basic_frag.glsl @@ -0,0 +1,169 @@ + +/* 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 +} + |