summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorJonathan "Geenz" Goodman <geenz@lindenlab.com>2023-04-12 16:40:51 -0700
committerGitHub <noreply@github.com>2023-04-12 16:40:51 -0700
commit88d35aaf0f6478c7d426c8d01b230d089a52aaf9 (patch)
tree2cd307846fafb16c4f53c464a2e55b1d1fd33ca6 /indra
parentbd7a924a9423105f0acaaaf271d611d435299d14 (diff)
parent6d5c16971654764de28833fd886f522212d3746d (diff)
Merge pull request #166 from secondlife/DRTVWR-559-post-refactor
Drtvwr 559 post processing refactor
Diffstat (limited to 'indra')
-rw-r--r--indra/llrender/llglslshader.cpp11
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl3
-rw-r--r--indra/newview/llviewerdisplay.cpp3
-rw-r--r--indra/newview/pipeline.cpp896
-rw-r--r--indra/newview/pipeline.h9
5 files changed, 447 insertions, 475 deletions
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index d27528296f..b12de563e4 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -1091,7 +1091,6 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLRenderTarget* texture, bool depth,
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
- LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
return -1;
}
@@ -1099,9 +1098,13 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLRenderTarget* texture, bool depth,
if (uniform > -1)
{
- bool has_mips = mode == LLTexUnit::TFO_TRILINEAR || mode == LLTexUnit::TFO_ANISOTROPIC;
- gGL.getTexUnit(uniform)->bindManual(texture->getUsage(), texture->getTexture(0), has_mips);
-
+ if (depth) {
+ gGL.getTexUnit(uniform)->bind(texture, true);
+ }
+ else {
+ bool has_mips = mode == LLTexUnit::TFO_TRILINEAR || mode == LLTexUnit::TFO_ANISOTROPIC;
+ gGL.getTexUnit(uniform)->bindManual(texture->getUsage(), texture->getTexture(0), has_mips);
+ }
gGL.getTexUnit(uniform)->setTextureFilteringOption(mode);
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl
index 6cc83138a2..c50548d528 100644
--- a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl
@@ -30,7 +30,6 @@
out vec4 frag_color;
uniform sampler2D diffuseRect;
-uniform sampler2D emissiveRect;
uniform vec2 screen_res;
@@ -38,7 +37,7 @@ in vec2 vary_tc;
void main()
{
- vec3 col = texture(diffuseRect, vary_tc).rgb + texture(emissiveRect, vary_tc).rgb;
+ vec3 col = texture(diffuseRect, vary_tc).rgb;
frag_color = vec4(col.rgb, dot(col.rgb, vec3(0.299, 0.587, 0.144)));
}
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 4266c16f94..3e9a1bb353 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6924,279 +6924,7 @@ void LLPipeline::renderPostProcess()
LLVertexBuffer::unbind();
- {
- bool dof_enabled =
- (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
- RenderDepthOfField &&
- !gCubeSnapshot;
-
- bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot;
-
- gViewerWindow->setup3DViewport();
-
- if (dof_enabled)
- {
- LL_PROFILE_GPU_ZONE("dof");
- LLGLSLShader* shader = &gDeferredPostProgram;
- LLGLDisable blend(GL_BLEND);
-
- // depth of field focal plane calculations
- static F32 current_distance = 16.f;
- static F32 start_distance = 16.f;
- static F32 transition_time = 1.f;
-
- LLVector3 focus_point;
-
- LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject();
- if (obj && obj->mDrawable && obj->isSelected())
- { // focus on selected media object
- S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace();
- if (obj && obj->mDrawable)
- {
- LLFace* face = obj->mDrawable->getFace(face_idx);
- if (face)
- {
- focus_point = face->getPositionAgent();
- }
- }
- }
-
- if (focus_point.isExactlyZero())
- {
- if (LLViewerJoystick::getInstance()->getOverrideCamera())
- { // focus on point under cursor
- focus_point.set(gDebugRaycastIntersection.getF32ptr());
- }
- else if (gAgentCamera.cameraMouselook())
- { // focus on point under mouselook crosshairs
- LLVector4a result;
- result.clear();
-
- gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, NULL, &result);
-
- focus_point.set(result.getF32ptr());
- }
- else
- {
- // focus on alt-zoom target
- LLViewerRegion* region = gAgent.getRegion();
- if (region)
- {
- focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal());
- }
- }
- }
-
- LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
- F32 target_distance = 16.f;
- if (!focus_point.isExactlyZero())
- {
- target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye);
- }
-
- if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f)
- { // large shift happened, interpolate smoothly to new target distance
- transition_time = 0.f;
- start_distance = current_distance;
- }
- else if (transition_time < 1.f)
- { // currently in a transition, continue interpolating
- transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value();
- transition_time = llmin(transition_time, 1.f);
-
- F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f;
- current_distance = start_distance + (target_distance - start_distance) * t;
- }
- else
- { // small or no change, just snap to target distance
- current_distance = target_distance;
- }
-
- // convert to mm
- F32 subject_distance = current_distance * 1000.f;
- F32 fnumber = CameraFNumber;
- F32 default_focal_length = CameraFocalLength;
-
- F32 fov = LLViewerCamera::getInstance()->getView();
-
- const F32 default_fov = CameraFieldOfView * F_PI / 180.f;
-
- // F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight();
-
- F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f);
-
- F32 focal_length = dv / (2 * tanf(fov / 2.f));
-
- // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle);
-
- // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f))
- // where N = fnumber
- // s2 = dot distance
- // s1 = subject distance
- // f = focal length
- //
-
- F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length));
- blur_constant /= 1000.f; // convert to meters for shader
- F32 magnification = focal_length / (subject_distance - focal_length);
-
- { // build diffuse+bloom+CoF
- mRT->deferredLight.bindTarget();
- shader = &gDeferredCoFProgram;
-
- bindDeferredShader(*shader);
-
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
- if (channel > -1)
- {
- mRT->screen.bindTexture(0, channel);
- }
-
- shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f);
- shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant);
- shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle));
- shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification);
- 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();
-
- unbindDeferredShader(*shader);
- mRT->deferredLight.flush();
- }
-
- U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale);
- U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale);
-
- { // perform DoF sampling at half-res (preserve alpha channel)
- mRT->screen.bindTarget();
- glViewport(0, 0, dof_width, dof_height);
- gGL.setColorMask(true, false);
-
- shader = &gDeferredPostProgram;
- bindDeferredShader(*shader);
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());
- if (channel > -1)
- {
- 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();
-
- unbindDeferredShader(*shader);
- mRT->screen.flush();
- gGL.setColorMask(true, true);
- }
-
- { // combine result based on alpha
- if (multisample)
- {
- mRT->deferredLight.bindTarget();
- glViewport(0, 0, mRT->deferredScreen.getWidth(), mRT->deferredScreen.getHeight());
- }
- else
- {
- 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]);
- }
-
- shader = &gDeferredDoFCombineProgram;
- bindDeferredShader(*shader);
-
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
- if (channel > -1)
- {
- mRT->screen.bindTexture(0, channel);
- }
-
- shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
- shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
- 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();
-
- unbindDeferredShader(*shader);
-
- if (multisample)
- {
- mRT->deferredLight.flush();
- }
- }
- }
- else
- {
- LL_PROFILE_GPU_ZONE("no dof");
- if (multisample)
- {
- mRT->deferredLight.bindTarget();
- }
- LLGLSLShader* shader = &gDeferredPostNoDoFProgram;
-
- bindDeferredShader(*shader);
-
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
- if (channel > -1)
- {
- 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();
-
- unbindDeferredShader(*shader);
-
- if (multisample)
- {
- mRT->deferredLight.flush();
- }
- }
- }
+
}
LLRenderTarget* LLPipeline::screenTarget() {
@@ -7214,186 +6942,161 @@ LLRenderTarget* LLPipeline::screenTarget() {
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();
+void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst) {
+ // luminance sample and mipmap generation
+ {
+ LL_PROFILE_GPU_ZONE("luminance sample");
- S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP);
- S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
+ dst->bindTarget();
- gGL.getTexUnit(diff_map)->bind(&src);
- gGL.getTexUnit(depth_map)->bind(&depth_src, true);
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ gLuminanceProgram.bind();
- dst.flush();
- }
+ S32 channel = 0;
+ channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE);
+ if (channel > -1)
+ {
+ src->bindTexture(0, channel, LLTexUnit::TFO_POINT);
+ }
- // luminance sample and mipmap generation
- {
- LL_PROFILE_GPU_ZONE("luminance sample");
+ channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
+ if (channel > -1)
+ {
+ mGlow[1].bindTexture(0, channel);
+ }
- mLuminanceMap.bindTarget();
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ dst->flush();
- LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+ dst->bindTexture(0, 0, LLTexUnit::TFO_TRILINEAR);
+ glGenerateMipmap(GL_TEXTURE_2D);
- gLuminanceProgram.bind();
+ // 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");
- S32 channel = 0;
- channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE);
- if (channel > -1)
- {
- screenTarget()->bindTexture(0, channel, LLTexUnit::TFO_POINT);
- }
+ {
+ // copy last frame's exposure into mLastExposure
+ mLastExposure.bindTarget();
+ gCopyProgram.bind();
+ gGL.getTexUnit(0)->bind(dst);
- channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
- if (channel > -1)
- {
- mGlow[1].bindTexture(0, channel);
- }
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ mLastExposure.flush();
+ }
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- mLuminanceMap.flush();
+ dst->bindTarget();
- mLuminanceMap.bindTexture(0, 0, LLTexUnit::TFO_TRILINEAR);
- glGenerateMipmap(GL_TEXTURE_2D);
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
- // 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();
- }
+ gExposureProgram.bind();
- // exposure sample
- {
- LL_PROFILE_GPU_ZONE("exposure sample");
+ S32 channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
+ if (channel > -1)
+ {
+ mLuminanceMap.bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR);
+ }
- {
- // copy last frame's exposure into mLastExposure
- mLastExposure.bindTarget();
- gCopyProgram.bind();
- gGL.getTexUnit(0)->bind(&mExposureMap);
+ channel = gExposureProgram.enableTexture(LLShaderMgr::EXPOSURE_MAP);
+ if (channel > -1)
+ {
+ mLastExposure.bindTexture(0, channel);
+ }
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ static LLStaticHashedString dt("dt");
+ static LLStaticHashedString noiseVec("noiseVec");
+ static LLStaticHashedString dynamic_exposure_params("dynamic_exposure_params");
+ 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);
- mLastExposure.flush();
- }
+ 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);
- mExposureMap.bindTarget();
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- LLGLDepthTest depth(GL_FALSE, GL_FALSE);
-
- gExposureProgram.bind();
+ gGL.getTexUnit(channel)->unbind(screenTarget()->getUsage());
+ gExposureProgram.unbind();
+ dst->flush();
+ }
+}
- S32 channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
- if (channel > -1)
- {
- mLuminanceMap.bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR);
- }
+void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) {
+ dst->bindTarget();
+ // gamma correct lighting
+ {
+ LL_PROFILE_GPU_ZONE("gamma correct");
- channel = gExposureProgram.enableTexture(LLShaderMgr::EXPOSURE_MAP);
- if (channel > -1)
- {
- mLastExposure.bindTexture(0, channel);
- }
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
- static LLStaticHashedString dt("dt");
- static LLStaticHashedString noiseVec("noiseVec");
- static LLStaticHashedString dynamic_exposure_params("dynamic_exposure_params");
- 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);
+ // Apply gamma correction to the frame here.
+ gDeferredPostGammaCorrectProgram.bind();
- 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);
+ S32 channel = 0;
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_POINT);
- gGL.getTexUnit(channel)->unbind(screenTarget()->getUsage());
- gExposureProgram.unbind();
- mExposureMap.flush();
- }
+ gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::EXPOSURE_MAP, &mExposureMap);
- mPostMap.bindTarget();
+ gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, src->getWidth(), src->getHeight());
- // gamma correct lighting
- {
- LL_PROFILE_GPU_ZONE("gamma correct");
+ static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f);
- LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+ F32 e = llclamp(exposure(), 0.5f, 4.f);
- // Apply gamma correction to the frame here.
- gDeferredPostGammaCorrectProgram.bind();
-
- S32 channel = 0;
+ static LLStaticHashedString s_exposure("exposure");
- gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, screenTarget(), false, LLTexUnit::TFO_POINT);
+ gDeferredPostGammaCorrectProgram.uniform1f(s_exposure, e);
- gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::EXPOSURE_MAP, &mExposureMap);
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screenTarget()->getWidth(), screenTarget()->getHeight());
+ gGL.getTexUnit(channel)->unbind(src->getUsage());
+ gDeferredPostGammaCorrectProgram.unbind();
+ }
+ dst->flush();
+}
- static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f);
+void LLPipeline::copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst) {
- F32 e = llclamp(exposure(), 0.5f, 4.f);
+ if (RenderScreenSpaceReflections && !gCubeSnapshot)
+ {
+ LL_PROFILE_GPU_ZONE("ssr copy");
+ LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
- static LLStaticHashedString s_exposure("exposure");
+ LLRenderTarget& depth_src = mRT->deferredScreen;
- gDeferredPostGammaCorrectProgram.uniform1f(s_exposure, e);
+ dst->bindTarget();
+ dst->clear();
+ gCopyDepthProgram.bind();
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP);
+ S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
- gGL.getTexUnit(channel)->unbind(screenTarget()->getUsage());
- gDeferredPostGammaCorrectProgram.unbind();
- }
+ gGL.getTexUnit(diff_map)->bind(src);
+ gGL.getTexUnit(depth_map)->bind(&depth_src, true);
- mPostMap.flush();
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- LLVertexBuffer::unbind();
- }
+ dst->flush();
+ }
+}
+void LLPipeline::generateGlow(LLRenderTarget* src) {
if (sRenderGlow)
{
LL_PROFILE_GPU_ZONE("glow");
@@ -7420,7 +7123,7 @@ void LLPipeline::renderFinalize()
gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
- gGlowExtractProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, &mPostMap);
+ gGlowExtractProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, src);
gGL.color4f(1, 1, 1, 1);
gPipeline.enableLightsFullbright();
@@ -7480,7 +7183,7 @@ void LLPipeline::renderFinalize()
}
gGlowProgram.unbind();
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
}
else // !sRenderGlow, skip the glow ping-pong and just clear the result target
{
@@ -7488,17 +7191,17 @@ void LLPipeline::renderFinalize()
mGlow[1].clear();
mGlow[1].flush();
}
+}
+void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) {
{
- llassert(!gCubeSnapshot);
+ 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)
{
@@ -7506,38 +7209,27 @@ void LLPipeline::renderFinalize()
// 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());
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
if (channel > -1)
{
- mPostMap.bindTexture(0, channel);
+ src->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
}
- channel = shader->enableTexture(LLShaderMgr::DEFERRED_EMISSIVE, mGlow[1].getUsage());
- if (channel > -1)
{
- mGlow[1].bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+ LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
}
- {
- 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->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
shader->unbind();
mRT->fxaaBuffer.flush();
+ dst->bindTarget();
shader = &gFXAAProgram;
shader->bind();
@@ -7547,12 +7239,6 @@ void LLPipeline::renderFinalize()
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);
@@ -7562,45 +7248,323 @@ void LLPipeline::renderFinalize()
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);
+ {
+ 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);
+ }
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- }
-
shader->unbind();
+ dst->flush();
}
- else
+ else {
+ copyRenderTarget(src, dst);
+ }
+ }
+}
+
+void LLPipeline::copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst) {
+
+ LL_PROFILE_GPU_ZONE("copyRenderTarget");
+ dst->bindTarget();
+
+ gDeferredPostNoDoFProgram.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);
+ }
+
+ gDeferredPostNoDoFProgram.unbind();
+
+ dst->flush();
+}
+
+void LLPipeline::combineGlow(LLRenderTarget* src, LLRenderTarget* dst) {
+ // 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::renderDoF(LLRenderTarget* src, LLRenderTarget* dst) {
+ {
+ bool dof_enabled =
+ (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
+ RenderDepthOfField &&
+ !gCubeSnapshot;
+
+ gViewerWindow->setup3DViewport();
+
+ if (dof_enabled)
{
- // at this point we should pointed at the backbuffer (or a snapshot render target)
- llassert(gSnapshot || LLRenderTarget::sCurFBO == 0);
+ LL_PROFILE_GPU_ZONE("dof");
+ LLGLDisable blend(GL_BLEND);
+
+ // depth of field focal plane calculations
+ static F32 current_distance = 16.f;
+ static F32 start_distance = 16.f;
+ static F32 transition_time = 1.f;
- LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ LLVector3 focus_point;
- shader->bind();
+ LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject();
+ if (obj && obj->mDrawable && obj->isSelected())
+ { // focus on selected media object
+ S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace();
+ if (obj && obj->mDrawable)
+ {
+ LLFace* face = obj->mDrawable->getFace(face_idx);
+ if (face)
+ {
+ focus_point = face->getPositionAgent();
+ }
+ }
+ }
- shader->bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &mPostMap);
- shader->bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
- shader->bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]);
+ if (focus_point.isExactlyZero())
+ {
+ if (LLViewerJoystick::getInstance()->getOverrideCamera())
+ { // focus on point under cursor
+ focus_point.set(gDebugRaycastIntersection.getF32ptr());
+ }
+ else if (gAgentCamera.cameraMouselook())
+ { // focus on point under mouselook crosshairs
+ LLVector4a result;
+ result.clear();
- 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]);
+ gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, NULL, &result);
- mScreenTriangleVB->setBuffer();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ focus_point.set(result.getF32ptr());
+ }
+ else
+ {
+ // focus on alt-zoom target
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal());
+ }
+ }
+ }
- gGL.flush();
- shader->unbind();
+ LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
+ F32 target_distance = 16.f;
+ if (!focus_point.isExactlyZero())
+ {
+ target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye);
+ }
+
+ if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f)
+ { // large shift happened, interpolate smoothly to new target distance
+ transition_time = 0.f;
+ start_distance = current_distance;
+ }
+ else if (transition_time < 1.f)
+ { // currently in a transition, continue interpolating
+ transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value();
+ transition_time = llmin(transition_time, 1.f);
+
+ F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f;
+ current_distance = start_distance + (target_distance - start_distance) * t;
+ }
+ else
+ { // small or no change, just snap to target distance
+ current_distance = target_distance;
+ }
+
+ // convert to mm
+ F32 subject_distance = current_distance * 1000.f;
+ F32 fnumber = CameraFNumber;
+ F32 default_focal_length = CameraFocalLength;
+
+ F32 fov = LLViewerCamera::getInstance()->getView();
+
+ const F32 default_fov = CameraFieldOfView * F_PI / 180.f;
+
+ // F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight();
+
+ F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f);
+
+ F32 focal_length = dv / (2 * tanf(fov / 2.f));
+
+ // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle);
+
+ // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f))
+ // where N = fnumber
+ // s2 = dot distance
+ // s1 = subject distance
+ // f = focal length
+ //
+
+ F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length));
+ blur_constant /= 1000.f; // convert to meters for shader
+ F32 magnification = focal_length / (subject_distance - focal_length);
+
+ { // build diffuse+bloom+CoF
+ mRT->deferredLight.bindTarget();
+
+ gDeferredCoFProgram.bind();
+
+ gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT);
+ gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
+
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff);
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff);
+ gDeferredCoFProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight());
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f);
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant);
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle));
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification);
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ gDeferredCoFProgram.unbind();
+ mRT->deferredLight.flush();
+ }
+
+ U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale);
+ U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale);
+
+ { // perform DoF sampling at half-res (preserve alpha channel)
+ src->bindTarget();
+ glViewport(0, 0, dof_width, dof_height);
+ gGL.setColorMask(true, false);
+
+ gDeferredPostProgram.bind();
+ gDeferredPostProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &mRT->deferredLight, LLTexUnit::TFO_POINT);
+
+ gDeferredPostProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight());
+ gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+ gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ gDeferredPostProgram.unbind();
+
+ src->flush();
+ gGL.setColorMask(true, true);
+ }
+
+ { // combine result based on alpha
+
+ dst->bindTarget();
+ glViewport(0, 0, dst->getWidth(), dst->getHeight());
+
+ gDeferredDoFCombineProgram.bind();
+ gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT);
+ gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_LIGHT, &mRT->deferredLight, LLTexUnit::TFO_POINT);
+
+ gDeferredDoFCombineProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight());
+ gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+ gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+ gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)src->getWidth());
+ gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)src->getHeight());
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ gDeferredDoFCombineProgram.unbind();
+
+ dst->flush();
+ }
+ }
+ else
+ {
+ copyRenderTarget(src, dst);
}
}
+}
+
+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)
+ {
+ copyScreenSpaceReflections(&mRT->screen, &mSceneMap);
+
+ generateLuminance(&mRT->screen, &mLuminanceMap);
+
+ generateExposure(&mLuminanceMap, &mExposureMap);
+
+ gammaCorrect(&mRT->screen, &mPostMap);
+
+ LLVertexBuffer::unbind();
+ }
+
+ generateGlow(&mPostMap);
+
+ combineGlow(&mPostMap, &mRT->screen);
+
+ renderDoF(&mRT->screen, &mPostMap);
+
+ applyFXAA(&mPostMap, &mRT->screen);
+
+
+ // Present the screen target.
+
+ gDeferredPostNoDoFProgram.bind();
+
+ // Whatever is last in the above post processing chain should _always_ be rendered directly here. If not, expect problems.
+ S32 channel = gDeferredPostNoDoFProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
+ if (channel > -1)
+ {
+ mRT->screen.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+ }
+
+ {
+ LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+
+ gDeferredPostNoDoFProgram.unbind();
gGL.setSceneBlendType(LLRender::BT_ALPHA);
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index a231084e5c..ed9e2dc452 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -135,6 +135,15 @@ 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 generateGlow(LLRenderTarget* src);
+ void applyFXAA(LLRenderTarget* src, LLRenderTarget* dst);
+ void renderDoF(LLRenderTarget* src, LLRenderTarget* dst);
+ void copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst);
+ void combineGlow(LLRenderTarget* src, LLRenderTarget* dst);
void renderPostProcess();
LLRenderTarget* screenTarget();