medfall

A super great game engine
Log | Files | Refs

terrain.glsl (2459B)


      1 struct VSOut {
      2 	vec4 view_position;
      3 	vec3 world_position;
      4 };
      5 
      6 #ifdef VERTEX_SHADER
      7 
      8 in vec3 position;
      9 out VSOut v2f;
     10 
     11 layout( std140 ) uniform view {
     12 	mat4 V;
     13 	mat4 P;
     14 };
     15 
     16 void main() {
     17 	v2f.world_position = position;
     18 	v2f.view_position = V * vec4( position, 1.0 );
     19 	gl_Position = P * v2f.view_position;
     20 }
     21 
     22 #else
     23 
     24 in VSOut v2f;
     25 out vec4 colour;
     26 
     27 layout( std140 ) uniform sun {
     28 	vec3 sun_dir;
     29 	float sun_angle;
     30 };
     31 
     32 uniform sampler2D normals;
     33 uniform sampler2D horizons;
     34 uniform sampler2D blue_noise;
     35 
     36 // uniform usamplerBuffer point_light_counts_and_offsets;
     37 // uniform usamplerBuffer point_light_indices;
     38 uniform samplerBuffer point_light_origins;
     39 uniform samplerBuffer point_light_colours;
     40 
     41 void main() {
     42 	vec2 world_pos = mod( v2f.world_position.xy, textureSize( normals, 0 ) - ivec2( 1, 1 ) );
     43 
     44 	vec3 normal = normalize( texture( normals, world_pos / textureSize( normals, 0 ) ).xyz );
     45 	float horizon_angle = texture( horizons, world_pos / textureSize( horizons, 0 ) ).r;
     46 
     47 	// ground colour
     48 	vec3 ground;
     49 	if( v2f.world_position.z > 175 ) {
     50 		// snow/rocks
     51 		if( normal.z > 0.5 ) {
     52 			ground = vec3( 0.8, 0.8, 0.8 );
     53 		}
     54 		else {
     55 			ground = vec3( 0.6, 0.6, 0.6 );
     56 		}
     57 	}
     58 	else if( v2f.world_position.z < 5 ) {
     59 		ground = vec3( 0.0, 0.25, 1.0 );
     60 	}
     61 	else {
     62 		if( normal.z > 0.8 ) {
     63 			ground = vec3( 0.4, 1.0, 0.4 );
     64 		}
     65 		else {
     66 			ground = vec3( 0.7, 0.7, 0.5 );
     67 		}
     68 	}
     69 
     70 	// sunlight + sky ambient lighting
     71 	// area of a chord is somewhat similar to smoothstep
     72 	float sun_visible_fraction = smoothstep( -0.2, 0.2, sun_angle - horizon_angle );
     73 	float sunlight_lambert = max( 0, dot( normal, sun_dir ) );
     74 	vec3 sunlight = sun_visible_fraction * sunlight_lambert * vec3( 0.9, 0.9, 0.5 );
     75 	vec3 ambient = vec3( 0.05, 0.05, 0.15 );
     76 
     77 	vec3 c = ( sunlight + ambient ) * ground;
     78 
     79 	// lights
     80 	for( int i = 0; i < 5; i++ ) {
     81 		vec3 light_position = texelFetch( point_light_origins, i ).xyz;
     82 		vec3 light_colour = texelFetch( point_light_colours, i ).rgb;
     83 		float light_sqdistance = dot( light_position - v2f.world_position, light_position - v2f.world_position );
     84 		vec3 light_direction = normalize( light_position - v2f.world_position );
     85 		float lambert_scale = dot( light_direction, normal );
     86 		float distance_scale = 1.0 / light_sqdistance;
     87 		c += vec3( light_colour * lambert_scale * distance_scale ) * ground;
     88 	}
     89 
     90 	// fog
     91 	c = apply_fog( c, length( v2f.view_position ) );
     92 
     93 	colour = vec4( linear_to_srgb( c + get_dither_noise( blue_noise ) ), 1.0 );
     94 }
     95 
     96 #endif