shadowed_vertex_colours_to_gbuffer.glsl (2388B)
1 layout( std140 ) uniform model { 2 mat4 M; 3 }; 4 5 layout( std140 ) uniform view { 6 mat4 V; 7 mat4 P; 8 vec3 camera_pos; 9 }; 10 11 layout( std140 ) uniform light_view { 12 mat4 lightVP; 13 vec3 light_pos; 14 }; 15 16 uniform sampler2D shadowmap; 17 uniform sampler2D dither_noise; 18 19 struct VSOut { 20 vec4 light_space_position; 21 vec3 position; 22 vec3 normal; 23 vec3 colour; 24 }; 25 26 #ifdef VERTEX_SHADER 27 28 in vec3 position; 29 in vec3 normal; 30 in vec3 colour; 31 32 out VSOut v2f; 33 34 void main() { 35 vec4 world_space = M * vec4( position, 1.0 ); 36 gl_Position = P * V * world_space; 37 v2f.light_space_position = lightVP * world_space; 38 v2f.position = world_space.xyz; 39 v2f.normal = mat3( M ) * normal; 40 v2f.colour = colour; 41 } 42 43 #else 44 45 in VSOut v2f; 46 out vec4 output_albedo; 47 out vec3 output_normal; 48 49 // http://the-witness.net/news/2013/09/shadow-mapping-summary-part-1/ 50 vec2 get_shadow_offsets( vec3 N, vec3 L ) { 51 float cos_alpha = dot_sat( N, L ); 52 float offset_scale_N = sqrt( 1.0 - cos_alpha * cos_alpha ); 53 float offset_scale_L = offset_scale_N / cos_alpha; 54 return vec2( offset_scale_N, min( 5.0, offset_scale_L ) ); 55 } 56 57 void main() { 58 vec3 light_colour = vec3( 400.0, 400.0, 400.0 ); 59 vec3 lightdir = normalize( light_pos - v2f.position ); 60 vec3 to_camera = normalize( camera_pos - v2f.position ); 61 vec3 normal = normalize( v2f.normal ); 62 63 vec3 light_ndc = v2f.light_space_position.xyz / v2f.light_space_position.w; 64 vec3 light_norm = light_ndc * 0.5 + 0.5; 65 vec2 offsets = get_shadow_offsets( normal, lightdir ); 66 float bias = 0.00002 + 0.00001 * offsets.x + 0.00005 * offsets.y; 67 68 float shadow = 0; 69 70 if( light_norm.z > 1.0 ) { 71 shadow = 1.0; 72 } 73 else { 74 vec2 inv_shadowmap_size = 1.0 / textureSize( shadowmap, 0 ); 75 for( int x = -1; x <= 1; x++ ) { 76 for( int y = -1; y <= 1; y++ ) { 77 vec2 offset = vec2( x, y ) * inv_shadowmap_size; 78 float shadow_depth = texture( shadowmap, light_norm.xy + offset ).r; 79 if( light_norm.z - bias <= shadow_depth ) { 80 shadow += 1.0 / 9.0; 81 } 82 } 83 } 84 } 85 86 vec3 noise = texture( dither_noise, gl_FragCoord.xy / textureSize( dither_noise, 0 ) ).xxx; 87 noise = ( noise - vec3( 0.5 ) ) / 128.0; 88 89 vec3 ambient = vec3( 0.03 ) * v2f.colour; 90 vec3 Lo = cook_torrance_brdf( to_camera, v2f.position, normal, light_pos, light_colour, v2f.colour, 0.75, 0.0 ); 91 92 output_albedo = vec4( linear_to_srgb( reinhard_tonemap( ambient + Lo * shadow + noise ) ), 1.0 ); 93 output_normal = normal; 94 } 95 96 #endif