diff --git a/data/shaders/IBL.frag b/data/shaders/IBL.frag index d1e3b2964f4..a1f169a5179 100644 --- a/data/shaders/IBL.frag +++ b/data/shaders/IBL.frag @@ -1,6 +1,7 @@ uniform sampler2D ntex; uniform sampler2D dtex; uniform sampler2D albedo; +uniform sampler2D ssao; #ifdef GL_ES layout (location = 0) out vec4 Diff; @@ -76,8 +77,9 @@ void main(void) { vec2 uv = gl_FragCoord.xy / u_screen; vec3 normal = DecodeNormal(texture(ntex, uv).xy); + float ao = texture(ssao, uv).x; - Diff = vec4(0.25 * DiffuseIBL(normal), 1.); + Diff = vec4(0.25 * DiffuseIBL(normal) * ao, 1.); float z = texture(dtex, uv).x; @@ -86,8 +88,11 @@ void main(void) // Extract roughness float specval = texture(ntex, uv).z; + // Lagarde and de Rousiers 2014, "Moving Frostbite to PBR" + float ao_spec = clamp(pow(max(dot(normal, eyedir), 0.) + ao, exp2(-16.0 * (1.0 - specval) - 1.0)) - 1.0 + ao); + #ifdef GL_ES - Spec = vec4(.25 * SpecularIBL(normal, eyedir, specval), 1.); + Spec = vec4(.25 * SpecularIBL(normal, eyedir, specval) * ao_spec, 1.); #else // :::::::: Compute Space Screen Reflection :::::::::::::::::::::::::::::::::::: @@ -123,7 +128,7 @@ void main(void) outColor = fallback; } - Spec = vec4(outColor.rgb, 1.0); + Spec = vec4(outColor.rgb * ao_spec, 1.0); #endif } diff --git a/data/shaders/bilateralH.frag b/data/shaders/bilateralH.frag index 61c7565362d..53a08ac25d5 100644 --- a/data/shaders/bilateralH.frag +++ b/data/shaders/bilateralH.frag @@ -8,7 +8,7 @@ out vec4 FragColor; void main() { - float sigma = 5.; + float sigma = 2.; vec2 uv = gl_FragCoord.xy * pixel; float X = uv.x; @@ -23,7 +23,7 @@ void main() g0 *= g1; g1 *= g2; float tmp_weight, total_weight = g0; - for (int i = 1; i < 9; i++) { + for (int i = 1; i < 3; i++) { tmp_weight = max(0.0, 1.0 - .001 * abs(texture(depth, vec2(X - float(i) * pixel.x, Y)).x - pixel_depth)); sum += texture(tex, vec2(X - float(i) * pixel.x, Y)) * g0 * tmp_weight; total_weight += g0 * tmp_weight; diff --git a/data/shaders/bilateralV.frag b/data/shaders/bilateralV.frag index 1779eb34e8d..30a7d0bcbbc 100644 --- a/data/shaders/bilateralV.frag +++ b/data/shaders/bilateralV.frag @@ -8,7 +8,7 @@ out vec4 FragColor; void main() { - float sigma = 5.; + float sigma = 2.; vec2 uv = gl_FragCoord.xy * pixel; float X = uv.x; @@ -23,7 +23,7 @@ void main() g0 *= g1; g1 *= g2; float tmp_weight, total_weight = g0; - for (int i = 1; i < 9; i++) { + for (int i = 1; i < 3; i++) { tmp_weight = max(0.0, 1.0 - .001 * abs(texture(depth, vec2(X, Y - float(i) * pixel.y)).x - pixel_depth)); sum += texture(tex, vec2(X, Y - float(i) * pixel.y)) * g0 * tmp_weight; total_weight += g0 * tmp_weight; diff --git a/data/shaders/combine_diffuse_color.frag b/data/shaders/combine_diffuse_color.frag index af71349cf78..5b037751ceb 100644 --- a/data/shaders/combine_diffuse_color.frag +++ b/data/shaders/combine_diffuse_color.frag @@ -1,6 +1,5 @@ uniform sampler2D diffuse_map; uniform sampler2D specular_map; -uniform sampler2D ssao_tex; uniform sampler2D normal_color; uniform sampler2D diffuse_color; #if defined(GL_ES) && defined(GL_FRAGMENT_PRECISION_HIGH) @@ -28,7 +27,6 @@ void main() float specMapValue = texture(normal_color, tc).z; float emitMapValue = diffuseMatColor.w; - float ao = texture(ssao_tex, tc).x; vec3 DiffuseComponent = texture(diffuse_map, tc).xyz; vec3 SpecularComponent = texture(specular_map, tc).xyz; @@ -42,7 +40,7 @@ void main() vec3 tmp = DiffuseComponent * mix(diffuseMatColor.xyz, vec3(0.0), metallicMapValue) + (metallicMatColor * SpecularComponent); vec3 emitCol = diffuseMatColor.xyz + (diffuseMatColor.xyz * diffuseMatColor.xyz * emitMapValue * emitMapValue * 10.0); - vec4 color_1 = vec4(tmp * ao + (emitMapValue * emitCol), 1.0); + vec4 color_1 = vec4(tmp + (emitMapValue * emitCol), 1.0); // Fog float depth = texture(depth_stencil, tc).x; diff --git a/data/shaders/degraded_ibl.frag b/data/shaders/degraded_ibl.frag index af53a3a850f..ce712b1c857 100644 --- a/data/shaders/degraded_ibl.frag +++ b/data/shaders/degraded_ibl.frag @@ -1,4 +1,5 @@ uniform sampler2D ntex; +uniform sampler2D ssao; #ifdef GL_ES layout (location = 0) out vec4 Diff; @@ -17,7 +18,9 @@ void main(void) { vec2 uv = gl_FragCoord.xy / u_screen; vec3 normal = DecodeNormal(texture(ntex, uv).xy); + vec3 spec_color = vec3(0.031, 0.106, 0.173); + float ao = texture(ssao, uv).x; - Diff = vec4(0.25 * DiffuseIBL(normal), 1.); - Spec = vec4(0.031, 0.106, 0.173, 1.); + Diff = vec4(0.25 * DiffuseIBL(normal) * ao, 1.); + Spec = vec4(spec_color * ao, 1.); } diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 3dee1176853..82bab755777 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -1,5 +1,6 @@ // From paper http://graphics.cs.williams.edu/papers/AlchemyHPG11/ // and improvements here http://graphics.cs.williams.edu/papers/SAOHPG12/ +// and implementations here https://github.com/google/filament/blob/026b985c07b7eec4f678e0e5130d0a4e742e9c61/filament/src/materials/ssao/saoImpl.fs uniform sampler2D dtex; uniform float radius; @@ -7,12 +8,11 @@ uniform float k; uniform float sigma; out float AO; -const float tau = 7.; -const float beta = 0.002; -const float epsilon = .00001; +const float bias = .0005; +const float thickness = 10.0; -#define SAMPLES 16 -const float invSamples = 0.0625; // 1. / SAMPLES +#define SAMPLES 8 +const float invSamples = 0.125; // 1. / SAMPLES vec3 getXcYcZc(int x, int y, float zC) { @@ -22,6 +22,12 @@ vec3 getXcYcZc(int x, int y, float zC) return vec3(xC, yC, zC); } +float interleavedGradientNoise(highp vec2 w) +{ + const vec3 m = vec3(0.06711056, 0.00583715, 52.9829189); + return fract(m.z * fract(dot(w, m.xy))); +} + void main(void) { vec2 uv = gl_FragCoord.xy / u_screen; @@ -34,32 +40,38 @@ void main(void) vec3 ddy = dFdy(FragPos); vec3 norm = normalize(cross(ddy, ddx)); - float r = radius / FragPos.z; - float phi = 3. * float((x ^ y) + x * y); + float r = radius / FragPos.z * 0.5; + float phi = interleavedGradientNoise(vec2(gl_FragCoord.x, gl_FragCoord.y)); float bl = 0.0; float m = log2(r) + 6. + log2(invSamples); - float theta = mod(2. * 3.14 * tau * .5 * invSamples + phi, 6.283185307179586); + float peak = 0.1 * radius; + float peak2 = peak * peak; + float intensity = 2.0 * 3.14159 * sigma * peak * invSamples; + + float theta = phi * 2.0 * 2.4 * 3.14159; vec2 rotations = vec2(cos(theta), sin(theta)) * u_screen; vec2 offset = vec2(cos(invSamples), sin(invSamples)); - for(int i = 0; i < SAMPLES; ++i) { + for(int i = 0; i < SAMPLES; ++i) + { float alpha = (float(i) + .5) * invSamples; rotations = vec2(rotations.x * offset.x - rotations.y * offset.y, rotations.x * offset.y + rotations.y * offset.x); float h = r * alpha; vec2 localoffset = h * rotations; - m = m + .5; - ivec2 ioccluder_uv = ivec2(x, y) + ivec2(localoffset); - - if (ioccluder_uv.x < 0 || ioccluder_uv.x > int(u_screen.x) || ioccluder_uv.y < 0 || ioccluder_uv.y > int(u_screen.y)) continue; + ivec2 ioccluder_uv = clamp(ivec2(x, y) + ivec2(localoffset), ivec2(0), ivec2(u_screen)); float LinearoccluderFragmentDepth = textureLod(dtex, vec2(ioccluder_uv) / u_screen, max(m, 0.)).x; vec3 OccluderPos = getXcYcZc(ioccluder_uv.x, ioccluder_uv.y, LinearoccluderFragmentDepth); vec3 vi = OccluderPos - FragPos; - bl += max(0., dot(vi, norm) - FragPos.z * beta) / (dot(vi, vi) + epsilon); + float vv = dot(vi, vi); + float vn = dot(vi, norm); + float w = max(0.0, 1.0 - vv / thickness / thickness); + w = w * w; + bl += w * max(0., vn - FragPos.z * bias) / (vv + peak); } - AO = max(pow(1.0 - min(2. * sigma * bl * invSamples, 0.99), k), 0.); + AO = pow(max(1.0 - sqrt(bl * intensity), 0.), k); } diff --git a/src/graphics/lighting_passes.cpp b/src/graphics/lighting_passes.cpp index d30c6cf4c7e..344cd1e3e4b 100644 --- a/src/graphics/lighting_passes.cpp +++ b/src/graphics/lighting_passes.cpp @@ -170,7 +170,7 @@ class PointLightScatterShader : public TextureShader +class IBLShader : public TextureShader { public: IBLShader() @@ -181,12 +181,13 @@ class IBLShader : public TextureShader assignSamplerNames(0, "ntex", ST_NEAREST_FILTERED, 1, "dtex", ST_NEAREST_FILTERED, 2, "probe", ST_TRILINEAR_CUBEMAP, - 3, "albedo",ST_NEAREST_FILTERED); + 3, "albedo",ST_NEAREST_FILTERED, + 4, "ssao", ST_NEAREST_FILTERED); } // IBLShader }; // IBLShader // ============================================================================ -class DegradedIBLShader : public TextureShader +class DegradedIBLShader : public TextureShader { public: DegradedIBLShader() @@ -194,7 +195,8 @@ class DegradedIBLShader : public TextureShader loadProgram(OBJECT, GL_VERTEX_SHADER, "screenquad.vert", GL_FRAGMENT_SHADER, "degraded_ibl.frag"); assignUniforms(); - assignSamplerNames(0, "ntex", ST_NEAREST_FILTERED); + assignSamplerNames(0, "ntex", ST_NEAREST_FILTERED, + 1, "ssao", ST_NEAREST_FILTERED); } // DegradedIBLShader }; // DegradedIBLShader @@ -298,7 +300,8 @@ static void renderPointLights(unsigned count, void LightingPasses::renderEnvMap(GLuint normal_depth_texture, GLuint depth_stencil_texture, GLuint specular_probe, - GLuint albedo_buffer) + GLuint albedo_buffer, + GLuint ssao_texture) { glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); @@ -311,7 +314,7 @@ void LightingPasses::renderEnvMap(GLuint normal_depth_texture, glBindVertexArray(SharedGPUObjects::getFullScreenQuadVAO()); DegradedIBLShader::getInstance() - ->setTextureUnits(normal_depth_texture); + ->setTextureUnits(normal_depth_texture, ssao_texture); DegradedIBLShader::getInstance()->setUniforms(); } else @@ -323,7 +326,8 @@ void LightingPasses::renderEnvMap(GLuint normal_depth_texture, normal_depth_texture, depth_stencil_texture, specular_probe, - albedo_buffer); + albedo_buffer, + ssao_texture); IBLShader::getInstance()->setUniforms(); } @@ -434,6 +438,7 @@ void LightingPasses::renderLights( bool has_shadow, GLuint depth_stencil_texture, GLuint albedo_texture, const FrameBuffer* shadow_framebuffer, + GLuint ssao_texture, GLuint specular_probe) { { @@ -441,7 +446,8 @@ void LightingPasses::renderLights( bool has_shadow, renderEnvMap(normal_depth_texture, depth_stencil_texture, specular_probe, - albedo_texture); + albedo_texture, + ssao_texture); } // Render sunlight if and only if track supports shadow diff --git a/src/graphics/lighting_passes.hpp b/src/graphics/lighting_passes.hpp index 2655a4f50d8..3b14b1725be 100644 --- a/src/graphics/lighting_passes.hpp +++ b/src/graphics/lighting_passes.hpp @@ -47,7 +47,8 @@ class LightingPasses void renderEnvMap(GLuint normal_depth_texture, GLuint depth_stencil_texture, GLuint specular_probe, - GLuint albedo_buffer); + GLuint albedo_buffer, + GLuint ssao_buffer); /** Generate diffuse and specular map */ void renderSunlight(const core::vector3df &direction, @@ -65,6 +66,7 @@ class LightingPasses GLuint depth_stencil_texture, GLuint albedo_texture, const FrameBuffer* shadow_framebuffer, + GLuint ssao_texture, GLuint specular_probe); void renderLightsScatter(GLuint depth_stencil_texture, const FrameBuffer& half1_framebuffer, diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 092dfeaf1e7..ca714c64859 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -902,59 +902,60 @@ void PostProcessing::renderGaussian17TapBlur(const FrameBuffer &in_fbo, { assert(in_fbo.getWidth() == auxiliary.getWidth() && in_fbo.getHeight() == auxiliary.getHeight()); - -#if !defined(USE_GLES2) - if (CVS->supportsComputeShadersFiltering()) - glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT); -#endif - { - if (!CVS->supportsComputeShadersFiltering()) - { - auxiliary.bind(); - Gaussian17TapHShader::getInstance()->render(in_fbo, - linear_depth, - in_fbo.getWidth(), - in_fbo.getHeight()); - } - else - { - ComputeGaussian17TapHShader::getInstance()->render(in_fbo, - auxiliary, - linear_depth, - in_fbo.getWidth(), - in_fbo.getHeight()); - } - } +// Not quite necessary +// #if !defined(USE_GLES2) +// if (CVS->supportsComputeShadersFiltering()) +// glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT); +// #endif + +// { +// if (!CVS->supportsComputeShadersFiltering()) +// { + auxiliary.bind(); + Gaussian17TapHShader::getInstance()->render(in_fbo, + linear_depth, + in_fbo.getWidth(), + in_fbo.getHeight()); +// } +// else +// { +// ComputeGaussian17TapHShader::getInstance()->render(in_fbo, +// auxiliary, +// linear_depth, +// in_fbo.getWidth(), +// in_fbo.getHeight()); +// } +// } -#if !defined(USE_GLES2) - if (CVS->supportsComputeShadersFiltering()) - glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); -#endif +// #if !defined(USE_GLES2) +// if (CVS->supportsComputeShadersFiltering()) +// glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); +// #endif - { - if (!CVS->supportsComputeShadersFiltering()) - { - in_fbo.bind(); - Gaussian17TapVShader::getInstance()->render(auxiliary, - linear_depth, - in_fbo.getWidth(), - in_fbo.getHeight()); - } - else - { - ComputeGaussian17TapVShader::getInstance()->render(auxiliary, - in_fbo, - linear_depth, - in_fbo.getWidth(), - in_fbo.getHeight()); - } - } +// { +// if (!CVS->supportsComputeShadersFiltering()) +// { + in_fbo.bind(); + Gaussian17TapVShader::getInstance()->render(auxiliary, + linear_depth, + in_fbo.getWidth(), + in_fbo.getHeight()); +// } +// else +// { +// ComputeGaussian17TapVShader::getInstance()->render(auxiliary, +// in_fbo, +// linear_depth, +// in_fbo.getWidth(), +// in_fbo.getHeight()); +// } +// } -#if !defined(USE_GLES2) - if (CVS->supportsComputeShadersFiltering()) - glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); -#endif +// #if !defined(USE_GLES2) +// if (CVS->supportsComputeShadersFiltering()) +// glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); +// #endif } // renderGaussian17TapBlur // ---------------------------------------------------------------------------- diff --git a/src/graphics/shader_based_renderer.cpp b/src/graphics/shader_based_renderer.cpp index 943b8348fff..7828fb310a6 100644 --- a/src/graphics/shader_based_renderer.cpp +++ b/src/graphics/shader_based_renderer.cpp @@ -195,7 +195,7 @@ void ShaderBasedRenderer::renderShadows() } // ============================================================================ -class CombineDiffuseColor : public TextureShader > { public: @@ -206,17 +206,16 @@ class CombineDiffuseColor : public TextureShader & bg_color) { - setTextureUnits(dm, sm, st, nt, dc, ds, lt); + setTextureUnits(dm, sm, nt, dc, ds, lt); drawFullScreenEffect(bg_color); } // render }; // CombineDiffuseColor @@ -266,6 +265,15 @@ void ShaderBasedRenderer::renderSceneDeferred(scene::ICameraSceneNode * const ca SP::draw(SP::RP_1ST, SP::DCT_NORMAL); } + // Handle SSAO + { + PROFILER_PUSH_CPU_MARKER("- SSAO", 0xFF, 0xFF, 0x00); + ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_SSAO)); + if (UserConfigParams::m_ssao) + renderSSAO(); + PROFILER_POP_CPU_MARKER(); + } + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Lights { @@ -282,19 +290,11 @@ void ShaderBasedRenderer::renderSceneDeferred(scene::ICameraSceneNode * const ca m_rtts->getDepthStencilTexture(), m_rtts->getRenderTarget(RTT_COLOR), m_rtts->getShadowFrameBuffer(), + m_rtts->getRenderTarget(RTT_HALF1_R), specular_probe); PROFILER_POP_CPU_MARKER(); } - // Handle SSAO - { - PROFILER_PUSH_CPU_MARKER("- SSAO", 0xFF, 0xFF, 0x00); - ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_SSAO)); - if (UserConfigParams::m_ssao) - renderSSAO(); - PROFILER_POP_CPU_MARKER(); - } - const Track * const track = Track::getCurrentTrack(); // Render discrete lights scattering if (UserConfigParams::m_light_scatter && track && track->isFogEnabled()) @@ -349,7 +349,6 @@ void ShaderBasedRenderer::renderSceneDeferred(scene::ICameraSceneNode * const ca CombineDiffuseColor::getInstance()->render( m_rtts->getRenderTarget(RTT_DIFFUSE), m_rtts->getRenderTarget(RTT_SPECULAR), - m_rtts->getRenderTarget(RTT_HALF1_R), m_rtts->getRenderTarget(RTT_NORMAL_AND_DEPTH), m_rtts->getRenderTarget(RTT_SP_DIFF_COLOR), m_rtts->getDepthStencilTexture(), diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 738037c2124..56d15ea39f2 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -542,7 +542,7 @@ void Track::loadTrackInfo() m_sun_diffuse_color = video::SColor(255, 255, 255, 255); m_sun_position = core::vector3df(0, 10, 10); irr_driver->setSSAORadius(1.); - irr_driver->setSSAOK(1.5); + irr_driver->setSSAOK(2.0); irr_driver->setSSAOSigma(1.); XMLNode *root = file_manager->createXMLTree(m_filename);