gbuffer.glsl (3015B)
1 layout( std140 ) uniform view { 2 mat4 camera_from_world; 3 mat4 clip_from_camera; 4 }; 5 6 layout( std140 ) uniform model { 7 mat4 world_from_model; 8 }; 9 10 uniform sampler2D world_normal; 11 uniform sampler2D world_depth; 12 uniform sampler2D outline_depth; 13 uniform sampler2D blue_noise; 14 15 struct VSOut { 16 vec3 colour; 17 }; 18 19 #ifdef VERTEX_SHADER 20 21 in vec3 position; 22 in vec3 colour; 23 24 out VSOut v2f; 25 26 void main() { 27 gl_Position = clip_from_camera * camera_from_world * world_from_model * vec4( position, 1.0 ); 28 v2f.colour = colour; 29 } 30 31 #else 32 33 in VSOut v2f; 34 35 out vec4 screen_colour; 36 37 float linearize_depth( float depth ) { 38 return ( 2.0 + 0.1 ) / ( 10000.0 + 0.1 - depth * ( 10000.0 - 0.1 ) ); 39 } 40 41 void main() { 42 vec2 pixel = vec2( 1.0 / textureSize( world_normal, 0 ) ); 43 vec3 pole = vec3( -1.0, 0.0, 1.0 ); 44 45 vec2 uv = gl_FragCoord.xy / textureSize( world_normal, 0 ); 46 47 float d0 = linearize_depth( texture( world_depth, uv + pixel.xy * pole.xx ).r ); // x1, y1 48 float d1 = linearize_depth( texture( world_depth, uv + pixel.xy * pole.yx ).r ); // x2, y1 49 float d2 = linearize_depth( texture( world_depth, uv + pixel.xy * pole.zx ).r ); // x3, y1 50 float d3 = linearize_depth( texture( world_depth, uv + pixel.xy * pole.xy ).r ); // x1, y2 51 float d4 = linearize_depth( texture( world_depth, uv + pixel.xy * pole.yy ).r ); // x2, y2 52 float d5 = linearize_depth( texture( world_depth, uv + pixel.xy * pole.zy ).r ); // x3, y2 53 float d6 = linearize_depth( texture( world_depth, uv + pixel.xy * pole.xz ).r ); // x1, y3 54 float d7 = linearize_depth( texture( world_depth, uv + pixel.xy * pole.yz ).r ); // x2, y3 55 float d8 = linearize_depth( texture( world_depth, uv + pixel.xy * pole.zz ).r ); // x3, y3 56 57 float edgeness_depth = ( 58 abs( d1 - d7 ) + 59 abs( d5 - d3 ) + 60 abs( d0 - d8 ) + 61 abs( d2 - d6 ) 62 ); 63 64 vec3 n0 = texture( world_normal, uv + pixel.xy * pole.xx ).rgb; // x1, y1 65 vec3 n1 = texture( world_normal, uv + pixel.xy * pole.yx ).xyz; // x2, y1 66 vec3 n2 = texture( world_normal, uv + pixel.xy * pole.zx ).xyz; // x3, y1 67 vec3 n3 = texture( world_normal, uv + pixel.xy * pole.xy ).xyz; // x1, y2 68 // vec3 n4 = texture( world_normal, uv + pixel.xy * pole.yy ).xyz; // x2, y2 69 vec3 n5 = texture( world_normal, uv + pixel.xy * pole.zy ).xyz; // x3, y2 70 vec3 n6 = texture( world_normal, uv + pixel.xy * pole.xz ).xyz; // x1, y3 71 vec3 n7 = texture( world_normal, uv + pixel.xy * pole.yz ).xyz; // x2, y3 72 vec3 n8 = texture( world_normal, uv + pixel.xy * pole.zz ).xyz; // x3, y3 73 74 float edgeness_normal = ( 75 max( 0.0, 1.0 - dot( n1, n7 ) ) + 76 max( 0.0, 1.0 - dot( n5, n3 ) ) + 77 max( 0.0, 1.0 - dot( n0, n8 ) ) + 78 max( 0.0, 1.0 - dot( n2, n6 ) ) 79 ) * 0.25; 80 81 edgeness_normal = max( edgeness_normal - 0.1, 0.0 ) / 0.9; 82 83 vec3 edgeness = vec3( max( edgeness_depth, edgeness_normal ) ); 84 85 vec3 colour = texture( outline_depth, uv ).r > d4 ? vec3( 1.0, 0.0, 0.0 ) : v2f.colour; 86 87 screen_colour = vec4( colour, 1.0 ); 88 screen_colour += vec4( vec3( d4 / 10.0 ) + get_dither_noise( blue_noise ) + edgeness * vec3( 0.1 ), 1.0 ); 89 } 90 91 #endif