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