summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorJonathan "Geenz" Goodman <geenz@geenzo.com>2023-01-02 05:38:29 -0800
committerJonathan "Geenz" Goodman <geenz@geenzo.com>2023-01-02 05:38:29 -0800
commit003e34190f314cd159f8ec227ef32c2400e90f48 (patch)
tree08b7cd8b9b007251382a2c2f94374eec2920bdf0 /indra/newview
parent40799b97c188bb3c0a4b2d00a35bcc41be461f08 (diff)
Refactor post processing a smidge
Fixes SL-18484.
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl4
-rw-r--r--indra/newview/llviewerdisplay.cpp7
-rw-r--r--indra/newview/pipeline.cpp955
-rw-r--r--indra/newview/pipeline.h2
4 files changed, 524 insertions, 444 deletions
diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl
index e08284f762..71fa095505 100644
--- a/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl
@@ -35,7 +35,7 @@ VARYING vec2 vary_texcoord1;
void main()
{
gl_Position = vec4(position.xyz, 1.0);
- vary_texcoord0 = texcoord0;
- vary_texcoord1 = texcoord1;
+ vary_texcoord0 = position.xy * 0.5 + 0.5;
+ vary_texcoord1 = vary_texcoord0;
}
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 1b2f07515a..58b1716caa 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1348,9 +1348,12 @@ void render_ui(F32 zoom_factor, int subfield)
}
{
+ // Render our post process prior to the HUD, UI, etc.
+ gPipeline.renderPostProcess();
+
// draw hud and 3D ui elements into screen render target so they'll be able to use
// the depth buffer (avoids extra copy of depth buffer per frame)
- gPipeline.mRT->screen.bindTarget();
+ gPipeline.screenTarget()->bindTarget();
// SL-15709
// NOTE: Tracy only allows one ZoneScoped per function.
// Solutions are:
@@ -1384,7 +1387,7 @@ void render_ui(F32 zoom_factor, int subfield)
}
}
- gPipeline.mRT->screen.flush();
+ gPipeline.screenTarget()->flush();
// apply gamma correction and post effects before rendering 2D UI
gPipeline.renderFinalize();
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 744d21b2c9..4edc092271 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -880,7 +880,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0)
{ //only need mRT->deferredLight for shadows OR ssao OR dof OR fxaa
- if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE)) return false;
+ if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA16, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE)) return false;
}
else
{
@@ -7530,500 +7530,541 @@ void LLPipeline::bindScreenToTexture()
static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom");
-void LLPipeline::renderFinalize()
+void LLPipeline::renderPostProcess()
{
- LLVertexBuffer::unbind();
- LLGLState::checkStates();
- LLGLState::checkTextureChannels();
+ LLVertexBuffer::unbind();
+ LLGLState::checkStates();
+ LLGLState::checkTextureChannels();
- assertInitialized();
+ assertInitialized();
- LLVector2 tc1(0, 0);
- LLVector2 tc2((F32) mRT->screen.getWidth() * 2, (F32) mRT->screen.getHeight() * 2);
+ LLVector2 tc1(0, 0);
+ LLVector2 tc2((F32)mRT->screen.getWidth() * 2, (F32)mRT->screen.getHeight() * 2);
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
- LL_PROFILE_GPU_ZONE("renderFinalize");
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
+ LL_PROFILE_GPU_ZONE("renderPostProcess");
- gGL.color4f(1, 1, 1, 1);
- LLGLDepthTest depth(GL_FALSE);
- LLGLDisable blend(GL_BLEND);
- LLGLDisable cull(GL_CULL_FACE);
+ gGL.color4f(1, 1, 1, 1);
+ LLGLDepthTest depth(GL_FALSE);
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable cull(GL_CULL_FACE);
- enableLightsFullbright();
+ enableLightsFullbright();
- LLGLDisable test(GL_ALPHA_TEST);
+ LLGLDisable test(GL_ALPHA_TEST);
- gGL.setColorMask(true, true);
- glClearColor(0, 0, 0, 0);
+ gGL.setColorMask(true, true);
+ glClearColor(0, 0, 0, 0);
- if (!gCubeSnapshot)
- {
- LLRenderTarget* screen_target = &mRT->screen;
- screen_target->bindTarget();
+ if (sRenderGlow)
+ {
+ LL_PROFILE_GPU_ZONE("glow");
+ mGlow[2].bindTarget();
+ mGlow[2].clear();
- if (RenderScreenSpaceReflections)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - screen space reflections");
- LL_PROFILE_GPU_ZONE("screen space reflections");
+ gGlowExtractProgram.bind();
+ F32 minLum = llmax((F32)RenderGlowMinLuminance, 0.0f);
+ F32 maxAlpha = RenderGlowMaxExtractAlpha;
+ F32 warmthAmount = RenderGlowWarmthAmount;
+ LLVector3 lumWeights = RenderGlowLumWeights;
+ LLVector3 warmthWeights = RenderGlowWarmthWeights;
- bindDeferredShader(gPostScreenSpaceReflectionProgram, NULL);
- mScreenTriangleVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum);
+ 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);
- set_camera_projection_matrix(gPostScreenSpaceReflectionProgram);
+ {
+ LLGLEnable blend_on(GL_BLEND);
+ LLGLEnable test(GL_ALPHA_TEST);
- // We need linear depth.
- static LLStaticHashedString zfar("zFar");
- static LLStaticHashedString znear("zNear");
- float nearClip = LLViewerCamera::getInstance()->getNear();
- float farClip = LLViewerCamera::getInstance()->getFar();
- gPostScreenSpaceReflectionProgram.uniform1f(zfar, farClip);
- gPostScreenSpaceReflectionProgram.uniform1f(znear, nearClip);
+ gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
- S32 channel = gPostScreenSpaceReflectionProgram.enableTexture(LLShaderMgr::DIFFUSE_MAP, screen_target->getUsage());
- if (channel > -1)
- {
- screen_target->bindTexture(0, channel, LLTexUnit::TFO_POINT);
- }
+ mRT->screen.bindTexture(0, 0, LLTexUnit::TFO_POINT);
- {
- LLGLDisable blend(GL_BLEND);
- LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+ gGL.color4f(1, 1, 1, 1);
+ gPipeline.enableLightsFullbright();
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+ gGL.vertex2f(-1, -1);
- stop_glerror();
- mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- stop_glerror();
- }
+ gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+ gGL.vertex2f(-1, 3);
- unbindDeferredShader(gPostScreenSpaceReflectionProgram);
- }
+ gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+ gGL.vertex2f(3, -1);
- // gamma correct lighting
- {
- LL_PROFILE_GPU_ZONE("gamma correct");
+ gGL.end();
- LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+ gGL.getTexUnit(0)->unbind(mRT->screen.getUsage());
- LLVector2 tc1(0, 0);
- LLVector2 tc2((F32)screen_target->getWidth() * 2, (F32)screen_target->getHeight() * 2);
+ mGlow[2].flush();
- // Apply gamma correction to the frame here.
- gDeferredPostGammaCorrectProgram.bind();
- // mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- S32 channel = 0;
- channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screen_target->getUsage());
- if (channel > -1)
- {
- screen_target->bindTexture(0, channel, LLTexUnit::TFO_POINT);
- }
+ tc1.setVec(0, 0);
+ tc2.setVec(2, 2);
+ }
- gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screen_target->getWidth(), screen_target->getHeight());
+ // power of two between 1 and 1024
+ U32 glowResPow = RenderGlowResolutionPow;
+ const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow));
- F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+ 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;
- gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
+ gGlowProgram.bind();
+ gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength);
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
- gGL.vertex2f(-1, -1);
+ for (S32 i = 0; i < kernel; i++)
+ {
+ mGlow[i % 2].bindTarget();
+ mGlow[i % 2].clear();
- gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
- gGL.vertex2f(-1, 3);
+ if (i == 0)
+ {
+ gGL.getTexUnit(0)->bind(&mGlow[2]);
+ }
+ else
+ {
+ gGL.getTexUnit(0)->bind(&mGlow[(i - 1) % 2]);
+ }
- gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
- gGL.vertex2f(3, -1);
+ if (i % 2 == 0)
+ {
+ gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0);
+ }
+ else
+ {
+ gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta);
+ }
- gGL.end();
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+ gGL.vertex2f(-1, -1);
- gGL.getTexUnit(channel)->unbind(screen_target->getUsage());
- gDeferredPostGammaCorrectProgram.unbind();
- }
+ gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+ gGL.vertex2f(-1, 3);
- screen_target->flush();
+ gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+ gGL.vertex2f(3, -1);
- LLVertexBuffer::unbind();
- }
+ gGL.end();
- if (sRenderGlow)
- {
- LL_PROFILE_GPU_ZONE("glow");
- mGlow[2].bindTarget();
- mGlow[2].clear();
-
- gGlowExtractProgram.bind();
- F32 minLum = llmax((F32) RenderGlowMinLuminance, 0.0f);
- F32 maxAlpha = RenderGlowMaxExtractAlpha;
- F32 warmthAmount = RenderGlowWarmthAmount;
- LLVector3 lumWeights = RenderGlowLumWeights;
- LLVector3 warmthWeights = RenderGlowWarmthWeights;
-
- gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum);
- 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);
+ mGlow[i % 2].flush();
+ }
- gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
+ gGlowProgram.unbind();
+ }
+ else // !sRenderGlow, skip the glow ping-pong and just clear the result target
+ {
+ mGlow[1].bindTarget();
+ mGlow[1].clear();
+ mGlow[1].flush();
+ }
- mRT->screen.bindTexture(0, 0, LLTexUnit::TFO_POINT);
+ 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]);
- gGL.color4f(1, 1, 1, 1);
- gPipeline.enableLightsFullbright();
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
- gGL.vertex2f(-1, -1);
+ tc2.setVec((F32)mRT->screen.getWidth(), (F32)mRT->screen.getHeight());
- gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
- gGL.vertex2f(-1, 3);
+ gGL.flush();
- gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
- gGL.vertex2f(3, -1);
+ LLVertexBuffer::unbind();
- gGL.end();
+ if (LLPipeline::sRenderDeferred)
+ {
+ bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
+ (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
+ RenderDepthOfField &&
+ !gCubeSnapshot;
- gGL.getTexUnit(0)->unbind(mRT->screen.getUsage());
+ bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot;
- mGlow[2].flush();
+ gViewerWindow->setup3DViewport();
- tc1.setVec(0, 0);
- tc2.setVec(2, 2);
- }
+ if (dof_enabled)
+ {
+ LL_PROFILE_GPU_ZONE("dof");
+ LLGLSLShader* shader = &gDeferredPostProgram;
+ LLGLDisable blend(GL_BLEND);
- // power of two between 1 and 1024
- U32 glowResPow = RenderGlowResolutionPow;
- const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow));
+ // depth of field focal plane calculations
+ static F32 current_distance = 16.f;
+ static F32 start_distance = 16.f;
+ static F32 transition_time = 1.f;
- 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;
+ LLVector3 focus_point;
- gGlowProgram.bind();
- gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength);
+ 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();
+ }
+ }
+ }
- for (S32 i = 0; i < kernel; i++)
- {
- mGlow[i % 2].bindTarget();
- mGlow[i % 2].clear();
+ 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();
- if (i == 0)
- {
- gGL.getTexUnit(0)->bind(&mGlow[2]);
- }
- else
- {
- gGL.getTexUnit(0)->bind(&mGlow[(i - 1) % 2]);
- }
+ gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, NULL, &result);
- if (i % 2 == 0)
- {
- gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0);
- }
- else
- {
- gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta);
- }
+ 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.begin(LLRender::TRIANGLE_STRIP);
- gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
- gGL.vertex2f(-1, -1);
+ LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
+ F32 target_distance = 16.f;
+ if (!focus_point.isExactlyZero())
+ {
+ target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye);
+ }
- gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
- gGL.vertex2f(-1, 3);
+ 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);
- gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
- gGL.vertex2f(3, -1);
+ 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;
+ }
- gGL.end();
+ // convert to mm
+ F32 subject_distance = current_distance * 1000.f;
+ F32 fnumber = CameraFNumber;
+ F32 default_focal_length = CameraFocalLength;
- mGlow[i % 2].flush();
- }
+ F32 fov = LLViewerCamera::getInstance()->getView();
- gGlowProgram.unbind();
- }
- else // !sRenderGlow, skip the glow ping-pong and just clear the result target
- {
- mGlow[1].bindTarget();
- mGlow[1].clear();
- mGlow[1].flush();
- }
+ const F32 default_fov = CameraFieldOfView * F_PI / 180.f;
- 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 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight();
- tc2.setVec((F32) mRT->screen.getWidth(), (F32) mRT->screen.getHeight());
+ F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f);
- gGL.flush();
+ F32 focal_length = dv / (2 * tanf(fov / 2.f));
- LLVertexBuffer::unbind();
+ // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle);
- if (LLPipeline::sRenderDeferred)
- {
- bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
- (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
- RenderDepthOfField &&
- !gCubeSnapshot;
+ // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f))
+ // where N = fnumber
+ // s2 = dot distance
+ // s1 = subject distance
+ // f = focal length
+ //
- bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot;
+ 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);
- gViewerWindow->setup3DViewport();
+ { // build diffuse+bloom+CoF
+ mRT->deferredLight.bindTarget();
+ shader = &gDeferredCoFProgram;
- if (dof_enabled)
- {
- LL_PROFILE_GPU_ZONE("dof");
- LLGLSLShader *shader = &gDeferredPostProgram;
- LLGLDisable blend(GL_BLEND);
+ bindDeferredShader(*shader);
- // depth of field focal plane calculations
- static F32 current_distance = 16.f;
- static F32 start_distance = 16.f;
- static F32 transition_time = 1.f;
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
+ if (channel > -1)
+ {
+ mRT->screen.bindTexture(0, channel);
+ }
- LLVector3 focus_point;
+ 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);
- 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();
- }
- }
- }
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+ gGL.vertex2f(-1, -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();
+ gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+ gGL.vertex2f(-1, 3);
- gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, NULL, &result);
+ gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+ gGL.vertex2f(3, -1);
- 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.end();
- LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
- F32 target_distance = 16.f;
- if (!focus_point.isExactlyZero())
- {
- target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye);
- }
+ unbindDeferredShader(*shader);
+ mRT->deferredLight.flush();
+ }
- 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);
+ U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale);
+ U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale);
- 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;
- }
+ { // perform DoF sampling at half-res (preserve alpha channel)
+ mRT->screen.bindTarget();
+ glViewport(0, 0, dof_width, dof_height);
+ gGL.setColorMask(true, false);
- // convert to mm
- F32 subject_distance = current_distance * 1000.f;
- F32 fnumber = CameraFNumber;
- F32 default_focal_length = CameraFocalLength;
+ shader = &gDeferredPostProgram;
+ bindDeferredShader(*shader);
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());
+ if (channel > -1)
+ {
+ mRT->deferredLight.bindTexture(0, channel);
+ }
- F32 fov = LLViewerCamera::getInstance()->getView();
+ shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+ shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
- const F32 default_fov = CameraFieldOfView * F_PI / 180.f;
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+ gGL.vertex2f(-1, -1);
- // F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight();
+ gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+ gGL.vertex2f(-1, 3);
- F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f);
+ gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+ gGL.vertex2f(3, -1);
- F32 focal_length = dv / (2 * tanf(fov / 2.f));
+ gGL.end();
- // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle);
+ unbindDeferredShader(*shader);
+ mRT->screen.flush();
+ gGL.setColorMask(true, true);
+ }
- // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f))
- // where N = fnumber
- // s2 = dot distance
- // s1 = subject distance
- // f = focal length
- //
+ { // 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]);
+ }
- 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);
+ shader = &gDeferredDoFCombineProgram;
+ bindDeferredShader(*shader);
- { // build diffuse+bloom+CoF
- mRT->deferredLight.bindTarget();
- shader = &gDeferredCoFProgram;
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
+ if (channel > -1)
+ {
+ mRT->screen.bindTexture(0, channel);
+ }
- bindDeferredShader(*shader);
+ 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());
- 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);
- 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.texCoord2f(tc1.mV[0], tc2.mV[1]);
+ gGL.vertex2f(-1, 3);
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
- gGL.vertex2f(-1, -1);
+ gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+ gGL.vertex2f(3, -1);
- gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
- gGL.vertex2f(-1, 3);
+ gGL.end();
- gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
- gGL.vertex2f(3, -1);
+ unbindDeferredShader(*shader);
- gGL.end();
+ if (multisample)
+ {
+ mRT->deferredLight.flush();
+ }
+ }
+ }
+ else
+ {
+ LL_PROFILE_GPU_ZONE("no dof");
+ if (multisample)
+ {
+ mRT->deferredLight.bindTarget();
+ }
+ LLGLSLShader* shader = &gDeferredPostNoDoFProgram;
- unbindDeferredShader(*shader);
- mRT->deferredLight.flush();
- }
+ bindDeferredShader(*shader);
- U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale);
- U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale);
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
+ if (channel > -1)
+ {
+ mRT->screen.bindTexture(0, channel);
+ }
- { // perform DoF sampling at half-res (preserve alpha channel)
- mRT->screen.bindTarget();
- glViewport(0, 0, dof_width, dof_height);
- gGL.setColorMask(true, false);
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+ gGL.vertex2f(-1, -1);
- shader = &gDeferredPostProgram;
- bindDeferredShader(*shader);
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());
- if (channel > -1)
- {
- mRT->deferredLight.bindTexture(0, channel);
- }
+ gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+ gGL.vertex2f(-1, 3);
- shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
- shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+ gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+ gGL.vertex2f(3, -1);
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
- gGL.vertex2f(-1, -1);
+ gGL.end();
- gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
- gGL.vertex2f(-1, 3);
+ unbindDeferredShader(*shader);
- gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
- gGL.vertex2f(3, -1);
+ if (multisample)
+ {
+ mRT->deferredLight.flush();
+ }
+ }
+ }
+}
- gGL.end();
+LLRenderTarget* LLPipeline::screenTarget() {
- unbindDeferredShader(*shader);
- mRT->screen.flush();
- gGL.setColorMask(true, true);
- }
+ bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
+ (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
+ RenderDepthOfField &&
+ !gCubeSnapshot;
- { // 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]);
- }
+ bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot;
- shader = &gDeferredDoFCombineProgram;
- bindDeferredShader(*shader);
+ if (multisample || dof_enabled)
+ return &mRT->deferredLight;
+
+ return &mRT->screen;
+}
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
- if (channel > -1)
- {
- mRT->screen.bindTexture(0, channel);
- }
+void LLPipeline::renderFinalize()
+{
+ LLVertexBuffer::unbind();
+ LLGLState::checkStates();
+ LLGLState::checkTextureChannels();
+
+ assertInitialized();
+
+ LLVector2 tc1(0, 0);
+ LLVector2 tc2((F32) mRT->screen.getWidth() * 2, (F32) mRT->screen.getHeight() * 2);
- 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());
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
+ LL_PROFILE_GPU_ZONE("renderFinalize");
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
- gGL.vertex2f(-1, -1);
+ gGL.color4f(1, 1, 1, 1);
+ LLGLDepthTest depth(GL_FALSE);
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable cull(GL_CULL_FACE);
- gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
- gGL.vertex2f(-1, 3);
+ enableLightsFullbright();
- gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
- gGL.vertex2f(3, -1);
+ LLGLDisable test(GL_ALPHA_TEST);
- gGL.end();
+ gGL.setColorMask(true, true);
+ glClearColor(0, 0, 0, 0);
- unbindDeferredShader(*shader);
+ if (!gCubeSnapshot)
+ {
+ screenTarget()->bindTarget();
- if (multisample)
- {
- mRT->deferredLight.flush();
- }
- }
- }
- else
+ if (RenderScreenSpaceReflections)
{
- LL_PROFILE_GPU_ZONE("no dof");
- if (multisample)
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - screen space reflections");
+ LL_PROFILE_GPU_ZONE("screen space reflections");
+
+ bindDeferredShader(gPostScreenSpaceReflectionProgram, NULL);
+ mScreenTriangleVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ set_camera_projection_matrix(gPostScreenSpaceReflectionProgram);
+
+ // We need linear depth.
+ static LLStaticHashedString zfar("zFar");
+ static LLStaticHashedString znear("zNear");
+ float nearClip = LLViewerCamera::getInstance()->getNear();
+ float farClip = LLViewerCamera::getInstance()->getFar();
+ gPostScreenSpaceReflectionProgram.uniform1f(zfar, farClip);
+ gPostScreenSpaceReflectionProgram.uniform1f(znear, nearClip);
+
+ S32 channel = gPostScreenSpaceReflectionProgram.enableTexture(LLShaderMgr::DIFFUSE_MAP, screenTarget()->getUsage());
+ if (channel > -1)
{
- mRT->deferredLight.bindTarget();
+ screenTarget()->bindTexture(0, channel, LLTexUnit::TFO_POINT);
}
- LLGLSLShader *shader = &gDeferredPostNoDoFProgram;
- bindDeferredShader(*shader);
+ {
+ LLGLDisable blend(GL_BLEND);
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+
+ stop_glerror();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ stop_glerror();
+ }
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage());
+ unbindDeferredShader(gPostScreenSpaceReflectionProgram);
+ }
+
+ // gamma correct lighting
+ {
+ LL_PROFILE_GPU_ZONE("gamma correct");
+
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+
+ LLVector2 tc1(0, 0);
+ LLVector2 tc2((F32)screenTarget()->getWidth() * 2, (F32)screenTarget()->getHeight() * 2);
+
+ // Apply gamma correction to the frame here.
+ gDeferredPostGammaCorrectProgram.bind();
+ // mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ S32 channel = 0;
+ channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screenTarget()->getUsage());
if (channel > -1)
{
- mRT->screen.bindTexture(0, channel);
+ screenTarget()->bindTexture(0, channel, LLTexUnit::TFO_POINT);
}
+ gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screenTarget()->getWidth(), screenTarget()->getHeight());
+
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+
+ gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
+
gGL.begin(LLRender::TRIANGLE_STRIP);
gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
gGL.vertex2f(-1, -1);
@@ -8036,82 +8077,116 @@ void LLPipeline::renderFinalize()
gGL.end();
- unbindDeferredShader(*shader);
-
- if (multisample)
- {
- mRT->deferredLight.flush();
- }
+ gGL.getTexUnit(channel)->unbind(screenTarget()->getUsage());
+ gDeferredPostGammaCorrectProgram.unbind();
}
- if (multisample)
- {
- LL_PROFILE_GPU_ZONE("aa");
- // bake out texture2D with RGBL for FXAA shader
- mRT->fxaaBuffer.bindTarget();
+ screenTarget()->flush();
- S32 width = mRT->screen.getWidth();
- S32 height = mRT->screen.getHeight();
- glViewport(0, 0, width, height);
+ LLVertexBuffer::unbind();
+ }
- LLGLSLShader *shader = &gGlowCombineFXAAProgram;
+ if (RenderDeferred)
+ {
+ bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot;
+ LLGLSLShader* shader = &gGlowCombineProgram;
- shader->bind();
- shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height);
+ S32 width = mRT->screen.getWidth();
+ S32 height = mRT->screen.getHeight();
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());
- if (channel > -1)
- {
- mRT->deferredLight.bindTexture(0, channel);
- }
+ S32 channel = -1;
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.vertex2f(-1, -1);
- gGL.vertex2f(-1, 3);
- gGL.vertex2f(3, -1);
- gGL.end();
+ // Present everything.
+ if (multisample)
+ {
+ LL_PROFILE_GPU_ZONE("aa");
+ // bake out texture2D with RGBL for FXAA shader
+ mRT->fxaaBuffer.bindTarget();
- gGL.flush();
+ glViewport(0, 0, width, height);
- shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());
- shader->unbind();
+ shader = &gGlowCombineFXAAProgram;
- mRT->fxaaBuffer.flush();
+ shader->bind();
+ shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height);
- shader = &gFXAAProgram;
- shader->bind();
+ channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());
+ if (channel > -1)
+ {
+ mRT->deferredLight.bindTexture(0, channel);
+ }
- channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mRT->fxaaBuffer.getUsage());
- if (channel > -1)
- {
- mRT->fxaaBuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
- }
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.vertex2f(-1, -1);
+ gGL.vertex2f(-1, 3);
+ gGL.vertex2f(3, -1);
+ gGL.end();
- 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);
+ gGL.flush();
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.vertex2f(-1, -1);
- gGL.vertex2f(-1, 3);
- gGL.vertex2f(3, -1);
- gGL.end();
+ shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());
+ shader->unbind();
- gGL.flush();
- 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);
+
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.vertex2f(-1, -1);
+ gGL.vertex2f(-1, 3);
+ gGL.vertex2f(3, -1);
+ gGL.end();
+
+ gGL.flush();
+ shader->unbind();
+ }
+ else
+ {
+ shader->bind();
+
+
+ gGL.getTexUnit(0)->bind(&mGlow[1]);
+ gGL.getTexUnit(1)->bind(screenTarget());
+
+ 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]);
+
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.vertex2f(-1, -1);
+ gGL.vertex2f(-1, 3);
+ gGL.vertex2f(3, -1);
+ gGL.end();
+
+ gGL.flush();
+ shader->unbind();
+ }
+ }
+
#if 0 // DEPRECATED
else // not deferred
{
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 0097b863ab..bac68cfff0 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -137,6 +137,8 @@ public:
void generateImpostor(LLVOAvatar* avatar, bool preview_avatar = false);
void bindScreenToTexture();
void renderFinalize();
+ void renderPostProcess();
+ LLRenderTarget* screenTarget();
void init();
void cleanup();