From c7b98c4e6ca96d5e72d2ed76a8e6a1597ce93575 Mon Sep 17 00:00:00 2001 From: vlj Date: Mon, 6 Oct 2014 02:19:21 +0200 Subject: [PATCH] Emulate envmap specular reflexion --- data/shaders/diffuseenvmap.frag | 19 ++++++++++++++++++- src/graphics/post_processing.cpp | 8 ++++---- src/graphics/post_processing.hpp | 2 +- src/graphics/render_lighting.cpp | 6 +++--- src/graphics/shaders.cpp | 5 +++-- src/graphics/shaders.hpp | 4 ++-- 6 files changed, 31 insertions(+), 13 deletions(-) diff --git a/data/shaders/diffuseenvmap.frag b/data/shaders/diffuseenvmap.frag index c88478b23..741578da3 100644 --- a/data/shaders/diffuseenvmap.frag +++ b/data/shaders/diffuseenvmap.frag @@ -2,11 +2,15 @@ uniform float blueLmn[9]; uniform float greenLmn[9]; uniform float redLmn[9]; uniform sampler2D ntex; +uniform sampler2D dtex; +uniform samplerCube tex; uniform mat4 TransposeViewMatrix; out vec4 Diff; +out vec4 Spec; vec3 DecodeNormal(vec2 n); +vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix); mat4 getMatrix(float L[9]) { @@ -24,8 +28,9 @@ void main(void) { vec2 uv = gl_FragCoord.xy / screen; vec3 normal = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.)); + // Convert normal in world space (where SH coordinates were computed) - vec4 extendednormal = TransposeViewMatrix * vec4(normal, 1.); + vec4 extendednormal = TransposeViewMatrix * vec4(normal, 0.); extendednormal.w = 1.; mat4 rmat = getMatrix(redLmn); mat4 gmat = getMatrix(greenLmn); @@ -36,4 +41,16 @@ void main(void) float b = dot(extendednormal, bmat * extendednormal); Diff = max(0.25 * vec4(r, g, b, .1), vec4(0.)); + + float z = texture(dtex, uv).x; + + vec4 xpos = getPosFromUVDepth(vec3(uv, z), InverseProjectionMatrix); + vec3 eyedir = -normalize(xpos.xyz); + vec3 sampleDirection = reflect(-eyedir, normal); + sampleDirection = (InverseViewMatrix * vec4(sampleDirection, 0.)).xyz; + + float specval = texture(ntex, uv).z; + float lodval = 8 * (1 - (log2(specval) / 10 - 1)); + vec4 specular = textureLod(tex, sampleDirection, lodval); + Spec = max(specular, vec4(0.)); } diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index d4370bb8b..3ac843d14 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -221,19 +221,19 @@ void renderBloom(GLuint in) DrawFullScreenEffect(); } -void PostProcessing::renderDiffuseEnvMap(const float *bSHCoeff, const float *gSHCoeff, const float *rSHCoeff) +void PostProcessing::renderEnvMap(const float *bSHCoeff, const float *gSHCoeff, const float *rSHCoeff, GLuint skybox) { glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_ONE, GL_ONE); - glUseProgram(FullScreenShader::DiffuseEnvMapShader::getInstance()->Program); + glUseProgram(FullScreenShader::EnvMapShader::getInstance()->Program); glBindVertexArray(SharedObject::FullScreenQuadVAO); - FullScreenShader::DiffuseEnvMapShader::getInstance()->SetTextureUnits(createVector(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH))); + FullScreenShader::EnvMapShader::getInstance()->SetTextureUnits(createVector(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH), irr_driver->getDepthStencilTexture(), skybox)); core::matrix4 TVM = irr_driver->getViewMatrix().getTransposed(); - FullScreenShader::DiffuseEnvMapShader::getInstance()->setUniforms(TVM, std::vector(bSHCoeff, bSHCoeff + 9), std::vector(gSHCoeff, gSHCoeff + 9), std::vector(rSHCoeff, rSHCoeff + 9)); + FullScreenShader::EnvMapShader::getInstance()->setUniforms(TVM, std::vector(bSHCoeff, bSHCoeff + 9), std::vector(gSHCoeff, gSHCoeff + 9), std::vector(rSHCoeff, rSHCoeff + 9)); glDrawArrays(GL_TRIANGLES, 0, 3); glBindVertexArray(0); diff --git a/src/graphics/post_processing.hpp b/src/graphics/post_processing.hpp index a6b990432..e09a66451 100644 --- a/src/graphics/post_processing.hpp +++ b/src/graphics/post_processing.hpp @@ -81,7 +81,7 @@ public: void renderFog(); void renderSSAO(); - void renderDiffuseEnvMap(const float *bSHCoeff, const float *gSHCoeff, const float *rSHCoeff); + void renderEnvMap(const float *bSHCoeff, const float *gSHCoeff, const float *rSHCoeff, unsigned skycubemap); void renderRHDebug(unsigned SHR, unsigned SHG, unsigned SHB, const core::matrix4 &rh_matrix, const core::vector3df &rh_extend); void renderGI(const core::matrix4 &RHMatrix, const core::vector3df &rh_extend, unsigned shr, unsigned shg, unsigned shb); diff --git a/src/graphics/render_lighting.cpp b/src/graphics/render_lighting.cpp index 71b569abe..f1e3d08dc 100644 --- a/src/graphics/render_lighting.cpp +++ b/src/graphics/render_lighting.cpp @@ -152,13 +152,13 @@ void IrrDriver::renderLights(unsigned pointlightcount, bool hasShadow) m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]); } + m_rtts->getFBO(FBO_COMBINED_DIFFUSE_SPECULAR).Bind(); + { ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_ENVMAP)); - m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff); + m_post_processing->renderEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff, SkyboxCubeMap); } - m_rtts->getFBO(FBO_COMBINED_DIFFUSE_SPECULAR).Bind(); - // Render sunlight if and only if track supports shadow if (!World::getWorld() || World::getWorld()->getTrack()->hasShadows()) { diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index d445f96a9..4cdb4b051 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -1455,14 +1455,15 @@ namespace FullScreenShader AssignUniforms("direction", "col"); } - DiffuseEnvMapShader::DiffuseEnvMapShader() + EnvMapShader::EnvMapShader() { Program = LoadProgram(OBJECT, GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/decodeNormal.frag").c_str(), + GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/getPosFromUVDepth.frag").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/diffuseenvmap.frag").c_str()); AssignUniforms("TransposeViewMatrix", "blueLmn[0]", "greenLmn[0]", "redLmn[0]"); - AssignSamplerNames(Program, 0, "ntex"); + AssignSamplerNames(Program, 0, "ntex", 1, "dtex", 2, "tex"); } ShadowedSunLightShader::ShadowedSunLightShader() diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 3113ce75c..0c7e42133 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -395,10 +395,10 @@ public: SunLightShader(); }; -class DiffuseEnvMapShader : public ShaderHelperSingleton, std::vector, std::vector >, public TextureRead +class EnvMapShader : public ShaderHelperSingleton, std::vector, std::vector >, public TextureRead { public: - DiffuseEnvMapShader(); + EnvMapShader(); }; class ShadowedSunLightShader : public ShaderHelperSingleton, public TextureRead