commit 3e52f9f14df5714229040f6a7ddcbd1df32e162b parent edd75bba41bf5fcbd8175b1c1473e830da54adf5 Author: Michael Savage <mikejsavage@gmail.com> Date: Sat Jul 8 23:04:03 +0300 Make the sun move across the sky instead of just up Diffstat:
game.h | | | 2 | +- |
renderer.cc | | | 2 | +- |
renderer.h | | | 10 | +++++----- |
shaders/skybox.glsl | | | 12 | +++++------- |
shaders/terrain.glsl | | | 15 | ++++++++------- |
shaders/tree.glsl | | | 7 | +++---- |
skybox.cc | | | 6 | +++--- |
skybox.h | | | 2 | +- |
terrain_manager.cc | | | 8 | ++++---- |
terrain_manager.h | | | 4 | ++-- |
diff --git a/game.h b/game.h @@ -36,7 +36,7 @@ struct GameState { Skybox skybox; - float test_sun; + float sun_angle; BTTs btt; GPUBTT gpubtt; diff --git a/renderer.cc b/renderer.cc @@ -327,7 +327,7 @@ Shader renderer_new_shader( ShaderConfig config ) { return INVALID_SHADER; } - const char * ubo_names[] = { "v_cold", "f_hot", "view", "model", "light_view", "window" }; + const char * ubo_names[] = { "v_cold", "view", "model", "light_view", "window", "sun" }; for( GLuint i = 0; i < ARRAY_COUNT( ubo_names ); i++ ) { GLuint idx = glGetUniformBlockIndex( program, ubo_names[ i ] ); if( idx != GL_INVALID_INDEX ) { diff --git a/renderer.h b/renderer.h @@ -17,11 +17,11 @@ typedef u32 TextureBufferObject; typedef u32 FramebufferObject; const u32 UB_VS_COLD = 0; -const u32 UB_FS_HOT = 1; -const u32 UB_VIEW = 2; -const u32 UB_MODEL = 3; -const u32 UB_LIGHT_VIEW = 4; -const u32 UB_WINDOW = 5; +const u32 UB_VIEW = 1; +const u32 UB_MODEL = 2; +const u32 UB_LIGHT_VIEW = 3; +const u32 UB_WINDOW = 4; +const u32 UB_SUN = 5; #define RENDERER_MAX_TEXTURES 4 #define RENDERER_MAX_TEXTURE_BUFFERS 4 diff --git a/shaders/skybox.glsl b/shaders/skybox.glsl @@ -18,21 +18,19 @@ void main() { in vec3 pos; out vec4 colour; -layout( std140 ) uniform f_hot { - float sun; +layout( std140 ) uniform sun { + vec3 sun_dir; }; void main() { - vec3 sun_direction = normalize( vec3( -1, 0, sun ) ); - 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.7, 0.8, 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 ); float scaled_z = smoothstep( 0.0, 0.2, pos.z ); - float sun_dot = smoothstep( 0.99, 1.0, dot( sun_direction, normalize( pos ) ) ); - float halo_dot = smoothstep( 0.9, 1.0, dot( sun_direction, normalize( pos ) ) ); + 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 ) ) ); colour = mix( mix( mix( horizon, top, scaled_z ), halo, halo_dot ), sunny, sun_dot ); } diff --git a/shaders/terrain.glsl b/shaders/terrain.glsl @@ -24,8 +24,9 @@ void main() { in VSOut v2f; out vec4 colour; -layout( std140 ) uniform f_hot { - float sun; +layout( std140 ) uniform sun { + vec3 sun_dir; + float sun_angle; }; uniform sampler2D normals; @@ -40,7 +41,7 @@ void main() { vec2 world_pos = mod( v2f.world_position.xy, textureSize( normals, 0 ) - ivec2( 1, 1 ) ); vec3 normal = normalize( texture( normals, world_pos / textureSize( normals, 0 ) ).xyz ); - float horizon = texture( horizons, world_pos / textureSize( horizons, 0 ) ).r; + float horizon_angle = texture( horizons, world_pos / textureSize( horizons, 0 ) ).r; // ground colour vec3 ground; @@ -66,10 +67,10 @@ void main() { } // sunlight + sky ambient lighting - // TODO: use formula for area of a chord? - float sun_visible_fraction = smoothstep( 0, 0.2, sun - horizon ); - vec3 sun_direction = normalize( vec3( -1, 0, sun ) ); - float sunlight_lambert = max( 0, dot( normal, sun_direction ) ); + // area of a chord is somewhat similar to smoothstep + vec3 sun_dir2 = vec3( 0, 0, 1 ); + float sun_visible_fraction = smoothstep( -0.2, 0.2, sun_angle - horizon_angle ); + float sunlight_lambert = max( 0, dot( normal, sun_dir2 ) ); vec3 sunlight = sun_visible_fraction * sunlight_lambert * vec3( 0.9, 0.9, 0.5 ); vec3 ambient = vec3( 0.05, 0.05, 0.15 ); diff --git a/shaders/tree.glsl b/shaders/tree.glsl @@ -7,8 +7,8 @@ layout( std140 ) uniform view { mat4 P; }; -layout( std140 ) uniform f_hot { - float sun; +layout( std140 ) uniform sun { + vec3 sun_dir; }; struct VSOut { @@ -44,8 +44,7 @@ float sq( float x ) { void main() { // sunlight - vec3 sun_direction = normalize( vec3( -1, 0, sun ) ); - float lambert = dot( sun_direction, v2f.normal ); + float lambert = dot( sun_dir, v2f.normal ); float half_lambert = sq( lambert * 0.5 + 0.5 ); vec3 c = v2f.colour * half_lambert; diff --git a/skybox.cc b/skybox.cc @@ -41,16 +41,16 @@ 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, float sun ) { +void skybox_render( const Skybox * skybox, const m4 & V, const m4 & P, v3 sun_dir ) { renderer_ub_easy( skybox->ub_view, V, P ); - renderer_ub_easy( skybox->ub_sun, sun ); + renderer_ub_easy( skybox->ub_sun, sun_dir ); RenderState render_state; render_state.shader = get_shader( SHADER_SKYBOX ); render_state.cull_face = CULLFACE_FRONT; render_state.disable_depth_writes = true; render_state.ubs[ UB_VIEW ] = skybox->ub_view; - render_state.ubs[ UB_FS_HOT ] = skybox->ub_sun; + render_state.ubs[ UB_SUN ] = skybox->ub_sun; renderer_draw_mesh( skybox->mesh, render_state ); } 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, float sun ); +void skybox_render( const Skybox * skybox, const m4 & V, const m4 & P, v3 sun_dir ); void skybox_destroy( Skybox * skybox ); diff --git a/terrain_manager.cc b/terrain_manager.cc @@ -216,7 +216,7 @@ void terrain_init( } tm->ub_view = renderer_new_ub(); - tm->fragment_uniforms = renderer_new_ub(); + tm->ub_sun = renderer_new_ub(); tm->point_light_origins = renderer_new_tb( TEXFMT_RGB_FLOAT ); tm->point_light_colours = renderer_new_tb( TEXFMT_RGB_FLOAT ); @@ -304,7 +304,7 @@ void terrain_update( TerrainManager * tm, v3 position ) { } } -void terrain_render( TerrainManager * tm, const m4 & V, const m4 & P, float sun, double current_time ) { +void terrain_render( TerrainManager * tm, const m4 & V, const m4 & P, float sun_angle, v3 sun_dir, double current_time ) { PROFILE_FUNCTION(); ReadyTile ready_tile; @@ -330,7 +330,7 @@ void terrain_render( TerrainManager * tm, const m4 & V, const m4 & P, float sun, } renderer_ub_easy( tm->ub_view, V, P ); - renderer_ub_easy( tm->fragment_uniforms, sun ); + renderer_ub_easy( tm->ub_sun, sun_dir, sun_angle ); /* start lighting */ float tbo1[ 15 ] = { @@ -355,7 +355,7 @@ void terrain_render( TerrainManager * tm, const m4 & V, const m4 & P, float sun, RenderState render_state; render_state.shader = get_shader( SHADER_TERRAIN ); render_state.ubs[ UB_VIEW ] = tm->ub_view; - render_state.ubs[ UB_FS_HOT ] = tm->fragment_uniforms; + render_state.ubs[ UB_SUN ] = tm->ub_sun; render_state.tbs[ 0 ] = tm->point_light_origins; render_state.tbs[ 1 ] = tm->point_light_colours; diff --git a/terrain_manager.h b/terrain_manager.h @@ -53,7 +53,7 @@ struct TerrainManager { u32 width, height; UB ub_view; - UB fragment_uniforms; + UB ub_sun; TB point_light_origins; TB point_light_colours; @@ -77,7 +77,7 @@ struct TerrainManager { void terrain_init( TerrainManager * tm, const char * tiles_dir, MemoryArena * arena, WorkQueue * background_tasks ); void terrain_teleport( TerrainManager * tm, v3 position ); void terrain_update( TerrainManager * tm, v3 position ); -void terrain_render( TerrainManager * tm, const m4 & V, const m4 & P, float sun, double current_time ); +void terrain_render( TerrainManager * tm, const m4 & V, const m4 & P, float sun_angle, v3 sun_dir, double current_time ); float terrain_height( const TerrainManager * tm, v3 position ); v3 terrain_normal( const TerrainManager * tm, v3 position );