commit 4e909f86b2f4bd19389d5f085227907e60c7d280 parent e14f300f0db9a62046071753bd304286b1be40a8 Author: Michael Savage <mikejsavage@gmail.com> Date: Sun Jul 9 15:47:58 +0300 Dumpy sunrise shader Diffstat:
hm.cc | | | 2 | +- |
shaders/skybox.glsl | | | 50 | ++++++++++++++++++++++++++++++++++++++++++-------- |
skybox.cc | | | 4 | ++-- |
skybox.h | | | 2 | +- |
diff --git a/hm.cc b/hm.cc @@ -198,7 +198,7 @@ GAME_FRAME( game_frame ) { m4 Vsky = m4_view( forward, right, up, v3( 0 ) ); v3 sun_dir = v3( -cosf( game->sun_angle ), 0, sinf( game->sun_angle ) ); - skybox_render( &game->skybox, Vsky, P, sun_dir ); + skybox_render( &game->skybox, Vsky, P, game->sun_angle, sun_dir ); terrain_render( &game->tm, V, P, game->sun_angle, sun_dir, current_time ); struct { m4 V; m4 P; } uniforms = { V, P }; diff --git a/shaders/skybox.glsl b/shaders/skybox.glsl @@ -20,19 +20,53 @@ out vec4 colour; layout( std140 ) uniform sun { vec3 sun_dir; + float sun_angle; }; +float asdf( float x, float lo, float hi ) { + return clamp( ( x - lo ) / ( hi - lo ), 0.0, 1.0 ); +} + +float hdot( vec3 u, vec3 v ) { + float d = dot( u, v ) * 0.5 + 0.5; + return d * d; +} + void main() { - vec4 horizon = vec4( 0.4, 0.7, 1.0, 1.0 ); - vec4 top = vec4( 0.3, 0.6, 1.0, 1.0 ); - vec4 halo = vec4( 0.5, 0.7, 1.0, 1.0 ); - vec4 sunny = vec4( 0.9, 0.9, 0.2, 1.0 ); + vec3 npos = normalize( pos ); + + vec3 night = vec3( 0.0, 0.0, 0.01 ); + vec3 horizon = vec3( 0.4, 0.7, 1.0 ); + vec3 top = vec3( 0.1, 0.4, 0.8 ); + vec3 sunny = vec3( 1.0, 0.9, 0.8 ); + + float elevation = 0.0; + if( abs( npos.z ) > 0.001 ) { + float cos_elevation = dot( npos.xy, npos.xy ) / ( length( npos.xy ) ); + elevation = acos( cos_elevation ); + } + + float sun_dot = clamp( dot( sun_dir, npos ), 0.0, 1.0 ); + float sun_intensity = smoothstep( 0.995, 1.0, sun_dot ); + float halo_intensity = smoothstep( 0.90, 1.0, sun_dot ); + + float scaled_z = elevation / 1.571; + vec3 day_colour = mix( horizon, top, scaled_z ); + + vec3 dawn = vec3( 1.0, 0.35, 0.0 ); + + float night_sun_angle = -0.4; + float dawn_sun_angle = 0.0; + float day_sun_angle = 1.0; + + float night_to_dawn = asdf( sun_angle, night_sun_angle, dawn_sun_angle ); + float dawn_to_day = asdf( sun_angle, dawn_sun_angle, day_sun_angle ); + day_colour += vec3( 0.5, 0.2, 0.0 ) * halo_intensity * 0.5 * dawn_to_day; - float scaled_z = smoothstep( 0.0, 0.2, pos.z ); - float sun_dot = smoothstep( 0.995, 1.0, dot( sun_dir, normalize( pos ) ) ); - float halo_dot = smoothstep( 0.90, 1.0, dot( sun_dir, normalize( pos ) ) ); + vec3 night_colour = mix( night, sunny, sun_intensity ); - colour = mix( mix( mix( horizon, top, scaled_z ), halo, halo_dot ), sunny, sun_dot ); + colour = vec4( mix( mix( night_colour, dawn * hdot( npos, sun_dir ), night_to_dawn ), day_colour, dawn_to_day ), 1.0 ); + colour = mix( colour, vec4( sunny, 1.0 ), sun_intensity ); } #endif diff --git a/skybox.cc b/skybox.cc @@ -41,9 +41,9 @@ static m4 angles_to_view( v3 angles ) { return m4_rotz( -angles.y ) * m4_rotx( -angles.x ); } -void skybox_render( const Skybox * skybox, const m4 & V, const m4 & P, v3 sun_dir ) { +void skybox_render( const Skybox * skybox, const m4 & V, const m4 & P, float sun_angle, v3 sun_dir ) { renderer_ub_easy( skybox->ub_view, V, P ); - renderer_ub_easy( skybox->ub_sun, sun_dir ); + renderer_ub_easy( skybox->ub_sun, sun_dir, sun_angle ); RenderState render_state; render_state.shader = get_shader( SHADER_SKYBOX ); diff --git a/skybox.h b/skybox.h @@ -10,5 +10,5 @@ struct Skybox { }; void skybox_init( Skybox * skybox ); -void skybox_render( const Skybox * skybox, const m4 & V, const m4 & P, v3 sun_dir ); +void skybox_render( const Skybox * skybox, const m4 & V, const m4 & P, float sun_angle, v3 sun_dir ); void skybox_destroy( Skybox * skybox );