diff --git a/TODO b/TODO index 1363e79..029ce85 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,4 @@ Rendering: -* "Fog" * Improved light sources * Secondary rays * Shadows diff --git a/raymarcher.cc b/raymarcher.cc index 17cde60..a3ef35e 100644 --- a/raymarcher.cc +++ b/raymarcher.cc @@ -50,6 +50,7 @@ void T_Raymarcher::render( ) U_NEAR_PLANE = 5 , U_LIGHT_DIR = 6 , U_RAYMARCHER = 7 , + U_FOG = 8 , }; const auto id( program_.program( E_ShaderType::FRAGMENT ) ); @@ -66,6 +67,8 @@ void T_Raymarcher::render( ) glProgramUniform4f( id , U_RAYMARCHER , rmIterations , rmStep , rmEpsilon , rmMaxDist ); + glProgramUniform1f( id , U_FOG , fog ); + glDrawArrays( GL_TRIANGLE_STRIP , 0 , 4 ); PEND( ); @@ -75,16 +78,15 @@ void T_Raymarcher::makeUI( ) { camera_.makeUI( ); - if ( !ImGui::CollapsingHeader( "Raymarcher" ) ) { - return; - } - - ImGui::DragInt( "Iterations" , &rmIterations , .1 , 1 , 512 ); - ImGui::DragFloat( "Step" , &rmStep , .005 , .1 , 2 ); - ImGui::DragFloat( "Max. dist." , &rmMaxDist , .1f , - 0.01 , 1000.0 , "%.2f" ); - if ( ImGui::DragFloat( "Epsilon" , &epsLog , .01f , - -10 , -0.5 , "10 ^ %.2f" ) ) { - rmEpsilon = pow( 10 , epsLog ); + if ( ImGui::CollapsingHeader( "Raymarcher" ) ) { + ImGui::DragInt( "Iterations" , &rmIterations , .01 , 1 , 512 ); + ImGui::DragFloat( "Step" , &rmStep , .00005 , .1 , 2 ); + ImGui::DragFloat( "Max. dist." , &rmMaxDist , .1f , + 0.01 , 1000.0 , "%.2f" ); + if ( ImGui::DragFloat( "Epsilon" , &epsLog , .01f , + -10 , -0.5 , "10 ^ %.2f" ) ) { + rmEpsilon = pow( 10 , epsLog ); + } + ImGui::DragFloat( "Fog" , &fog , .000001 , 0 , 1 , "%.5f" ); } } diff --git a/raymarcher.hh b/raymarcher.hh index 3d7958a..a315638 100644 --- a/raymarcher.hh +++ b/raymarcher.hh @@ -37,5 +37,6 @@ struct T_Raymarcher float rmStep = 1.2; float rmEpsilon = .001; float rmMaxDist = 250; + float fog = .00015; float epsLog = log( rmEpsilon ) / log( 10 ); }; diff --git a/shaders/chunks/raymarcher.glsl b/shaders/chunks/raymarcher.glsl index a2c107c..9239d2f 100644 --- a/shaders/chunks/raymarcher.glsl +++ b/shaders/chunks/raymarcher.glsl @@ -8,6 +8,7 @@ layout( location = 4 ) uniform vec3 u_CamUp; layout( location = 5 ) uniform float u_NearPlane; layout( location = 6 ) uniform vec3 u_LightDir; layout( location = 7 ) uniform vec4 u_Render; +layout( location = 8 ) uniform float u_FogAttenuation; layout( location = 0 ) out vec3 o_Color; layout( location = 1 ) out float o_Z; diff --git a/shaders/lib/fog.glsl b/shaders/lib/fog.glsl new file mode 100644 index 0000000..94c3518 --- /dev/null +++ b/shaders/lib/fog.glsl @@ -0,0 +1,10 @@ +//! type library + +vec3 FOG_Apply( + in vec3 color , + in float dist , + in float attenuation , + in vec3 background ) +{ + return mix( background , color , exp( - dist * dist * attenuation ) ); +} diff --git a/shaders/scene.f.glsl b/shaders/scene.f.glsl index fcc61f2..10bc448 100644 --- a/shaders/scene.f.glsl +++ b/shaders/scene.f.glsl @@ -4,6 +4,7 @@ //! include chunks/raymarcher.glsl //! include lib/shading-pbr.glsl //! include lib/shading-blinnphong.glsl +//! include lib/fog.glsl T_BPMaterial BPMaterials[1] = { @@ -64,8 +65,9 @@ void main( ) int( u_Render.x ) , u_Render.y , u_Render.z , .001 , u_Render.w ); vec3 hitPos = u_CamPos + rayDir * r.x; + const vec3 background = vec3( .01 ); - vec3 bc = vec3( 0 ); + vec3 bc = background; if ( r.y >= 0. ) { const int midx = int( r.y ); const vec3 normal = RM_GetNormal( hitPos ); @@ -85,6 +87,7 @@ void main( ) if ( glowidx >= 0 ) { bc += Glow[ glowidx ]; } + bc = FOG_Apply( bc , r.x , u_FogAttenuation , background ); } o_Color = bc;