Added exposure pass calculating the bloom/tonemap exposure based on what the eye is seeing
This commit is contained in:
parent
1e6b99cebd
commit
f7b6b1433c
17 changed files with 358 additions and 40 deletions
|
|
@ -75,7 +75,10 @@ CUSTOM_CVAR(Float, gl_bloom_amount, 1.4f, 0)
|
|||
if (self < 0.1f) self = 0.1f;
|
||||
}
|
||||
|
||||
CVAR(Float, gl_exposure, 0.0f, 0)
|
||||
CVAR(Float, gl_exposure_scale, 0.75f, 0)
|
||||
CVAR(Float, gl_exposure_min, 0.35f, 0)
|
||||
CVAR(Float, gl_exposure_base, 0.35f, 0)
|
||||
CVAR(Float, gl_exposure_speed, 0.05f, 0)
|
||||
|
||||
CUSTOM_CVAR(Int, gl_tonemap, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
{
|
||||
|
|
@ -106,6 +109,78 @@ void FGLRenderer::RenderScreenQuad()
|
|||
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Extracts light average from the scene and updates the camera exposure texture
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FGLRenderer::UpdateCameraExposure()
|
||||
{
|
||||
if (!gl_bloom && gl_tonemap == 0)
|
||||
return;
|
||||
|
||||
FGLDebug::PushGroup("UpdateCameraExposure");
|
||||
|
||||
FGLPostProcessState savedState;
|
||||
savedState.SaveTextureBinding1();
|
||||
|
||||
// Extract light level from scene texture:
|
||||
const auto &level0 = mBuffers->ExposureLevels[0];
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, level0.Framebuffer);
|
||||
glViewport(0, 0, level0.Width, level0.Height);
|
||||
mBuffers->BindCurrentTexture(0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
mExposureExtractShader->Bind();
|
||||
mExposureExtractShader->SceneTexture.Set(0);
|
||||
mExposureExtractShader->Scale.Set(mSceneViewport.width / (float)mScreenViewport.width, mSceneViewport.height / (float)mScreenViewport.height);
|
||||
mExposureExtractShader->Offset.Set(mSceneViewport.left / (float)mScreenViewport.width, mSceneViewport.top / (float)mScreenViewport.height);
|
||||
RenderScreenQuad();
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
// Find the average value:
|
||||
for (int i = 0; i + 1 < mBuffers->ExposureLevels.Size(); i++)
|
||||
{
|
||||
const auto &level = mBuffers->ExposureLevels[i];
|
||||
const auto &next = mBuffers->ExposureLevels[i + 1];
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, next.Framebuffer);
|
||||
glViewport(0, 0, next.Width, next.Height);
|
||||
glBindTexture(GL_TEXTURE_2D, level.Texture);
|
||||
mExposureAverageShader->Bind();
|
||||
mExposureAverageShader->ExposureTexture.Set(0);
|
||||
RenderScreenQuad();
|
||||
}
|
||||
|
||||
// Combine average value with current camera exposure:
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mBuffers->ExposureFB);
|
||||
glViewport(0, 0, 1, 1);
|
||||
if (!mBuffers->FirstExposureFrame)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
mBuffers->FirstExposureFrame = false;
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, mBuffers->ExposureLevels.Last().Texture);
|
||||
mExposureCombineShader->Bind();
|
||||
mExposureCombineShader->ExposureTexture.Set(0);
|
||||
mExposureCombineShader->ExposureBase.Set(gl_exposure_base);
|
||||
mExposureCombineShader->ExposureMin.Set(gl_exposure_min);
|
||||
mExposureCombineShader->ExposureScale.Set(gl_exposure_scale);
|
||||
mExposureCombineShader->ExposureSpeed.Set(gl_exposure_speed);
|
||||
RenderScreenQuad();
|
||||
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
||||
|
||||
FGLDebug::PopGroup();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Adds bloom contribution to scene texture
|
||||
|
|
@ -121,6 +196,7 @@ void FGLRenderer::BloomScene()
|
|||
FGLDebug::PushGroup("BloomScene");
|
||||
|
||||
FGLPostProcessState savedState;
|
||||
savedState.SaveTextureBinding1();
|
||||
|
||||
const float blurAmount = gl_bloom_amount;
|
||||
int sampleCount = gl_bloom_kernel_size;
|
||||
|
|
@ -133,9 +209,12 @@ void FGLRenderer::BloomScene()
|
|||
mBuffers->BindCurrentTexture(0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, mBuffers->ExposureTexture);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
mBloomExtractShader->Bind();
|
||||
mBloomExtractShader->SceneTexture.Set(0);
|
||||
mBloomExtractShader->Exposure.Set(mCameraExposure);
|
||||
mBloomExtractShader->ExposureTexture.Set(1);
|
||||
mBloomExtractShader->Scale.Set(mSceneViewport.width / (float)mScreenViewport.width, mSceneViewport.height / (float)mScreenViewport.height);
|
||||
mBloomExtractShader->Offset.Set(mSceneViewport.left / (float)mScreenViewport.width, mSceneViewport.top / (float)mScreenViewport.height);
|
||||
RenderScreenQuad();
|
||||
|
|
@ -220,7 +299,12 @@ void FGLRenderer::TonemapScene()
|
|||
}
|
||||
else
|
||||
{
|
||||
mTonemapShader->Exposure.Set(mCameraExposure);
|
||||
savedState.SaveTextureBinding1();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, mBuffers->ExposureTexture);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
mTonemapShader->ExposureTexture.Set(1);
|
||||
}
|
||||
|
||||
RenderScreenQuad();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue