commit ed1205501c0646ac1db4963b48413ba7debbd18d parent 8f324ba972827900f403e065436b0e3bef90217f Author: Michael Savage <mikejsavage@gmail.com> Date: Sat Sep 2 20:15:06 +0300 Dither the skybox Diffstat:
renderer.cc | | | 11 | +++++++++++ |
renderer.h | | | 2 | ++ |
shaders.cc | | | 1 | + |
shaders/common.glsl | | | 4 | ++++ |
shaders/skybox.glsl | | | 13 | ++++++------- |
shadow_map.cc | | | 5 | +---- |
skybox.cc | | | 1 | + |
terrain_manager.cc | | | 4 | +--- |
terrain_manager.h | | | 1 | - |
diff --git a/renderer.cc b/renderer.cc @@ -6,6 +6,8 @@ #include "renderer.h" #include "log.h" #include "linear_algebra.h" +#include "blue_noise.h" +#include "obj.h" STATIC_ASSERT( SAME_TYPE( VB, GLuint ) ); STATIC_ASSERT( SAME_TYPE( IB, GLuint ) ); @@ -72,6 +74,8 @@ static size_t ubo_offset_alignment; static u8 * uniforms_buffer; static size_t uniforms_offset; +static Texture blue_noise; + static RenderState previous_render_state; static u32 previous_viewport_width, previous_viewport_height; @@ -109,10 +113,13 @@ void renderer_init() { GLint alignment; glGetIntegerv( GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &alignment ); ubo_offset_alignment = checked_cast< size_t >( alignment ); + + blue_noise = load_png_memory( blue_noise_png, blue_noise_png_len, TEXFMT_R_U8NORM, 1, false ); } void renderer_term() { glDeleteBuffers( 1, &uniforms ); + renderer_delete_texture( blue_noise ); } void renderer_begin_frame() { @@ -247,6 +254,10 @@ void renderer_end_pass() { render_passes.append( current_render_pass ); } +Texture renderer_blue_noise() { + return blue_noise; +} + void renderer_begin_frame( ClearColourBool clear_colour, ClearDepthBool clear_depth ) { GLbitfield clear_mask = 0; if( clear_colour == RENDERER_CLEAR_COLOUR_DO ) { diff --git a/renderer.h b/renderer.h @@ -199,6 +199,8 @@ void renderer_begin_pass( ClearColourBool clear_colour, ClearDepthBool clear_dep void renderer_end_pass(); void renderer_end_frame(); +Texture renderer_blue_noise(); + UniformBinding renderer_ub_data( const void * data, size_t size, size_t alignment ); // void renderer_begin_frame( ClearColourBool clear_colour = RENDERER_CLEAR_COLOUR_DO, ClearDepthBool clear_depth = RENDERER_CLEAR_DEPTH_DO ); diff --git a/shaders.cc b/shaders.cc @@ -40,6 +40,7 @@ void shaders_init() { shaders[ SHADER_TEXT ].texture_uniform_names[ 0 ] = "atlas"; shaders[ SHADER_SKYBOX ].path = "shaders/skybox.glsl"; + shaders[ SHADER_SKYBOX ].texture_uniform_names[ 0 ] = "blue_noise"; shaders[ SHADER_FLAT_VERTEX_COLOURS ].path = "shaders/flat_vertex_colours.glsl"; diff --git a/shaders/common.glsl b/shaders/common.glsl @@ -10,6 +10,10 @@ float saturate( float x ) { return clamp( x, 0.0, 1.0 ); } +vec3 saturate( vec3 x ) { + return clamp( x, 0.0, 1.0 ); +} + float unlerp( float x, float lo, float hi ) { return ( x - lo ) / ( hi - lo ); } diff --git a/shaders/skybox.glsl b/shaders/skybox.glsl @@ -23,17 +23,13 @@ layout( std140 ) uniform sky { vec3 sun_dir; }; +uniform sampler2D blue_noise; + vec3 perez_ext( float cos_theta, float gamma, float cos_gamma ) { vec3 chi = ( 1 + cos_gamma * cos_gamma ) / pow( 1 + H * H - 2 * cos_gamma * H, vec3( 1.5 ) ); return ( 1 + A * exp( B / ( cos_theta + 0.01 ) ) ) * ( C + D * exp( E * gamma ) + F * ( cos_gamma * cos_gamma ) + G * chi + I * sqrt( cos_theta ) ); } - -float hdot( vec3 u, vec3 v ) { - float d = dot( u, v ) * 0.5 + 0.5; - return d * d; -} - void main() { vec3 clamped_pos = vec3( pos.x, pos.y, saturate( pos.z ) ); vec3 V = normalize( clamped_pos ); @@ -44,7 +40,10 @@ void main() { vec3 R = Z * perez_ext( cos_theta, gamma, cos_gamma ); - colour = vec4( clamp( R, 0.0, 1.0 ), 1.0 ); + vec3 dither_noise = texture( blue_noise, gl_FragCoord.xy / textureSize( blue_noise, 0 ) ).xxx; + dither_noise = ( dither_noise - vec3( 0.5 ) ) / 128.0; + + colour = vec4( saturate( R + dither_noise ), 1.0 ); } #endif diff --git a/shadow_map.cc b/shadow_map.cc @@ -8,7 +8,6 @@ #include "text_renderer.h" #include "log.h" #include "obj.h" -#include "blue_noise.h" static ImmediateTriangle triangles[ 512000 ]; static ImmediateContext imm; @@ -16,7 +15,6 @@ static ImmediateContext imm; static Mesh square; static FB shadow_fb; static Mesh tree_mesh; -static Texture blue_noise; static const u32 SHADOW_SIZE = 1024; @@ -87,7 +85,6 @@ GAME_INIT( game_init ) { } tree_mesh = load_obj( "models/trees/PineTree.obj", &mem->persistent_arena ); - blue_noise = load_png_memory( blue_noise_png, blue_noise_png_len, TEXFMT_R_U8NORM, 1, false ); } GAME_FRAME( game_frame ) { @@ -167,7 +164,7 @@ GAME_FRAME( game_frame ) { render_state.uniforms[ UB_VIEW ] = renderer_uniforms( V, P, game->pos ); render_state.uniforms[ UB_LIGHT_VIEW ] = light_view_uniforms; render_state.textures[ 0 ] = shadow_fb.texture; - render_state.textures[ 1 ] = blue_noise; + render_state.textures[ 1 ] = renderer_blue_noise(); draw_scene( render_state, true ); } diff --git a/skybox.cc b/skybox.cc @@ -138,6 +138,7 @@ void skybox_render( const Skybox * skybox, const m4 & Vsky, const m4 & P, float render_state.disable_depth_writes = true; render_state.uniforms[ UB_VIEW ] = renderer_uniforms( Vsky, P ); render_state.uniforms[ UB_SKY ] = renderer_uniforms( hosek.A, hosek.B, hosek.C, hosek.D, hosek.E, hosek.F, hosek.G, hosek.H, hosek.I, hosek.Z, sun_dir ); + render_state.textures[ 0 ] = renderer_blue_noise(); renderer_draw_mesh( skybox->mesh, render_state ); } diff --git a/terrain_manager.cc b/terrain_manager.cc @@ -16,7 +16,6 @@ #include "profiler.h" #include "renderer.h" #include "shaders.h" -#include "blue_noise.h" #include "obj.h" #include "libs/lodepng/lodepng.h" @@ -218,7 +217,6 @@ void terrain_init( } } - tm->blue_noise = load_png_memory( blue_noise_png, blue_noise_png_len, TEXFMT_R_U8NORM, 1, false ); tm->point_light_origins = renderer_new_tb( TEXFMT_RGB_FLOAT ); tm->point_light_colours = renderer_new_tb( TEXFMT_RGB_FLOAT ); @@ -353,7 +351,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.textures[ 2 ] = tm->blue_noise; + render_state.textures[ 2 ] = renderer_blue_noise(); render_state.uniforms[ UB_VIEW ] = renderer_uniforms( V, P ); render_state.uniforms[ UB_SUN ] = renderer_uniforms( sun_dir, sun_angle ); render_state.tbs[ 0 ] = tm->point_light_origins; diff --git a/terrain_manager.h b/terrain_manager.h @@ -52,7 +52,6 @@ struct TerrainManager { u32 width, height; - Texture blue_noise; TB point_light_origins; TB point_light_colours;