Skip to content

Commit

Permalink
Add Contrast Adaptive Sharpening post process effect(#2399)
Browse files Browse the repository at this point in the history
  • Loading branch information
RyeMutt committed Aug 24, 2024
1 parent 45b2d69 commit cbca178
Show file tree
Hide file tree
Showing 11 changed files with 2,732 additions and 5 deletions.
46 changes: 46 additions & 0 deletions indra/llrender/llglslshader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1552,6 +1552,34 @@ void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
}
}

void LLGLSLShader::uniform4uiv(U32 index, U32 count, const GLuint* v)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
llassert(sCurBoundShaderPtr == this);

if (mProgramObject)
{
if (mUniform.size() <= index)
{
LL_WARNS_ONCE("Shader") << "Uniform index out of bounds. Size: " << (S32)mUniform.size() << " index: " << index << LL_ENDL;
llassert(false);
return;
}

if (mUniform[index] >= 0)
{
const auto& iter = mValue.find(mUniform[index]);
LLVector4 vec((F32)v[0], (F32)v[1], (F32)v[2], (F32)v[3]);
if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
glUniform4uiv(mUniform[index], count, v);
mValue[mUniform[index]] = vec;
}
}
}
}

void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat* v)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
Expand Down Expand Up @@ -1886,6 +1914,24 @@ void LLGLSLShader::uniform4fv(const LLStaticHashedString& uniform, U32 count, co
}
}

void LLGLSLShader::uniform4uiv(const LLStaticHashedString& uniform, U32 count, const GLuint* v)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
GLint location = getUniformLocation(uniform);

if (location >= 0)
{
LLVector4 vec((F32)v[0], (F32)v[1], (F32)v[2], (F32)v[3]);
const auto& iter = mValue.find(location);
if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
glUniform4uiv(location, count, v);
mValue[location] = vec;
}
}
}

void LLGLSLShader::uniformMatrix4fv(const LLStaticHashedString& uniform, U32 count, GLboolean transpose, const GLfloat* v)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
Expand Down
2 changes: 2 additions & 0 deletions indra/llrender/llglslshader.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ class LLGLSLShader
void uniform2fv(U32 index, U32 count, const GLfloat* v);
void uniform3fv(U32 index, U32 count, const GLfloat* v);
void uniform4fv(U32 index, U32 count, const GLfloat* v);
void uniform4uiv(U32 index, U32 count, const GLuint* v);
void uniform2i(const LLStaticHashedString& uniform, GLint i, GLint j);
void uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat* v);
void uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat* v);
Expand All @@ -223,6 +224,7 @@ class LLGLSLShader
void uniform2fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
void uniform3fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
void uniform4fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
void uniform4uiv(const LLStaticHashedString& uniform, U32 count, const GLuint* v);
void uniformMatrix4fv(const LLStaticHashedString& uniform, U32 count, GLboolean transpose, const GLfloat* v);

void setMinimumAlpha(F32 minimum);
Expand Down
11 changes: 11 additions & 0 deletions indra/newview/app_settings/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9810,6 +9810,17 @@
<key>Value</key>
<string>00000000-0000-0000-0000-000000000000</string>
</map>
<key>RenderCASSharpness</key>
<map>
<key>Comment</key>
<string>Level of sharpening to apply via Contrast Adaptive Sharpening (0.0(off) - 1.0)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.4</real>
</map>
<key>ReplaySession</key>
<map>
<key>Comment</key>
Expand Down
2,558 changes: 2,558 additions & 0 deletions indra/newview/app_settings/shaders/class1/deferred/CASF.glsl

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions indra/newview/featuretable.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ RenderHeroProbeDistance 1 16
RenderHeroProbeUpdateRate 1 4
RenderHeroProbeConservativeUpdateMultiplier 1 16
RenderDownScaleMethod 1 1
RenderCASSharpness 1 1


//
Expand Down Expand Up @@ -115,6 +116,7 @@ RenderHeroProbeResolution 1 256
RenderHeroProbeDistance 1 4
RenderHeroProbeUpdateRate 1 6
RenderHeroProbeConservativeUpdateMultiplier 1 16
RenderCASSharpness 1 0

//
// Medium Low Graphics Settings
Expand Down Expand Up @@ -150,6 +152,7 @@ RenderHeroProbeResolution 1 256
RenderHeroProbeDistance 1 6
RenderHeroProbeUpdateRate 1 3
RenderHeroProbeConservativeUpdateMultiplier 1 16
RenderCASSharpness 1 0

//
// Medium Graphics Settings (standard)
Expand Down Expand Up @@ -185,6 +188,7 @@ RenderHeroProbeResolution 1 512
RenderHeroProbeDistance 1 6
RenderHeroProbeUpdateRate 1 3
RenderHeroProbeConservativeUpdateMultiplier 1 16
RenderCASSharpness 1 0

//
// Medium High Graphics Settings
Expand Down Expand Up @@ -220,6 +224,7 @@ RenderHeroProbeResolution 1 512
RenderHeroProbeDistance 1 6
RenderHeroProbeUpdateRate 1 2
RenderHeroProbeConservativeUpdateMultiplier 1 8
RenderCASSharpness 1 0

//
// High Graphics Settings (SSAO + sun shadows)
Expand Down Expand Up @@ -255,6 +260,7 @@ RenderHeroProbeResolution 1 512
RenderHeroProbeDistance 1 8
RenderHeroProbeUpdateRate 1 2
RenderHeroProbeConservativeUpdateMultiplier 1 8
RenderCASSharpness 1 0.4

//
// High Ultra Graphics Settings (deferred + SSAO + all shadows)
Expand Down Expand Up @@ -290,6 +296,7 @@ RenderHeroProbeResolution 1 1024
RenderHeroProbeDistance 1 16
RenderHeroProbeUpdateRate 1 1
RenderHeroProbeConservativeUpdateMultiplier 1 4
RenderCASSharpness 1 0.4

//
// Ultra graphics (REALLY PURTY!)
Expand Down Expand Up @@ -325,6 +332,7 @@ RenderHeroProbeResolution 1 2048
RenderHeroProbeDistance 1 16
RenderHeroProbeUpdateRate 1 1
RenderHeroProbeConservativeUpdateMultiplier 1 4
RenderCASSharpness 1 0.4

//
// Class Unknown Hardware (unknown)
Expand Down
8 changes: 8 additions & 0 deletions indra/newview/featuretable_mac.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ RenderHeroProbeResolution 1 2048
RenderHeroProbeDistance 1 16
RenderHeroProbeUpdateRate 1 4
RenderHeroProbeConservativeUpdateMultiplier 1 16
RenderCASSharpness 1 1

//
// Low Graphics Settings
Expand Down Expand Up @@ -112,6 +113,7 @@ RenderHeroProbeResolution 1 256
RenderHeroProbeDistance 1 4
RenderHeroProbeUpdateRate 1 6
RenderHeroProbeConservativeUpdateMultiplier 1 16
RenderCASSharpness 1 0

//
// Medium Low Graphics Settings
Expand Down Expand Up @@ -147,6 +149,7 @@ RenderHeroProbeResolution 1 256
RenderHeroProbeDistance 1 6
RenderHeroProbeUpdateRate 1 3
RenderHeroProbeConservativeUpdateMultiplier 1 16
RenderCASSharpness 1 0

//
// Medium Graphics Settings (standard)
Expand Down Expand Up @@ -182,6 +185,7 @@ RenderHeroProbeResolution 1 512
RenderHeroProbeDistance 1 6
RenderHeroProbeUpdateRate 1 3
RenderHeroProbeConservativeUpdateMultiplier 1 16
RenderCASSharpness 1 0

//
// Medium High Graphics Settings
Expand Down Expand Up @@ -217,6 +221,7 @@ RenderHeroProbeResolution 1 512
RenderHeroProbeDistance 1 6
RenderHeroProbeUpdateRate 1 2
RenderHeroProbeConservativeUpdateMultiplier 1 8
RenderCASSharpness 1 0

//
// High Graphics Settings (SSAO + sun shadows)
Expand Down Expand Up @@ -252,6 +257,7 @@ RenderHeroProbeResolution 1 512
RenderHeroProbeDistance 1 8
RenderHeroProbeUpdateRate 1 2
RenderHeroProbeConservativeUpdateMultiplier 1 8
RenderCASSharpness 1 0

//
// High Ultra Graphics Settings (SSAO + all shadows)
Expand Down Expand Up @@ -287,6 +293,7 @@ RenderHeroProbeResolution 1 512
RenderHeroProbeDistance 1 16
RenderHeroProbeUpdateRate 1 1
RenderHeroProbeConservativeUpdateMultiplier 1 4
RenderCASSharpness 1 0.4

//
// Ultra graphics (REALLY PURTY!)
Expand Down Expand Up @@ -322,6 +329,7 @@ RenderHeroProbeResolution 1 1024
RenderHeroProbeDistance 1 16
RenderHeroProbeUpdateRate 1 1
RenderHeroProbeConservativeUpdateMultiplier 1 4
RenderCASSharpness 1 0.4

//
// Class Unknown Hardware (unknown)
Expand Down
12 changes: 12 additions & 0 deletions indra/newview/llviewershadermgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ LLGLSLShader gExposureProgram;
LLGLSLShader gExposureProgramNoFade;
LLGLSLShader gLuminanceProgram;
LLGLSLShader gFXAAProgram;
LLGLSLShader gCASProgram;
LLGLSLShader gDeferredPostNoDoFProgram;
LLGLSLShader gDeferredWLSkyProgram;
LLGLSLShader gEnvironmentMapProgram;
Expand Down Expand Up @@ -2349,6 +2350,17 @@ bool LLViewerShaderMgr::loadShadersDeferred()
llassert(success);
}

if (success)
{
gCASProgram.mName = "Contrast Adaptive Sharpening Shader";
gCASProgram.mFeatures.hasSrgb = true;
gCASProgram.mShaderFiles.clear();
gCASProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
gCASProgram.mShaderFiles.push_back(make_pair("deferred/CASF.glsl", GL_FRAGMENT_SHADER));
gCASProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gCASProgram.createShader();
}

if (success)
{
gDeferredPostProgram.mName = "Deferred Post Shader";
Expand Down
1 change: 1 addition & 0 deletions indra/newview/llviewershadermgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ extern LLGLSLShader gDeferredPostProgram;
extern LLGLSLShader gDeferredCoFProgram;
extern LLGLSLShader gDeferredDoFCombineProgram;
extern LLGLSLShader gFXAAProgram;
extern LLGLSLShader gCASProgram;
extern LLGLSLShader gDeferredPostNoDoFProgram;
extern LLGLSLShader gDeferredPostGammaCorrectProgram;
extern LLGLSLShader gNoPostGammaCorrectProgram;
Expand Down
68 changes: 64 additions & 4 deletions indra/newview/pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,17 @@
#include "llenvironment.h"
#include "llsettingsvo.h"

#ifndef LL_WINDOWS
#define A_GCC 1
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-variable"
#if LL_LINUX
#pragma GCC diagnostic ignored "-Wrestrict"
#endif
#endif
#define A_CPU 1
#include "app_settings/shaders/class1/deferred/CASF.glsl" // This is also C++

extern bool gSnapshot;
bool gShiftFrame = false;

Expand Down Expand Up @@ -202,6 +213,7 @@ S32 LLPipeline::RenderBufferVisualization;
bool LLPipeline::RenderMirrors;
S32 LLPipeline::RenderHeroProbeUpdateRate;
S32 LLPipeline::RenderHeroProbeConservativeUpdateMultiplier;
F32 LLPipeline::RenderCASSharpness;
LLTrace::EventStatHandle<S64> LLPipeline::sStatBatchSize("renderbatchsize");

const U32 LLPipeline::MAX_BAKE_WIDTH = 512;
Expand Down Expand Up @@ -564,6 +576,7 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("RenderMirrors");
connectRefreshCachedSettingsSafe("RenderHeroProbeUpdateRate");
connectRefreshCachedSettingsSafe("RenderHeroProbeConservativeUpdateMultiplier");
connectRefreshCachedSettingsSafe("RenderCASSharpness");
gSavedSettings.getControl("RenderAutoHideSurfaceAreaLimit")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
}

Expand Down Expand Up @@ -1081,6 +1094,7 @@ void LLPipeline::refreshCachedSettings()
RenderMirrors = gSavedSettings.getBOOL("RenderMirrors");
RenderHeroProbeUpdateRate = gSavedSettings.getS32("RenderHeroProbeUpdateRate");
RenderHeroProbeConservativeUpdateMultiplier = gSavedSettings.getS32("RenderHeroProbeConservativeUpdateMultiplier");
RenderCASSharpness = gSavedSettings.getF32("RenderCASSharpness");

sReflectionProbesEnabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionsEnabled") && gSavedSettings.getBOOL("RenderReflectionsEnabled");
RenderSpotLight = nullptr;
Expand Down Expand Up @@ -7133,6 +7147,50 @@ void LLPipeline::generateGlow(LLRenderTarget* src)
}
}

void LLPipeline::applyCAS(LLRenderTarget* src, LLRenderTarget* dst)
{
if (RenderCASSharpness == 0.0)
{
gPipeline.copyRenderTarget(src, dst);
return;
}

LLGLSLShader* sharpen_shader = &gCASProgram;

// Bind setup:
dst->bindTarget();

sharpen_shader->bind();

{
static LLStaticHashedString cas_param_0("cas_param_0");
static LLStaticHashedString cas_param_1("cas_param_1");
static LLStaticHashedString out_screen_res("out_screen_res");

varAU4(const0);
varAU4(const1);
CasSetup(const0, const1,
RenderCASSharpness, // Sharpness tuning knob (0.0 to 1.0).
(AF1)src->getWidth(), (AF1)src->getHeight(), // Input size.
(AF1)dst->getWidth(), (AF1)dst->getHeight()); // Output size.

sharpen_shader->uniform4uiv(cas_param_0, 1, const0);
sharpen_shader->uniform4uiv(cas_param_1, 1, const1);

sharpen_shader->uniform2f(out_screen_res, (AF1)dst->getWidth(), (AF1)dst->getHeight());
}

sharpen_shader->bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_POINT);

// Draw
gPipeline.mScreenTriangleVB->setBuffer();
gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);

sharpen_shader->unbind();

dst->flush();
}

void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst)
{
{
Expand Down Expand Up @@ -7502,13 +7560,15 @@ void LLPipeline::renderFinalize()
gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);

renderDoF(&mRT->screen, &mPostMap);
applyCAS(&mRT->screen, &mPostMap);

renderDoF(&mPostMap, &mRT->screen);

applyFXAA(&mPostMap, &mRT->screen);
LLRenderTarget* finalBuffer = &mRT->screen;
applyFXAA(&mRT->screen, &mPostMap);
LLRenderTarget* finalBuffer = &mPostMap;
if (RenderBufferVisualization > -1)
{
finalBuffer = &mPostMap;
finalBuffer = &mRT->screen;
switch (RenderBufferVisualization)
{
case 0:
Expand Down
2 changes: 2 additions & 0 deletions indra/newview/pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ class LLPipeline
void generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool use_history = true);
void gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst);
void generateGlow(LLRenderTarget* src);
void applyCAS(LLRenderTarget* src, LLRenderTarget* dst);
void applyFXAA(LLRenderTarget* src, LLRenderTarget* dst);
void renderDoF(LLRenderTarget* src, LLRenderTarget* dst);
void copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst);
Expand Down Expand Up @@ -1067,6 +1068,7 @@ class LLPipeline
static bool RenderMirrors;
static S32 RenderHeroProbeUpdateRate;
static S32 RenderHeroProbeConservativeUpdateMultiplier;
static F32 RenderCASSharpness;
};

void render_bbox(const LLVector3 &min, const LLVector3 &max);
Expand Down
Loading

1 comment on commit cbca178

@vldevel
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wondering if the sharpening pass would not be best performed after the anti-aliasing pass: if you sharpen jagged (aliased) edges, they get less efficiently anti-aliased, while sharpening the bad FXAA blurring inside textures is definitely best done after the damages have been done...

Note also that FXAA could be replaced with great benefits by SMAA (which does not blur the details inside the textures unlike what FXAA is doing, but properly detects edges and anti-aliases these only); I backported Rye's pre-PBR SMAA code in Alchemy to the Cool VL Viewer a long while ago, and also managed to adapt it to the PBR renderer: you can test the result in the current Cool VL Viewer release (I also have an older/simpler CAS shader, still backported and adapted from Alchemy pre-PBR, applied after the AA pass), and you can easily compare between FXAA and SMAA in real time with it (just toggle the SMAA check box in the Graphics tab of the Preferences floater).

Please sign in to comment.