medfall

A super great game engine
Log | Files | Refs

commit 6cbdbf980b88131bf236b8125b7691597c37b09b
parent 35b2a106a6a3ec3b8b0a57040e5d49ad38717659
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Tue, 28 May 2019 16:45:07 +0300

.

Diffstat:
Ashaders/shadowed_vertex_colours_to_gbuffer.glsl | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 96 insertions(+), 0 deletions(-)

diff --git a/shaders/shadowed_vertex_colours_to_gbuffer.glsl b/shaders/shadowed_vertex_colours_to_gbuffer.glsl @@ -0,0 +1,96 @@ +layout( std140 ) uniform model { + mat4 M; +}; + +layout( std140 ) uniform view { + mat4 V; + mat4 P; + vec3 camera_pos; +}; + +layout( std140 ) uniform light_view { + mat4 lightVP; + vec3 light_pos; +}; + +uniform sampler2D shadowmap; +uniform sampler2D dither_noise; + +struct VSOut { + vec4 light_space_position; + vec3 position; + vec3 normal; + vec3 colour; +}; + +#ifdef VERTEX_SHADER + +in vec3 position; +in vec3 normal; +in vec3 colour; + +out VSOut v2f; + +void main() { + vec4 world_space = M * vec4( position, 1.0 ); + gl_Position = P * V * world_space; + v2f.light_space_position = lightVP * world_space; + v2f.position = world_space.xyz; + v2f.normal = mat3( M ) * normal; + v2f.colour = colour; +} + +#else + +in VSOut v2f; +out vec4 output_albedo; +out vec3 output_normal; + +// http://the-witness.net/news/2013/09/shadow-mapping-summary-part-1/ +vec2 get_shadow_offsets( vec3 N, vec3 L ) { + float cos_alpha = dot_sat( N, L ); + float offset_scale_N = sqrt( 1.0 - cos_alpha * cos_alpha ); + float offset_scale_L = offset_scale_N / cos_alpha; + return vec2( offset_scale_N, min( 5.0, offset_scale_L ) ); +} + +void main() { + vec3 light_colour = vec3( 400.0, 400.0, 400.0 ); + vec3 lightdir = normalize( light_pos - v2f.position ); + vec3 to_camera = normalize( camera_pos - v2f.position ); + vec3 normal = normalize( v2f.normal ); + + vec3 light_ndc = v2f.light_space_position.xyz / v2f.light_space_position.w; + vec3 light_norm = light_ndc * 0.5 + 0.5; + vec2 offsets = get_shadow_offsets( normal, lightdir ); + float bias = 0.00002 + 0.00001 * offsets.x + 0.00005 * offsets.y; + + float shadow = 0; + + if( light_norm.z > 1.0 ) { + shadow = 1.0; + } + else { + vec2 inv_shadowmap_size = 1.0 / textureSize( shadowmap, 0 ); + for( int x = -1; x <= 1; x++ ) { + for( int y = -1; y <= 1; y++ ) { + vec2 offset = vec2( x, y ) * inv_shadowmap_size; + float shadow_depth = texture( shadowmap, light_norm.xy + offset ).r; + if( light_norm.z - bias <= shadow_depth ) { + shadow += 1.0 / 9.0; + } + } + } + } + + vec3 noise = texture( dither_noise, gl_FragCoord.xy / textureSize( dither_noise, 0 ) ).xxx; + noise = ( noise - vec3( 0.5 ) ) / 128.0; + + vec3 ambient = vec3( 0.03 ) * v2f.colour; + vec3 Lo = cook_torrance_brdf( to_camera, v2f.position, normal, light_pos, light_colour, v2f.colour, 0.75, 0.0 ); + + output_albedo = vec4( linear_to_srgb( reinhard_tonemap( ambient + Lo * shadow + noise ) ), 1.0 ); + output_normal = normal; +} + +#endif