clipmap.glsl (2141B)
1 layout( std140 ) uniform view { 2 mat4 V; 3 mat4 P; 4 vec3 camera_pos; 5 }; 6 7 layout( std140 ) uniform model { 8 mat4 M; 9 }; 10 11 layout( std140 ) uniform sun { 12 vec3 sun_dir; 13 float sun_angle; 14 }; 15 16 layout( std140 ) uniform clipmap { 17 vec2 offset; 18 float scale; 19 }; 20 21 struct VSOut { 22 vec4 view_position; 23 vec3 world_position; 24 vec2 uv; 25 }; 26 27 uniform sampler2D heightmap; 28 uniform sampler2D normalmap; 29 uniform sampler2D horizonmap; 30 uniform sampler2D blue_noise; 31 32 #ifdef VERTEX_SHADER 33 34 in vec3 position; 35 out VSOut v2f; 36 37 void main() { 38 vec2 xy = offset + ( M * vec4( position, 1.0 ) ).xy * scale; 39 vec2 uv = ( xy + 0.5 ) / textureSize( heightmap, 0 ); 40 vec2 height_sample = texelFetch( heightmap, ivec2( xy ), 0 ).rg; 41 float z = 256.0 * height_sample.r + height_sample.g; 42 43 v2f.view_position = V * vec4( xy, z, 1.0 ); 44 v2f.world_position = vec3( xy, z ); 45 v2f.uv = uv; 46 gl_Position = P * v2f.view_position; 47 } 48 49 #else 50 51 in VSOut v2f; 52 out vec4 screen_colour; 53 54 void main() { 55 vec2 normal_xy = texture( normalmap, v2f.uv ).xy * 2.0 - 1.0; 56 float normal_z = sqrt( 1.0 - normal_xy.x * normal_xy.x - normal_xy.y * normal_xy.y ); 57 vec3 normal = vec3( normal_xy.x, normal_xy.y, normal_z ); 58 59 float horizon = texture( horizonmap, v2f.uv ).r; 60 61 // ground colour 62 vec3 ground; 63 if( v2f.world_position.z > 175 ) { 64 // snow/rocks 65 if( normal.z > 0.5 ) { 66 ground = vec3( 0.8, 0.8, 0.8 ); 67 } 68 else { 69 ground = vec3( 0.6, 0.6, 0.6 ); 70 } 71 } 72 else if( v2f.world_position.z < 5 ) { 73 ground = vec3( 0.0, 0.25, 1.0 ); 74 } 75 else { 76 if( normal.z > 0.8 ) { 77 ground = vec3( 0.4, 1.0, 0.4 ); 78 } 79 else { 80 ground = vec3( 0.7, 0.7, 0.5 ); 81 } 82 } 83 84 // sunlight + sky ambient lighting 85 // area of a chord is somewhat similar to smoothstep 86 float sun_visible_fraction = smoothstep( -0.1, 0.2, sun_angle - horizon ); 87 float sunlight_lambert = max( 0, dot( normal, sun_dir ) ); 88 vec3 sunlight = sun_visible_fraction * sunlight_lambert * vec3( 0.9, 0.9, 0.5 ); 89 vec3 ambient = vec3( 0.05, 0.05, 0.15 ); 90 91 vec3 c = ( sunlight + ambient ) * ground; 92 93 screen_colour = vec4( linear_to_srgb( apply_fog( c + get_dither_noise( blue_noise ), length( v2f.view_position ) ) ), 1.0 ); 94 } 95 96 #endif