Move glow extract to be after tonemapping.

SL-19513
master
Jonathan "Geenz" Goodman 2023-03-31 10:54:19 -07:00
parent b130831106
commit b44ad50f75
8 changed files with 158 additions and 159 deletions

View File

@ -32,6 +32,7 @@
#include "llfile.h"
#include "llrender.h"
#include "llvertexbuffer.h"
#include "llrendertarget.h"
#if LL_DARWIN
#include "OpenGL/OpenGL.h"
@ -1084,6 +1085,39 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture* texture, LLTexUnit::eTextu
return uniform;
}
S32 LLGLSLShader::bindTexture(S32 uniform, LLRenderTarget* texture, bool depth, LLTexUnit::eTextureFilterOptions mode)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
return -1;
}
uniform = getTextureChannel(uniform);
if (uniform > -1)
{
gGL.getTexUnit(uniform)->bindManual(texture->getUsage(), texture->getTexture(0));
gGL.getTexUnit(uniform)->setTextureFilteringOption(mode);
}
return uniform;
}
S32 LLGLSLShader::bindTexture(const std::string& uniform, LLRenderTarget* texture, bool depth, LLTexUnit::eTextureFilterOptions mode)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
S32 channel = 0;
channel = getUniformLocation(uniform);
return bindTexture(channel, texture, depth, mode);
}
S32 LLGLSLShader::unbindTexture(const std::string& uniform, LLTexUnit::eTextureType mode)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;

View File

@ -243,6 +243,8 @@ public:
// You can reuse the return value to unbind a texture when required.
S32 bindTexture(const std::string& uniform, LLTexture* texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
S32 bindTexture(S32 uniform, LLTexture* texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
S32 bindTexture(const std::string& uniform, LLRenderTarget* texture, bool depth = false, LLTexUnit::eTextureFilterOptions mode = LLTexUnit::TFO_BILINEAR);
S32 bindTexture(S32 uniform, LLRenderTarget* texture, bool depth = false, LLTexUnit::eTextureFilterOptions mode = LLTexUnit::TFO_BILINEAR);
S32 unbindTexture(const std::string& uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
S32 unbindTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);

View File

@ -34,7 +34,6 @@ out vec4 frag_color;
#endif
uniform sampler2D diffuseRect;
uniform sampler2D emissiveRect;
uniform sampler2D exposureMap;
uniform vec2 screen_res;
@ -184,7 +183,7 @@ vec3 legacyGamma(vec3 color)
void main()
{
//this is the one of the rare spots where diffuseRect contains linear color values (not sRGB)
vec4 diff = texture2D(diffuseRect, vary_fragcoord) + texture2D(emissiveRect, vary_fragcoord);
vec4 diff = texture2D(diffuseRect, vary_fragcoord);
diff.rgb = toneMap(diff.rgb);
diff.rgb = legacyGamma(diff.rgb);

View File

@ -26,7 +26,6 @@
uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
ATTRIBUTE vec2 texcoord0;
VARYING vec2 vary_texcoord0;

View File

@ -26,7 +26,6 @@
uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
ATTRIBUTE vec2 texcoord0;
uniform vec2 glowDelta;
@ -39,12 +38,15 @@ void main()
{
gl_Position = vec4(position, 1.0);
vary_texcoord0.xy = texcoord0 + glowDelta*(-3.5);
vary_texcoord1.xy = texcoord0 + glowDelta*(-2.5);
vary_texcoord2.xy = texcoord0 + glowDelta*(-1.5);
vary_texcoord3.xy = texcoord0 + glowDelta*(-0.5);
vary_texcoord0.zw = texcoord0 + glowDelta*(0.5);
vary_texcoord1.zw = texcoord0 + glowDelta*(1.5);
vary_texcoord2.zw = texcoord0 + glowDelta*(2.5);
vary_texcoord3.zw = texcoord0 + glowDelta*(3.5);
vec2 texcoord = position.xy * 0.5 + 0.5;
vary_texcoord0.xy = texcoord + glowDelta*(-3.5);
vary_texcoord1.xy = texcoord + glowDelta*(-2.5);
vary_texcoord2.xy = texcoord + glowDelta*(-1.5);
vary_texcoord3.xy = texcoord + glowDelta*(-0.5);
vary_texcoord0.zw = texcoord + glowDelta*(0.5);
vary_texcoord1.zw = texcoord + glowDelta*(1.5);
vary_texcoord2.zw = texcoord + glowDelta*(2.5);
vary_texcoord3.zw = texcoord + glowDelta*(3.5);
}

View File

@ -31,12 +31,13 @@ out vec4 frag_color;
uniform sampler2D diffuseRect;
uniform sampler2D depthMap;
uniform sampler2D emissiveRect;
in vec2 tc;
void main()
{
frag_color = texture2D(diffuseRect, tc);
frag_color = texture2D(diffuseRect, tc) + texture2D(emissiveRect, tc);
gl_FragDepth = texture(depthMap, tc).r;
}

View File

@ -30,6 +30,7 @@
out vec4 frag_color;
uniform sampler2D diffuseRect;
uniform sampler2D emissiveRect;
uniform vec2 screen_res;
@ -37,7 +38,7 @@ in vec2 vary_tc;
void main()
{
vec3 col = texture(diffuseRect, vary_tc).rgb;
vec3 col = texture(diffuseRect, vary_tc).rgb + texture(emissiveRect, vary_tc).rgb;
frag_color = vec4(col.rgb, dot(col.rgb, vec3(0.299, 0.587, 0.144)));
}

View File

@ -148,7 +148,6 @@ LLColor4 LLPipeline::PreviewSpecular2;
LLVector3 LLPipeline::PreviewDirection0;
LLVector3 LLPipeline::PreviewDirection1;
LLVector3 LLPipeline::PreviewDirection2;
F32 LLPipeline::RenderGlowMinLuminance;
F32 LLPipeline::RenderGlowMaxExtractAlpha;
F32 LLPipeline::RenderGlowWarmthAmount;
LLVector3 LLPipeline::RenderGlowLumWeights;
@ -502,7 +501,6 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("PreviewDirection0");
connectRefreshCachedSettingsSafe("PreviewDirection1");
connectRefreshCachedSettingsSafe("PreviewDirection2");
connectRefreshCachedSettingsSafe("RenderGlowMinLuminance");
connectRefreshCachedSettingsSafe("RenderGlowMaxExtractAlpha");
connectRefreshCachedSettingsSafe("RenderGlowWarmthAmount");
connectRefreshCachedSettingsSafe("RenderGlowLumWeights");
@ -986,7 +984,6 @@ void LLPipeline::refreshCachedSettings()
PreviewDirection0 = gSavedSettings.getVector3("PreviewDirection0");
PreviewDirection1 = gSavedSettings.getVector3("PreviewDirection1");
PreviewDirection2 = gSavedSettings.getVector3("PreviewDirection2");
RenderGlowMinLuminance = gSavedSettings.getF32("RenderGlowMinLuminance");
RenderGlowMaxExtractAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha");
RenderGlowWarmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount");
RenderGlowLumWeights = gSavedSettings.getVector3("RenderGlowLumWeights");
@ -6916,122 +6913,6 @@ void LLPipeline::renderPostProcess()
gGL.setColorMask(true, true);
glClearColor(0, 0, 0, 0);
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);
gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
mRT->screen.bindTexture(0, 0, LLTexUnit::TFO_POINT);
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);
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();
gGL.getTexUnit(0)->unbind(mRT->screen.getUsage());
mGlow[2].flush();
tc1.setVec(0, 0);
tc2.setVec(2, 2);
}
// 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)
{
gGL.getTexUnit(0)->bind(&mGlow[2]);
}
else
{
gGL.getTexUnit(0)->bind(&mGlow[(i - 1) % 2]);
}
if (i % 2 == 0)
{
gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0);
}
else
{
gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta);
}
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();
mGlow[i % 2].flush();
}
gGlowProgram.unbind();
gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
else // !sRenderGlow, skip the glow ping-pong and just clear the result target
{
mGlow[1].bindTarget();
mGlow[1].clear();
mGlow[1].flush();
}
gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
@ -7341,9 +7222,6 @@ void LLPipeline::renderFinalize()
assertInitialized();
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");
@ -7451,30 +7329,14 @@ void LLPipeline::renderFinalize()
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();
S32 channel = 0;
channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screenTarget()->getUsage());
if (channel > -1)
{
screenTarget()->bindTexture(0, channel, LLTexUnit::TFO_POINT);
}
channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE, screenTarget()->getUsage());
if (channel > -1)
{
mGlow[1].bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
}
gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, screenTarget(), false, LLTexUnit::TFO_POINT);
channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::EXPOSURE_MAP, mExposureMap.getUsage());
if (channel > -1)
{
mExposureMap.bindTexture(0, channel);
}
gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::EXPOSURE_MAP, &mExposureMap);
gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screenTarget()->getWidth(), screenTarget()->getHeight());
@ -7498,6 +7360,101 @@ void LLPipeline::renderFinalize()
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);
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
{
mGlow[1].bindTarget();
mGlow[1].clear();
mGlow[1].flush();
}
{
llassert(!gCubeSnapshot);
bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete();
@ -7528,6 +7485,12 @@ void LLPipeline::renderFinalize()
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();
@ -7587,11 +7550,9 @@ void LLPipeline::renderFinalize()
shader->bind();
S32 screen_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DIFFUSE);
S32 depth_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
gGL.getTexUnit(screen_channel)->bind(&mPostMap);
gGL.getTexUnit(depth_channel)->bind(&mRT->deferredScreen, true);
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;