Emulate envmap specular reflexion

This commit is contained in:
vlj 2014-10-06 02:19:21 +02:00
parent cb40f68229
commit c7b98c4e6c
6 changed files with 31 additions and 13 deletions

View File

@ -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.));
}

View File

@ -221,19 +221,19 @@ void renderBloom(GLuint in)
DrawFullScreenEffect<FullScreenShader::BloomShader>();
}
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<GLuint>(irr_driver->getRenderTargetTexture(RTT_NORMAL_AND_DEPTH)));
FullScreenShader::EnvMapShader::getInstance()->SetTextureUnits(createVector<GLuint>(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<float>(bSHCoeff, bSHCoeff + 9), std::vector<float>(gSHCoeff, gSHCoeff + 9), std::vector<float>(rSHCoeff, rSHCoeff + 9));
FullScreenShader::EnvMapShader::getInstance()->setUniforms(TVM, std::vector<float>(bSHCoeff, bSHCoeff + 9), std::vector<float>(gSHCoeff, gSHCoeff + 9), std::vector<float>(rSHCoeff, rSHCoeff + 9));
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);

View File

@ -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);

View File

@ -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())
{

View File

@ -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()

View File

@ -395,10 +395,10 @@ public:
SunLightShader();
};
class DiffuseEnvMapShader : public ShaderHelperSingleton<DiffuseEnvMapShader, core::matrix4, std::vector<float>, std::vector<float>, std::vector<float> >, public TextureRead<Nearest_Filtered>
class EnvMapShader : public ShaderHelperSingleton<EnvMapShader, core::matrix4, std::vector<float>, std::vector<float>, std::vector<float> >, public TextureRead<Nearest_Filtered, Nearest_Filtered, Trilinear_cubemap>
{
public:
DiffuseEnvMapShader();
EnvMapShader();
};
class ShadowedSunLightShader : public ShaderHelperSingleton<ShadowedSunLightShader, core::vector3df, video::SColorf>, public TextureRead<Nearest_Filtered, Nearest_Filtered, Shadow_Sampler>