summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorJonathan "Geenz" Goodman <geenz@geenzo.com>2023-04-08 19:30:58 -0700
committerJonathan "Geenz" Goodman <geenz@geenzo.com>2023-04-08 19:30:58 -0700
commit82ba39d2ff6eb0067bcb384246541eb54e206cd9 (patch)
treebe3343783622fddc3b543b7563033f78bf4a95e8 /indra
parent474739226433a74cdca05a949586139a9c9c0bbd (diff)
Start moving our post process into methods.
Lets make post processing make sense again. DRTVWR-559 SL-19524 SL-19513
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llviewerdisplay.cpp3
-rw-r--r--indra/newview/pipeline.cpp869
-rw-r--r--indra/newview/pipeline.h6
3 files changed, 430 insertions, 448 deletions
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 59333b6cee..a44452f0d1 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1307,9 +1307,6 @@ void render_ui(F32 zoom_factor, int subfield)
gGL.popMatrix();
}
- // Render our post process prior to the HUD, UI, etc.
- gPipeline.renderPostProcess();
-
// apply gamma correction and post effects
gPipeline.renderFinalize();
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index e4ffa5b6b0..a1183ccb0f 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6924,8 +6924,407 @@ void LLPipeline::renderPostProcess()
LLVertexBuffer::unbind();
+
+}
+
+LLRenderTarget* LLPipeline::screenTarget() {
+
+ bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
+ (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
+ RenderDepthOfField &&
+ !gCubeSnapshot;
+
+ bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot;
+
+ if (multisample || dof_enabled)
+ return &mRT->deferredLight;
+
+ return &mRT->screen;
+}
+
+void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst) {
+ // luminance sample and mipmap generation
+ {
+ LL_PROFILE_GPU_ZONE("luminance sample");
+
+ dst->bindTarget();
+
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+
+ gLuminanceProgram.bind();
+
+
+ S32 channel = 0;
+ channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE);
+ if (channel > -1)
+ {
+ src->bindTexture(0, channel, LLTexUnit::TFO_POINT);
+ }
+
+ channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
+ if (channel > -1)
+ {
+ mGlow[1].bindTexture(0, channel);
+ }
+
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ dst->flush();
+
+ dst->bindTexture(0, 0, LLTexUnit::TFO_TRILINEAR);
+ glGenerateMipmap(GL_TEXTURE_2D);
+
+ // note -- unbind AFTER the glGenerateMipMap so time in generatemipmap can be profiled under "Luminance"
+ // also note -- keep an eye on the performance of glGenerateMipmap, might need to replace it with a mip generation shader
+ gLuminanceProgram.unbind();
+ }
+}
+
+void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst) {
+ // exposure sample
+ {
+ LL_PROFILE_GPU_ZONE("exposure sample");
+
+ {
+ // copy last frame's exposure into mLastExposure
+ mLastExposure.bindTarget();
+ gCopyProgram.bind();
+ gGL.getTexUnit(0)->bind(&mExposureMap);
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ mLastExposure.flush();
+ }
+
+ dst->bindTarget();
+
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+
+ gExposureProgram.bind();
+
+ S32 channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
+ if (channel > -1)
+ {
+ src->bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR);
+ }
+
+ channel = gExposureProgram.enableTexture(LLShaderMgr::EXPOSURE_MAP);
+ if (channel > -1)
+ {
+ mLastExposure.bindTexture(0, channel);
+ }
+
+ static LLCachedControl<F32> dynamic_exposure_coefficient(gSavedSettings, "RenderDynamicExposureCoefficient", 0.175f);
+ static LLCachedControl<F32> dynamic_exposure_min(gSavedSettings, "RenderDynamicExposureMin", 0.125f);
+ static LLCachedControl<F32> dynamic_exposure_max(gSavedSettings, "RenderDynamicExposureMax", 1.3f);
+
+ static LLStaticHashedString dt("dt");
+ static LLStaticHashedString noiseVec("noiseVec");
+ static LLStaticHashedString dynamic_exposure_params("dynamic_exposure_params");
+ gExposureProgram.uniform1f(dt, gFrameIntervalSeconds);
+ gExposureProgram.uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0);
+ gExposureProgram.uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, dynamic_exposure_min, dynamic_exposure_max);
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ gGL.getTexUnit(channel)->unbind(screenTarget()->getUsage());
+ gExposureProgram.unbind();
+ dst->flush();
+ }
+}
+
+void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) {
+ dst->bindTarget();
+ // gamma correct lighting
+ {
+ LL_PROFILE_GPU_ZONE("gamma correct");
+
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+
+ // Apply gamma correction to the frame here.
+ gDeferredPostGammaCorrectProgram.bind();
+
+ S32 channel = 0;
+
+ gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_POINT);
+
+ gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::EXPOSURE_MAP, &mExposureMap);
+
+ gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, src->getWidth(), src->getHeight());
+
+ static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f);
+
+ F32 e = llclamp(exposure(), 0.5f, 4.f);
+
+ static LLStaticHashedString s_exposure("exposure");
+
+ gDeferredPostGammaCorrectProgram.uniform1f(s_exposure, e);
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ gGL.getTexUnit(channel)->unbind(src->getUsage());
+ gDeferredPostGammaCorrectProgram.unbind();
+ }
+ dst->flush();
+}
+
+void LLPipeline::copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst) {
+
+ if (RenderScreenSpaceReflections && !gCubeSnapshot)
+ {
+ LL_PROFILE_GPU_ZONE("ssr copy");
+ LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+
+ LLRenderTarget& depth_src = mRT->deferredScreen;
+
+ dst->bindTarget();
+ dst->clear();
+ gCopyDepthProgram.bind();
+
+ S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP);
+ S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
+
+ gGL.getTexUnit(diff_map)->bind(src);
+ gGL.getTexUnit(depth_map)->bind(&depth_src, true);
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ dst->flush();
+ }
+}
+
+void LLPipeline::renderGlow(LLRenderTarget* src, LLRenderTarget* dst) {
+ if (sRenderGlow)
+ {
+ LL_PROFILE_GPU_ZONE("glow");
+ mGlow[2].bindTarget();
+ mGlow[2].clear();
+
+ gGlowExtractProgram.bind();
+ F32 maxAlpha = RenderGlowMaxExtractAlpha;
+ F32 warmthAmount = RenderGlowWarmthAmount;
+ LLVector3 lumWeights = RenderGlowLumWeights;
+ LLVector3 warmthWeights = RenderGlowWarmthWeights;
+
+ gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, 9999);
+ gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha);
+ gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1],
+ lumWeights.mV[2]);
+ gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1],
+ warmthWeights.mV[2]);
+ gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount);
+
+ {
+ LLGLEnable blend_on(GL_BLEND);
+ LLGLEnable test(GL_ALPHA_TEST);
+
+ gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
+
+ gGlowExtractProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, src);
+
+ gGL.color4f(1, 1, 1, 1);
+ gPipeline.enableLightsFullbright();
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ mGlow[2].flush();
+ }
+
+ gGlowExtractProgram.unbind();
+
+ // power of two between 1 and 1024
+ U32 glowResPow = RenderGlowResolutionPow;
+ const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow));
+
+ S32 kernel = RenderGlowIterations * 2;
+ F32 delta = RenderGlowWidth / glow_res;
+ // Use half the glow width if we have the res set to less than 9 so that it looks
+ // almost the same in either case.
+ if (glowResPow < 9)
+ {
+ delta *= 0.5f;
+ }
+ F32 strength = RenderGlowStrength;
+
+ gGlowProgram.bind();
+ gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength);
+
+ for (S32 i = 0; i < kernel; i++)
+ {
+ mGlow[i % 2].bindTarget();
+ mGlow[i % 2].clear();
+
+ if (i == 0)
+ {
+ gGlowProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, &mGlow[2]);
+ }
+ else
+ {
+ gGlowProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, &mGlow[(i - 1) % 2]);
+ }
+
+ if (i % 2 == 0)
+ {
+ gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0);
+ }
+ else
+ {
+ gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta);
+ }
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ mGlow[i % 2].flush();
+ }
+
+ gGlowProgram.unbind();
+
+ }
+ else // !sRenderGlow, skip the glow ping-pong and just clear the result target
+ {
+ mGlow[1].bindTarget();
+ mGlow[1].clear();
+ mGlow[1].flush();
+ }
+
+ // Go ahead and do our glow combine here in our destination. We blit this later into the front buffer.
+
+ dst->bindTarget();
+
+ {
+ LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+
+ gGlowCombineProgram.bind();
+
+ gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src);
+ gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
+ gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]);
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+
+ dst->flush();
+}
+
+void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) {
+ {
+ llassert(!gCubeSnapshot);
+ bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete();
+ LLGLSLShader* shader = &gGlowCombineProgram;
+
+ S32 width = screenTarget()->getWidth();
+ S32 height = screenTarget()->getHeight();
+
+ // Present everything.
+ if (multisample)
+ {
+ LL_PROFILE_GPU_ZONE("aa");
+ // bake out texture2D with RGBL for FXAA shader
+ mRT->fxaaBuffer.bindTarget();
+
+ shader = &gDeferredPostNoDoFProgram;
+ shader->bind();
+
+ S32 channel = gDeferredPostNoDoFProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
+ if (channel > -1)
+ {
+ src->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+ }
+
+ {
+ LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+
+ shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
+ shader->unbind();
+
+ mRT->fxaaBuffer.flush();
+
+ dst->bindTarget();
+ shader = &gFXAAProgram;
+ shader->bind();
+
+ channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mRT->fxaaBuffer.getUsage());
+ if (channel > -1)
+ {
+ mRT->fxaaBuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+ }
+
+ F32 scale_x = (F32)width / mRT->fxaaBuffer.getWidth();
+ F32 scale_y = (F32)height / mRT->fxaaBuffer.getHeight();
+ shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y);
+ shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y);
+ shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y,
+ 0.5f / width * scale_x, 0.5f / height * scale_y);
+ shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y,
+ 2.f / width * scale_x, 2.f / height * scale_y);
+
+ {
+ // at this point we should pointed at the backbuffer (or a snapshot render target)
+ LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ S32 depth_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
+ gGL.getTexUnit(depth_channel)->bind(&mRT->deferredScreen, true);
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+
+ shader->unbind();
+ dst->flush();
+ }
+ }
+}
+
+void LLPipeline::renderFinalize()
+{
+ LLVertexBuffer::unbind();
+ LLGLState::checkStates();
+
+ assertInitialized();
+
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
+ LL_PROFILE_GPU_ZONE("renderFinalize");
+
+ gGL.color4f(1, 1, 1, 1);
+ LLGLDepthTest depth(GL_FALSE);
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable cull(GL_CULL_FACE);
+
+ enableLightsFullbright();
+
+ LLGLDisable test(GL_ALPHA_TEST);
+
+ gGL.setColorMask(true, true);
+ glClearColor(0, 0, 0, 0);
+
+ if (!gCubeSnapshot)
{
- bool dof_enabled =
+
+ copyScreenSpaceReflections(&mSceneMap, screenTarget());
+
+ generateLuminance(screenTarget(), &mLuminanceMap);
+
+ generateExposure(&mLuminanceMap, &mExposureMap);
+
+ gammaCorrect(screenTarget(), &mPostMap);
+
+ LLVertexBuffer::unbind();
+ }
+
+ renderGlow(&mPostMap, screenTarget());
+ /*
+ {
+ bool dof_enabled =
(RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
RenderDepthOfField &&
!gCubeSnapshot;
@@ -7041,7 +7440,7 @@ void LLPipeline::renderPostProcess()
F32 magnification = focal_length / (subject_distance - focal_length);
{ // build diffuse+bloom+CoF
- mRT->deferredLight.bindTarget();
+ mRT->deferredLight.bindTarget();
shader = &gDeferredCoFProgram;
bindDeferredShader(*shader);
@@ -7059,20 +7458,11 @@ void LLPipeline::renderPostProcess()
shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
- gGL.vertex2f(-1, -1);
-
- gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
- gGL.vertex2f(-1, 3);
-
- gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
- gGL.vertex2f(3, -1);
-
- gGL.end();
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
unbindDeferredShader(*shader);
- mRT->deferredLight.flush();
+ mRT->deferredLight.flush();
}
U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale);
@@ -7085,26 +7475,17 @@ void LLPipeline::renderPostProcess()
shader = &gDeferredPostProgram;
bindDeferredShader(*shader);
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());
if (channel > -1)
{
- mRT->deferredLight.bindTexture(0, channel);
+ mRT->deferredLight.bindTexture(0, channel);
}
shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
- gGL.vertex2f(-1, -1);
-
- gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
- gGL.vertex2f(-1, 3);
-
- gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
- gGL.vertex2f(3, -1);
-
- gGL.end();
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
unbindDeferredShader(*shader);
mRT->screen.flush();
@@ -7140,17 +7521,8 @@ void LLPipeline::renderPostProcess()
shader->uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)mRT->screen.getWidth());
shader->uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)mRT->screen.getHeight());
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
- gGL.vertex2f(-1, -1);
-
- gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
- gGL.vertex2f(-1, 3);
-
- gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
- gGL.vertex2f(3, -1);
-
- gGL.end();
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
unbindDeferredShader(*shader);
@@ -7177,17 +7549,8 @@ void LLPipeline::renderPostProcess()
mRT->screen.bindTexture(0, channel);
}
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
- gGL.vertex2f(-1, -1);
-
- gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
- gGL.vertex2f(-1, 3);
-
- gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
- gGL.vertex2f(3, -1);
-
- gGL.end();
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
unbindDeferredShader(*shader);
@@ -7196,412 +7559,28 @@ void LLPipeline::renderPostProcess()
mRT->deferredLight.flush();
}
}
- }
-}
-
-LLRenderTarget* LLPipeline::screenTarget() {
-
- bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
- (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
- RenderDepthOfField &&
- !gCubeSnapshot;
-
- bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot;
-
- if (multisample || dof_enabled)
- return &mRT->deferredLight;
-
- return &mRT->screen;
-}
-
-void LLPipeline::renderFinalize()
-{
- LLVertexBuffer::unbind();
- LLGLState::checkStates();
-
- assertInitialized();
-
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
- LL_PROFILE_GPU_ZONE("renderFinalize");
-
- gGL.color4f(1, 1, 1, 1);
- LLGLDepthTest depth(GL_FALSE);
- LLGLDisable blend(GL_BLEND);
- LLGLDisable cull(GL_CULL_FACE);
-
- enableLightsFullbright();
-
- LLGLDisable test(GL_ALPHA_TEST);
-
- gGL.setColorMask(true, true);
- glClearColor(0, 0, 0, 0);
-
- if (!gCubeSnapshot)
- {
- LLRenderTarget* screen_target = screenTarget();
-
- if (RenderScreenSpaceReflections && !gCubeSnapshot)
- {
- LL_PROFILE_GPU_ZONE("ssr copy");
- LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
-
- LLRenderTarget& src = *screen_target;
- LLRenderTarget& depth_src = mRT->deferredScreen;
- LLRenderTarget& dst = mSceneMap;
-
- dst.bindTarget();
- dst.clear();
- gCopyDepthProgram.bind();
-
- S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP);
- S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
-
- gGL.getTexUnit(diff_map)->bind(&src);
- gGL.getTexUnit(depth_map)->bind(&depth_src, true);
-
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
- dst.flush();
- }
-
- // luminance sample and mipmap generation
- {
- LL_PROFILE_GPU_ZONE("luminance sample");
-
- mLuminanceMap.bindTarget();
-
- LLGLDepthTest depth(GL_FALSE, GL_FALSE);
-
- gLuminanceProgram.bind();
-
-
- S32 channel = 0;
- channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE);
- if (channel > -1)
- {
- screenTarget()->bindTexture(0, channel, LLTexUnit::TFO_POINT);
- }
-
- channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
- if (channel > -1)
- {
- mGlow[1].bindTexture(0, channel);
- }
-
-
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- mLuminanceMap.flush();
-
- mLuminanceMap.bindTexture(0, 0, LLTexUnit::TFO_TRILINEAR);
- glGenerateMipmap(GL_TEXTURE_2D);
-
- // note -- unbind AFTER the glGenerateMipMap so time in generatemipmap can be profiled under "Luminance"
- // also note -- keep an eye on the performance of glGenerateMipmap, might need to replace it with a mip generation shader
- gLuminanceProgram.unbind();
- }
-
- // exposure sample
- {
- LL_PROFILE_GPU_ZONE("exposure sample");
-
- {
- // copy last frame's exposure into mLastExposure
- mLastExposure.bindTarget();
- gCopyProgram.bind();
- gGL.getTexUnit(0)->bind(&mExposureMap);
-
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
- mLastExposure.flush();
- }
-
- mExposureMap.bindTarget();
-
- LLGLDepthTest depth(GL_FALSE, GL_FALSE);
-
- gExposureProgram.bind();
+ }*/
- S32 channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
- if (channel > -1)
- {
- mLuminanceMap.bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR);
- }
-
- channel = gExposureProgram.enableTexture(LLShaderMgr::EXPOSURE_MAP);
- if (channel > -1)
- {
- mLastExposure.bindTexture(0, channel);
- }
-
- static LLCachedControl<F32> dynamic_exposure_coefficient(gSavedSettings, "RenderDynamicExposureCoefficient", 0.175f);
- static LLCachedControl<F32> dynamic_exposure_min(gSavedSettings, "RenderDynamicExposureMin", 0.125f);
- static LLCachedControl<F32> dynamic_exposure_max(gSavedSettings, "RenderDynamicExposureMax", 1.3f);
-
- static LLStaticHashedString dt("dt");
- static LLStaticHashedString noiseVec("noiseVec");
- static LLStaticHashedString dynamic_exposure_params("dynamic_exposure_params");
- gExposureProgram.uniform1f(dt, gFrameIntervalSeconds);
- gExposureProgram.uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0);
- gExposureProgram.uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, dynamic_exposure_min, dynamic_exposure_max);
-
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
- gGL.getTexUnit(channel)->unbind(screenTarget()->getUsage());
- gExposureProgram.unbind();
- mExposureMap.flush();
- }
-
- mPostMap.bindTarget();
-
- // gamma correct lighting
- {
- LL_PROFILE_GPU_ZONE("gamma correct");
-
- LLGLDepthTest depth(GL_FALSE, GL_FALSE);
-
- // Apply gamma correction to the frame here.
- gDeferredPostGammaCorrectProgram.bind();
-
- S32 channel = 0;
+ //applyFXAA(screenTarget(), screenTarget());
- gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, screenTarget(), false, LLTexUnit::TFO_POINT);
+ // Present the screen target.
- gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::EXPOSURE_MAP, &mExposureMap);
-
- gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screenTarget()->getWidth(), screenTarget()->getHeight());
-
- static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f);
-
- F32 e = llclamp(exposure(), 0.5f, 4.f);
-
- static LLStaticHashedString s_exposure("exposure");
-
- gDeferredPostGammaCorrectProgram.uniform1f(s_exposure, e);
-
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
- gGL.getTexUnit(channel)->unbind(screenTarget()->getUsage());
- gDeferredPostGammaCorrectProgram.unbind();
- }
-
- mPostMap.flush();
-
- LLVertexBuffer::unbind();
- }
-
- if (sRenderGlow)
- {
- LL_PROFILE_GPU_ZONE("glow");
- mGlow[2].bindTarget();
- mGlow[2].clear();
-
- gGlowExtractProgram.bind();
- F32 maxAlpha = RenderGlowMaxExtractAlpha;
- F32 warmthAmount = RenderGlowWarmthAmount;
- LLVector3 lumWeights = RenderGlowLumWeights;
- LLVector3 warmthWeights = RenderGlowWarmthWeights;
-
- gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, 9999);
- gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha);
- gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1],
- lumWeights.mV[2]);
- gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1],
- warmthWeights.mV[2]);
- gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount);
-
- {
- LLGLEnable blend_on(GL_BLEND);
- LLGLEnable test(GL_ALPHA_TEST);
+ gDeferredPostNoDoFProgram.bind();
- gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
-
- gGlowExtractProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, &mPostMap);
-
- gGL.color4f(1, 1, 1, 1);
- gPipeline.enableLightsFullbright();
-
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
- mGlow[2].flush();
- }
-
- gGlowExtractProgram.unbind();
-
- // power of two between 1 and 1024
- U32 glowResPow = RenderGlowResolutionPow;
- const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow));
-
- S32 kernel = RenderGlowIterations * 2;
- F32 delta = RenderGlowWidth / glow_res;
- // Use half the glow width if we have the res set to less than 9 so that it looks
- // almost the same in either case.
- if (glowResPow < 9)
- {
- delta *= 0.5f;
- }
- F32 strength = RenderGlowStrength;
-
- gGlowProgram.bind();
- gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength);
-
- for (S32 i = 0; i < kernel; i++)
- {
- mGlow[i % 2].bindTarget();
- mGlow[i % 2].clear();
-
- if (i == 0)
- {
- gGlowProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, &mGlow[2]);
- }
- else
- {
- gGlowProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, &mGlow[(i - 1) % 2]);
- }
-
- if (i % 2 == 0)
- {
- gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0);
- }
- else
- {
- gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta);
- }
-
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
- mGlow[i % 2].flush();
- }
-
- gGlowProgram.unbind();
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
- }
- else // !sRenderGlow, skip the glow ping-pong and just clear the result target
+ S32 channel = gDeferredPostNoDoFProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screenTarget()->getUsage());
+ if (channel > -1)
{
- mGlow[1].bindTarget();
- mGlow[1].clear();
- mGlow[1].flush();
+ screenTarget()->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
}
{
- llassert(!gCubeSnapshot);
- bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete();
- LLGLSLShader* shader = &gGlowCombineProgram;
-
- S32 width = screenTarget()->getWidth();
- S32 height = screenTarget()->getHeight();
-
- S32 channel = -1;
-
- // Present everything.
- if (multisample)
- {
- LL_PROFILE_GPU_ZONE("aa");
- // bake out texture2D with RGBL for FXAA shader
- mRT->fxaaBuffer.bindTarget();
-
- glViewport(0, 0, width, height);
-
- shader = &gGlowCombineFXAAProgram;
-
- shader->bind();
- shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height);
-
- channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mPostMap.getUsage());
- if (channel > -1)
- {
- mPostMap.bindTexture(0, channel);
- }
-
- channel = shader->enableTexture(LLShaderMgr::DEFERRED_EMISSIVE, mGlow[1].getUsage());
- if (channel > -1)
- {
- mGlow[1].bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
- }
-
- {
- LLGLDepthTest depth_test(GL_FALSE, GL_FALSE, GL_ALWAYS);
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- }
-
- gGL.flush();
-
- shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mPostMap.getUsage());
- shader->unbind();
-
- mRT->fxaaBuffer.flush();
-
- shader = &gFXAAProgram;
- shader->bind();
-
- channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mRT->fxaaBuffer.getUsage());
- if (channel > -1)
- {
- mRT->fxaaBuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
- }
-
- gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
- gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
- gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
- gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
- glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
-
- F32 scale_x = (F32)width / mRT->fxaaBuffer.getWidth();
- F32 scale_y = (F32)height / mRT->fxaaBuffer.getHeight();
- shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y);
- shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y);
- shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y,
- 0.5f / width * scale_x, 0.5f / height * scale_y);
- shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y,
- 2.f / width * scale_x, 2.f / height * scale_y);
-
- {
- // at this point we should pointed at the backbuffer (or a snapshot render target)
- llassert(gSnapshot || LLRenderTarget::sCurFBO == 0);
- LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
- S32 depth_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
- gGL.getTexUnit(depth_channel)->bind(&mRT->deferredScreen, true);
-
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- }
-
- shader->unbind();
- }
- else
- {
- // at this point we should pointed at the backbuffer (or a snapshot render target)
- llassert(gSnapshot || LLRenderTarget::sCurFBO == 0);
-
- LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
-
- shader->bind();
-
- shader->bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &mPostMap);
- shader->bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
- shader->bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]);
-
- gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
- gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
- gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
- gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
- glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
-
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
- gGL.flush();
- shader->unbind();
- }
+ LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
}
+ gDeferredPostNoDoFProgram.unbind();
+
gGL.setSceneBlendType(LLRender::BT_ALPHA);
if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index a231084e5c..3ed9ed73a8 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -135,6 +135,12 @@ public:
void generateImpostor(LLVOAvatar* avatar, bool preview_avatar = false);
void bindScreenToTexture();
void renderFinalize();
+ void copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst);
+ void generateLuminance(LLRenderTarget* src, LLRenderTarget* dst);
+ void generateExposure(LLRenderTarget* src, LLRenderTarget* dst);
+ void gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst);
+ void renderGlow(LLRenderTarget* src, LLRenderTarget* dst);
+ void applyFXAA(LLRenderTarget* src, LLRenderTarget* dst);
void renderPostProcess();
LLRenderTarget* screenTarget();