Skip to content
Snippets Groups Projects
Commit f1fb85e9 authored by Rye Mutt's avatar Rye Mutt :bread:
Browse files

Replace janky amd tonemapper code with full LPM implementation

parent bdad7785
No related branches found
No related tags found
2 merge requests!3Update to main branch,!2Rebase onto current main branch
Showing with 6813 additions and 107 deletions
...@@ -95,6 +95,7 @@ LLShaderFeatures::LLShaderFeatures() ...@@ -95,6 +95,7 @@ LLShaderFeatures::LLShaderFeatures()
, hasAtmospherics(false) , hasAtmospherics(false)
, hasGamma(false) , hasGamma(false)
, hasSrgb(false) , hasSrgb(false)
, hasLPM(false)
, encodesNormal(false) , encodesNormal(false)
, isDeferred(false) , isDeferred(false)
, hasScreenSpaceReflections(false) , hasScreenSpaceReflections(false)
...@@ -1394,6 +1395,31 @@ void LLGLSLShader::uniform4iv(U32 index, U32 count, const GLint* v) ...@@ -1394,6 +1395,31 @@ void LLGLSLShader::uniform4iv(U32 index, U32 count, const GLint* 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_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
if (mUniform[index] >= 0)
{
const auto& iter = mValue.find(mUniform[index]);
LLVector4 vec(v[0], v[1], v[2], v[3]);
if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1)
{
glUniform1uiv(mUniform[index], count, v);
mValue[mUniform[index]] = vec;
}
}
}
}
void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v) void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
{ {
...@@ -1691,6 +1717,24 @@ void LLGLSLShader::uniform4iv(const LLStaticHashedString& uniform, U32 count, co ...@@ -1691,6 +1717,24 @@ void LLGLSLShader::uniform4iv(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(v[0], v[1], v[2], 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::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint j) void LLGLSLShader::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint j)
{ {
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
......
...@@ -51,6 +51,7 @@ class LLShaderFeatures ...@@ -51,6 +51,7 @@ class LLShaderFeatures
bool hasShadows; bool hasShadows;
bool hasAmbientOcclusion; bool hasAmbientOcclusion;
bool hasSrgb; bool hasSrgb;
bool hasLPM;
bool encodesNormal; // include: shaders\class1\environment\encodeNormF.glsl bool encodesNormal; // include: shaders\class1\environment\encodeNormF.glsl
bool isDeferred; bool isDeferred;
bool hasScreenSpaceReflections; bool hasScreenSpaceReflections;
...@@ -192,6 +193,7 @@ class LLGLSLShader ...@@ -192,6 +193,7 @@ class LLGLSLShader
void uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); void uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void uniform1iv(U32 index, U32 count, const GLint* i); void uniform1iv(U32 index, U32 count, const GLint* i);
void uniform4iv(U32 index, U32 count, const GLint* i); void uniform4iv(U32 index, U32 count, const GLint* i);
void uniform4uiv(U32 index, U32 count, const GLuint* i);
void uniform1fv(U32 index, U32 count, const GLfloat* v); void uniform1fv(U32 index, U32 count, const GLfloat* v);
void uniform2fv(U32 index, U32 count, const GLfloat* v); void uniform2fv(U32 index, U32 count, const GLfloat* v);
void uniform3fv(U32 index, U32 count, const GLfloat* v); void uniform3fv(U32 index, U32 count, const GLfloat* v);
...@@ -204,6 +206,7 @@ class LLGLSLShader ...@@ -204,6 +206,7 @@ class LLGLSLShader
void uniform1i(const LLStaticHashedString& uniform, GLint i); void uniform1i(const LLStaticHashedString& uniform, GLint i);
void uniform1iv(const LLStaticHashedString& uniform, U32 count, const GLint* v); void uniform1iv(const LLStaticHashedString& uniform, U32 count, const GLint* v);
void uniform4iv(const LLStaticHashedString& uniform, U32 count, const GLint* v); void uniform4iv(const LLStaticHashedString& uniform, U32 count, const GLint* v);
void uniform4uiv(const LLStaticHashedString& uniform, U32 count, const GLuint* v);
void uniform1f(const LLStaticHashedString& uniform, GLfloat v); void uniform1f(const LLStaticHashedString& uniform, GLfloat v);
void uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y); void uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y);
void uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y, GLfloat z); void uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y, GLfloat z);
......
...@@ -247,6 +247,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) ...@@ -247,6 +247,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
} }
} }
if (features->hasLPM)
{
if (!shader->attachFragmentObject("alchemy/LPMUtil.glsl"))
{
return FALSE;
}
}
if (features->hasGamma || features->isDeferred) if (features->hasGamma || features->isDeferred)
{ {
if (!shader->attachFragmentObject("windlight/gammaF.glsl")) if (!shader->attachFragmentObject("windlight/gammaF.glsl"))
......
...@@ -116,12 +116,27 @@ void ALFloaterLightBox::onClickResetGroupDefault(const LLSD& userdata) ...@@ -116,12 +116,27 @@ void ALFloaterLightBox::onClickResetGroupDefault(const LLSD& userdata)
{ {
controlp->resetToDefault(true); controlp->resetToDefault(true);
} }
controlp = gSavedSettings.getControl("AlchemyToneMapAMDExposure");
if (controlp)
{
controlp->resetToDefault(true);
}
controlp = gSavedSettings.getControl("AlchemyToneMapAMDContrast"); controlp = gSavedSettings.getControl("AlchemyToneMapAMDContrast");
if (controlp) if (controlp)
{ {
controlp->resetToDefault(true); controlp->resetToDefault(true);
} }
controlp = gSavedSettings.getControl("AlchemyToneMapAMDShoulder"); controlp = gSavedSettings.getControl("AlchemyToneMapAMDSaturationR");
if (controlp)
{
controlp->resetToDefault(true);
}
controlp = gSavedSettings.getControl("AlchemyToneMapAMDSaturationG");
if (controlp)
{
controlp->resetToDefault(true);
}
controlp = gSavedSettings.getControl("AlchemyToneMapAMDSaturationB");
if (controlp) if (controlp)
{ {
controlp->resetToDefault(true); controlp->resetToDefault(true);
...@@ -345,52 +360,79 @@ void ALFloaterLightBox::updateTonemapper() ...@@ -345,52 +360,79 @@ void ALFloaterLightBox::updateTonemapper()
text1->setText(std::string("HDR Max")); text1->setText(std::string("HDR Max"));
spinner1->setVisible(TRUE); spinner1->setVisible(TRUE);
spinner1->setMinValue(1.0); spinner1->setMinValue(1.0);
spinner1->setMaxValue(24.0); spinner1->setMaxValue(512.0);
spinner1->setIncrement(0.1); spinner1->setIncrement(1.f);
spinner1->setControlName("AlchemyToneMapAMDHDRMax"); spinner1->setControlName("AlchemyToneMapAMDHDRMax");
slider1->setVisible(TRUE); slider1->setVisible(TRUE);
slider1->setMinValue(1.0); slider1->setMinValue(1.0);
slider1->setMaxValue(24.0); slider1->setMaxValue(512.0);
slider1->setIncrement(0.1); slider1->setIncrement(1.f);
slider1->setControlName("AlchemyToneMapAMDHDRMax", nullptr); slider1->setControlName("AlchemyToneMapAMDHDRMax", nullptr);
text2->setVisible(TRUE); text2->setVisible(TRUE);
text2->setText(std::string("Contrast")); text2->setText(std::string("Tone Exposure"));
spinner2->setVisible(TRUE); spinner2->setVisible(TRUE);
spinner2->setMinValue(0.5); spinner2->setMinValue(1.0);
spinner2->setMaxValue(4.0); spinner2->setMaxValue(16.0);
spinner2->setControlName("AlchemyToneMapAMDContrast"); spinner2->setIncrement(0.1);
spinner2->setIncrement(0.01); spinner2->setControlName("AlchemyToneMapAMDExposure");
slider2->setVisible(TRUE); slider2->setVisible(TRUE);
slider2->setMinValue(0.5); slider2->setMinValue(1.0);
slider2->setMaxValue(4.0); slider2->setMaxValue(16.0);
slider2->setIncrement(0.01); slider2->setIncrement(0.1);
slider2->setControlName("AlchemyToneMapAMDContrast", nullptr); slider2->setControlName("AlchemyToneMapAMDExposure", nullptr);
text3->setVisible(TRUE); text3->setVisible(TRUE);
text3->setText(std::string("Shoulder")); text3->setText(std::string("Contrast"));
spinner3->setVisible(TRUE); spinner3->setVisible(TRUE);
spinner3->setMinValue(0.5); spinner3->setMinValue(0.0);
spinner3->setMaxValue(4.0); spinner3->setMaxValue(1.0);
spinner3->setIncrement(0.01); spinner3->setIncrement(0.01);
spinner3->setControlName("AlchemyToneMapAMDShoulder"); spinner3->setControlName("AlchemyToneMapAMDContrast");
slider3->setVisible(TRUE); slider3->setVisible(TRUE);
slider3->setMinValue(0.5); slider3->setMinValue(0.0);
slider3->setMaxValue(4.0); slider3->setMaxValue(1.0);
slider3->setIncrement(0.01); slider3->setIncrement(0.01);
slider3->setControlName("AlchemyToneMapAMDShoulder", nullptr); slider3->setControlName("AlchemyToneMapAMDContrast", nullptr);
text4->setVisible(FALSE); text4->setVisible(TRUE);
spinner4->setVisible(FALSE); text4->setText(std::string("R Saturation"));
slider4->setVisible(FALSE); spinner4->setVisible(TRUE);
spinner4->setMinValue(-2.0);
spinner4->setMaxValue(2.0);
spinner4->setIncrement(0.1);
spinner4->setControlName("AlchemyToneMapAMDSaturationR");
slider4->setVisible(TRUE);
slider4->setMinValue(-2.0);
slider4->setMaxValue(2.0);
slider4->setIncrement(0.1);
slider4->setControlName("AlchemyToneMapAMDSaturationR", nullptr);
text5->setVisible(FALSE); text5->setVisible(TRUE);
spinner5->setVisible(FALSE); text5->setText(std::string("G Saturation"));
slider5->setVisible(FALSE); spinner5->setVisible(TRUE);
spinner5->setMinValue(-2.0);
spinner5->setMaxValue(2.0);
spinner5->setIncrement(0.1);
spinner5->setControlName("AlchemyToneMapAMDSaturationG");
slider5->setVisible(TRUE);
slider5->setMinValue(-2.0);
slider5->setMaxValue(2.0);
slider5->setIncrement(0.1);
slider5->setControlName("AlchemyToneMapAMDSaturationG", nullptr);
text6->setVisible(FALSE); text6->setVisible(TRUE);
spinner6->setVisible(FALSE); text6->setText(std::string("B Saturation"));
slider6->setVisible(FALSE); spinner6->setVisible(TRUE);
spinner6->setMinValue(-2.0);
spinner6->setMaxValue(2.0);
spinner6->setIncrement(0.1);
spinner6->setControlName("AlchemyToneMapAMDSaturationB");
slider6->setVisible(TRUE);
slider6->setMinValue(-2.0);
slider6->setMaxValue(2.0);
slider6->setIncrement(0.1);
slider6->setControlName("AlchemyToneMapAMDSaturationB", nullptr);
text7->setVisible(FALSE); text7->setVisible(FALSE);
spinner7->setVisible(FALSE); spinner7->setVisible(FALSE);
......
...@@ -41,12 +41,21 @@ ...@@ -41,12 +41,21 @@
#include "llviewershadermgr.h" #include "llviewershadermgr.h"
#include "pipeline.h" #include "pipeline.h"
#define A_CPU 1
#include "app_settings/shaders/class1/alchemy/ffx_a.h"
AU1 ctl[24 * 4] = {}; // Upload this to a uint4[24] part of a constant buffer (for example 'constant.lpm[24]').
A_STATIC void LpmSetupOut(AU1 i, inAU4 v) { ctl[i * 4 + 0] = v[0]; ctl[i * 4 + 1] = v[1]; ctl[i * 4 + 2] = v[2]; ctl[i * 4 + 3] = v[3]; }
#include "app_settings/shaders/class1/alchemy/ffx_lpm.h"
const U32 ALRENDER_BUFFER_MASK = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1; const U32 ALRENDER_BUFFER_MASK = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
static LLStaticHashedString al_exposure("exposure"); static LLStaticHashedString al_exposure("exposure");
static LLStaticHashedString tone_uchimura_a("tone_uchimura_a"); static LLStaticHashedString tone_uchimura_a("tone_uchimura_a");
static LLStaticHashedString tone_uchimura_b("tone_uchimura_b"); static LLStaticHashedString tone_uchimura_b("tone_uchimura_b");
static LLStaticHashedString tonemap_amd_params("tonemap_amd"); static LLStaticHashedString tonemap_amd_params("tonemap_amd");
static LLStaticHashedString tonemap_amd_params_shoulder("tonemap_amd_shoulder");
static LLStaticHashedString tone_uncharted_a("tone_uncharted_a"); static LLStaticHashedString tone_uncharted_a("tone_uncharted_a");
static LLStaticHashedString tone_uncharted_b("tone_uncharted_b"); static LLStaticHashedString tone_uncharted_b("tone_uncharted_b");
static LLStaticHashedString tone_uncharted_c("tone_uncharted_c"); static LLStaticHashedString tone_uncharted_c("tone_uncharted_c");
...@@ -248,8 +257,16 @@ ALRenderUtil::ALRenderUtil() ...@@ -248,8 +257,16 @@ ALRenderUtil::ALRenderUtil()
gSavedSettings.getControl("RenderToneMapType")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this)); gSavedSettings.getControl("RenderToneMapType")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this));
gSavedSettings.getControl("RenderExposure")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this)); gSavedSettings.getControl("RenderExposure")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this));
gSavedSettings.getControl("AlchemyToneMapAMDHDRMax")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this)); gSavedSettings.getControl("AlchemyToneMapAMDHDRMax")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this));
gSavedSettings.getControl("AlchemyToneMapAMDExposure")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this));
gSavedSettings.getControl("AlchemyToneMapAMDContrast")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this)); gSavedSettings.getControl("AlchemyToneMapAMDContrast")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this));
gSavedSettings.getControl("AlchemyToneMapAMDShoulder")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this)); gSavedSettings.getControl("AlchemyToneMapAMDSaturationR")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this));
gSavedSettings.getControl("AlchemyToneMapAMDSaturationG")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this));
gSavedSettings.getControl("AlchemyToneMapAMDSaturationB")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this));
gSavedSettings.getControl("AlchemyToneMapAMDCrosstalkR")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this));
gSavedSettings.getControl("AlchemyToneMapAMDCrosstalkG")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this));
gSavedSettings.getControl("AlchemyToneMapAMDCrosstalkB")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this));
gSavedSettings.getControl("AlchemyToneMapAMDShoulderContrast")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this));
gSavedSettings.getControl("AlchemyToneMapAMDShoulderContrastRange")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this));
gSavedSettings.getControl("AlchemyToneMapUchimuraMaxBrightness")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this)); gSavedSettings.getControl("AlchemyToneMapUchimuraMaxBrightness")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this));
gSavedSettings.getControl("AlchemyToneMapUchimuraContrast")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this)); gSavedSettings.getControl("AlchemyToneMapUchimuraContrast")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this));
gSavedSettings.getControl("AlchemyToneMapUchimuraLinearStart")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this)); gSavedSettings.getControl("AlchemyToneMapUchimuraLinearStart")->getSignal()->connect(boost::bind(&ALRenderUtil::setupTonemap, this));
...@@ -319,12 +336,35 @@ bool ALRenderUtil::setupTonemap() ...@@ -319,12 +336,35 @@ bool ALRenderUtil::setupTonemap()
mTonemapExposure = llclamp(gSavedSettings.getF32("RenderExposure"), 0.5f, 4.f); mTonemapExposure = llclamp(gSavedSettings.getF32("RenderExposure"), 0.5f, 4.f);
mToneAMDParams = LLVector3(gSavedSettings.getF32("AlchemyToneMapAMDHDRMax"), gSavedSettings.getF32("AlchemyToneMapAMDContrast"), gSavedSettings.getF32("AlchemyToneMapAMDShoulder"));
mToneUchimuraParamA = LLVector3(gSavedSettings.getF32("AlchemyToneMapUchimuraMaxBrightness"), gSavedSettings.getF32("AlchemyToneMapUchimuraContrast"), gSavedSettings.getF32("AlchemyToneMapUchimuraLinearStart")); mToneUchimuraParamA = LLVector3(gSavedSettings.getF32("AlchemyToneMapUchimuraMaxBrightness"), gSavedSettings.getF32("AlchemyToneMapUchimuraContrast"), gSavedSettings.getF32("AlchemyToneMapUchimuraLinearStart"));
mToneUchimuraParamB = LLVector3(gSavedSettings.getF32("AlchemyToneMapUchimuraLinearLength"), gSavedSettings.getF32("AlchemyToneMapUchimuraBlackLevel"), 0.0); mToneUchimuraParamB = LLVector3(gSavedSettings.getF32("AlchemyToneMapUchimuraLinearLength"), gSavedSettings.getF32("AlchemyToneMapUchimuraBlackLevel"), 0.0);
mToneUnchartedParamA = LLVector3(gSavedSettings.getF32("AlchemyToneMapFilmicToeStr"), gSavedSettings.getF32("AlchemyToneMapFilmicToeLen"), gSavedSettings.getF32("AlchemyToneMapFilmicShoulderStr")); mToneUnchartedParamA = LLVector3(gSavedSettings.getF32("AlchemyToneMapFilmicToeStr"), gSavedSettings.getF32("AlchemyToneMapFilmicToeLen"), gSavedSettings.getF32("AlchemyToneMapFilmicShoulderStr"));
mToneUnchartedParamB = LLVector3(gSavedSettings.getF32("AlchemyToneMapFilmicShoulderLen"), gSavedSettings.getF32("AlchemyToneMapFilmicShoulderAngle"), gSavedSettings.getF32("AlchemyToneMapFilmicGamma")); mToneUnchartedParamB = LLVector3(gSavedSettings.getF32("AlchemyToneMapFilmicShoulderLen"), gSavedSettings.getF32("AlchemyToneMapFilmicShoulderAngle"), gSavedSettings.getF32("AlchemyToneMapFilmicGamma"));
mToneUnchartedParamC = LLVector3(gSavedSettings.getF32("AlchemyToneMapFilmicWhitePoint"), 2.0, 0.0); mToneUnchartedParamC = LLVector3(gSavedSettings.getF32("AlchemyToneMapFilmicWhitePoint"), 2.0, 0.0);
static LLCachedControl<F32> amd_hdrmax(gSavedSettings, "AlchemyToneMapAMDHDRMax", 256.f);
static LLCachedControl<F32> amd_exposure(gSavedSettings, "AlchemyToneMapAMDExposure", 8.0f);
static LLCachedControl<F32> amd_contrast(gSavedSettings, "AlchemyToneMapAMDContrast", 0.25f);
static LLCachedControl<F32> amd_satr(gSavedSettings, "AlchemyToneMapAMDSaturationR", 0.f);
static LLCachedControl<F32> amd_satg(gSavedSettings, "AlchemyToneMapAMDSaturationG", 0.f);
static LLCachedControl<F32> amd_satb(gSavedSettings, "AlchemyToneMapAMDSaturationB", 0.f);
static LLCachedControl<F32> amd_crossr(gSavedSettings, "AlchemyToneMapAMDCrosstalkR", 1.0 / 2.0);
static LLCachedControl<F32> amd_crossg(gSavedSettings, "AlchemyToneMapAMDCrosstalkG", 1.f);
static LLCachedControl<F32> amd_crossb(gSavedSettings, "AlchemyToneMapAMDCrosstalkB", 1.0 / 32.0);
static LLCachedControl<bool> amd_sh_contrast(gSavedSettings, "AlchemyToneMapAMDShoulderContrast", false);
static LLCachedControl<F32> amd_sh_contrast_range(gSavedSettings, "AlchemyToneMapAMDShoulderContrastRange", 1.0);
varAF3(saturation) = initAF3(amd_satr, amd_satg, amd_satb);
varAF3(crosstalk) = initAF3(amd_crossr, amd_crossg, amd_crossb);
LpmSetup(
amd_sh_contrast, LPM_CONFIG_709_709, LPM_COLORS_709_709, // <-- Using the LPM_ prefabs to make inputs easier.
0.0, // softGap
amd_hdrmax, // hdrMax
amd_exposure, // exposure
amd_contrast, // contrast
amd_sh_contrast ? amd_sh_contrast_range : 1.0, // shoulder contrast
saturation, crosstalk);
} }
return true; return true;
} }
...@@ -540,7 +580,9 @@ void ALRenderUtil::renderTonemap(LLRenderTarget* src, LLRenderTarget* exposure, ...@@ -540,7 +580,9 @@ void ALRenderUtil::renderTonemap(LLRenderTarget* src, LLRenderTarget* exposure,
} }
case ALTonemap::TONEMAP_AMD: case ALTonemap::TONEMAP_AMD:
{ {
tone_shader->uniform3fv(tonemap_amd_params, 1, mToneAMDParams.mV); static LLCachedControl<bool> amd_sh_contrast(gSavedSettings, "AlchemyToneMapAMDShoulderContrast", false);
tone_shader->uniform4uiv(tonemap_amd_params, 24, ctl);
tone_shader->uniform1i(tonemap_amd_params_shoulder, amd_sh_contrast);
break; break;
} }
case ALTonemap::TONEMAP_UNCHARTED: case ALTonemap::TONEMAP_UNCHARTED:
......
...@@ -78,7 +78,6 @@ class ALRenderUtil ...@@ -78,7 +78,6 @@ class ALRenderUtil
// State // State
U32 mTonemapType = ALTonemap::TONEMAP_NONE; U32 mTonemapType = ALTonemap::TONEMAP_NONE;
LLVector3 mToneAMDParams;
LLVector3 mToneUchimuraParamA; LLVector3 mToneUchimuraParamA;
LLVector3 mToneUchimuraParamB; LLVector3 mToneUchimuraParamB;
LLVector3 mToneUnchartedParamA; LLVector3 mToneUnchartedParamA;
......
...@@ -1146,29 +1146,117 @@ ...@@ -1146,29 +1146,117 @@
<key>AlchemyToneMapAMDHDRMax</key> <key>AlchemyToneMapAMDHDRMax</key>
<map> <map>
<key>Comment</key> <key>Comment</key>
<string>How much HDR range before clipping. HDR modes likely need this pushed up to say 25.0.</string> <string>Maximum input value.</string>
<key>Persist</key> <key>Persist</key>
<integer>1</integer> <integer>1</integer>
<key>Type</key> <key>Type</key>
<string>F32</string> <string>F32</string>
<key>Value</key> <key>Value</key>
<real>16.0</real> <real>256.0</real>
</map> </map>
<key>AlchemyToneMapAMDContrast</key> <key>AlchemyToneMapAMDExposure</key>
<map> <map>
<key>Comment</key> <key>Comment</key>
<string>Use as a baseline to tune the amount of contrast the tonemapper has.</string> <string>Number of stops between 'hdrMax' and 18% mid-level on input.</string>
<key>Persist</key> <key>Persist</key>
<integer>1</integer> <integer>1</integer>
<key>Type</key> <key>Type</key>
<string>F32</string> <string>F32</string>
<key>Value</key> <key>Value</key>
<real>1.4</real> <real>8.0</real>
</map>
<key>AlchemyToneMapAMDContrast</key>
<map>
<key>Comment</key>
<string>Input range 0.0 (no extra contrast) to 1.0 (maximum contrast)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.25</real>
</map>
<key>AlchemyToneMapAMDCrosstalkR</key>
<map>
<key>Comment</key>
<string>One channel must be 1.0, the rest can be greater than or equal to 1.0 but not zero.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.5</real>
</map>
<key>AlchemyToneMapAMDCrosstalkG</key>
<map>
<key>Comment</key>
<string>One channel must be 1.0, the rest can be greater than or equal to 1.0 but not zero.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>1.0</real>
</map>
<key>AlchemyToneMapAMDCrosstalkB</key>
<map>
<key>Comment</key>
<string> One channel must be 1.0, the rest can be greater than or equal to 1.0 but not zero.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.03125</real>
</map>
<key>AlchemyToneMapAMDSaturationR</key>
<map>
<key>Comment</key>
<string>A per channel adjustment, use less than 0 decrease, 0=no change, greater 0 increase.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.0</real>
</map>
<key>AlchemyToneMapAMDSaturationG</key>
<map>
<key>Comment</key>
<string>A per channel adjustment, use less than 0 decrease, 0=no change, greater 0 increase.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.0</real>
</map>
<key>AlchemyToneMapAMDSaturationB</key>
<map>
<key>Comment</key>
<string>A per channel adjustment, use less than 0 decrease, 0=no change, greater 0 increase.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.0</real>
</map>
<key>AlchemyToneMapAMDShoulderContrast</key>
<map>
<key>Comment</key>
<string>Use optional extra shoulderContrast tuning (set to false if shoulderContrast is 1.0).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map> </map>
<key>AlchemyToneMapAMDShoulder</key> <key>AlchemyToneMapAMDShoulderContrastRange</key>
<map> <map>
<key>Comment</key> <key>Comment</key>
<string>Tonemap shoulder adjustment</string> <string>Shoulder shaping, 1.0 = no change (fast path)</string>
<key>Persist</key> <key>Persist</key>
<integer>1</integer> <integer>1</integer>
<key>Type</key> <key>Type</key>
......
Source diff could not be displayed: it is too large. Options to address this: view the blob.
This diff is collapsed.
This diff is collapsed.
...@@ -47,6 +47,8 @@ uniform sampler3D colorgrade_lut; ...@@ -47,6 +47,8 @@ uniform sampler3D colorgrade_lut;
uniform vec4 colorgrade_lut_size; uniform vec4 colorgrade_lut_size;
#endif #endif
void RunLPMFilter(inout vec3 diff);
// ACES filmic tone map approximation // ACES filmic tone map approximation
// see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl // see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl
// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT // sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
...@@ -120,70 +122,6 @@ vec3 uchimura(vec3 x) ...@@ -120,70 +122,6 @@ vec3 uchimura(vec3 x)
return uchimura(x, P, a, m, l, c, b); return uchimura(x, P, a, m, l, c, b);
} }
//--------------------------------------------------------------------------------------
// AMD Tonemapper
//--------------------------------------------------------------------------------------
// General tonemapping operator, build 'b' term.
float ColToneB(float hdrMax, float contrast, float shoulder, float midIn, float midOut)
{
return
-((-pow(midIn, contrast) + (midOut*(pow(hdrMax, contrast*shoulder)*pow(midIn, contrast) -
pow(hdrMax, contrast)*pow(midIn, contrast*shoulder)*midOut)) /
(pow(hdrMax, contrast*shoulder)*midOut - pow(midIn, contrast*shoulder)*midOut)) /
(pow(midIn, contrast*shoulder)*midOut));
}
// General tonemapping operator, build 'c' term.
float ColToneC(float hdrMax, float contrast, float shoulder, float midIn, float midOut)
{
return (pow(hdrMax, contrast*shoulder)*pow(midIn, contrast) - pow(hdrMax, contrast)*pow(midIn, contrast*shoulder)*midOut) /
(pow(hdrMax, contrast*shoulder)*midOut - pow(midIn, contrast*shoulder)*midOut);
}
// General tonemapping operator, p := {contrast,shoulder,b,c}.
float ColTone(float x, vec4 p)
{
float z = pow(x, p.r);
return z / (pow(z, p.g)*p.b + p.a);
}
uniform vec3 tonemap_amd = vec3(16.0, 1.4, 1.0);
vec3 AMDTonemapper(vec3 color)
{
float hdrMax = tonemap_amd.x; // How much HDR range before clipping. HDR modes likely need this pushed up to say 25.0.
float contrast = tonemap_amd.y; // Use as a baseline to tune the amount of contrast the tonemapper has.
float shoulder = tonemap_amd.z; // Likely don’t need to mess with this factor, unless matching existing tonemapper is not working well..
const float midIn = 0.18; // most games will have a {0.0 to 1.0} range for LDR so midIn should be 0.18.
const float midOut = 0.18; // Use for LDR. For HDR10 10:10:10:2 use maybe 0.18/25.0 to start. For scRGB, I forget what a good starting point is, need to re-calculate.
float b = ColToneB(hdrMax, contrast, shoulder, midIn, midOut);
float c = ColToneC(hdrMax, contrast, shoulder, midIn, midOut);
#define EPS 1e-6f
float peak = max(color.r, max(color.g, color.b));
peak = max(EPS, peak);
vec3 ratio = color / peak;
peak = ColTone(peak, vec4(contrast, shoulder, b, c) );
// then process ratio
// probably want send these pre-computed (so send over saturation/crossSaturation as a constant)
float crosstalk = 4.0; // controls amount of channel crosstalk
float saturation = contrast; // full tonal range saturation control
float crossSaturation = contrast*16.0; // crosstalk saturation
float white = 1.0;
// wrap crosstalk in transform
ratio = pow(abs(ratio), vec3(saturation / crossSaturation));
ratio = mix(ratio, vec3(white), vec3(pow(peak, crosstalk)));
ratio = pow(abs(ratio), vec3(crossSaturation));
// then apply ratio to peak
color = peak * ratio;
return color;
}
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// Hable, http://filmicworlds.com/blog/filmic-tonemapping-operators/ // Hable, http://filmicworlds.com/blog/filmic-tonemapping-operators/
...@@ -279,7 +217,8 @@ void main() ...@@ -279,7 +217,8 @@ void main()
#elif TONEMAP_METHOD == 2 // Uchimura's Gran Turismo method #elif TONEMAP_METHOD == 2 // Uchimura's Gran Turismo method
diff.rgb = uchimura(diff.rgb); diff.rgb = uchimura(diff.rgb);
#elif TONEMAP_METHOD == 3 // AMD Tonemapper #elif TONEMAP_METHOD == 3 // AMD Tonemapper
diff.rgb = AMDTonemapper(diff.rgb); RunLPMFilter(diff.rgb);// LpmFilter(diff.r,diff.g,diff.b,false,LPM_CONFIG_709_709); // <-- Using the LPM_CONFIG_ prefab to make inputs easier.
//diff.rgb = AMDTonemapper(diff.rgb);
#elif TONEMAP_METHOD == 4 // Uncharted #elif TONEMAP_METHOD == 4 // Uncharted
diff.rgb = uncharted2(diff.rgb); diff.rgb = uncharted2(diff.rgb);
#endif #endif
......
...@@ -752,7 +752,8 @@ std::string LLViewerShaderMgr::loadBasicShaders() ...@@ -752,7 +752,8 @@ std::string LLViewerShaderMgr::loadBasicShaders()
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/deferredUtil.glsl", 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/deferredUtil.glsl", 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/reflectionProbeF.glsl", has_reflection_probes ? 3 : 2) ); index_channels.push_back(-1); shaders.push_back( make_pair( "alchemy/LPMUtil.glsl", 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/reflectionProbeF.glsl", has_reflection_probes ? 3 : 2) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/screenSpaceReflUtil.glsl", ssr ? 3 : 1) ); index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/screenSpaceReflUtil.glsl", ssr ? 3 : 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) ); index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
...@@ -2887,6 +2888,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() ...@@ -2887,6 +2888,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
mShaderList.push_back(&gDeferredPostTonemapProgram[i]); mShaderList.push_back(&gDeferredPostTonemapProgram[i]);
gDeferredPostTonemapProgram[i].mName = "Tonemapping Shader " + std::to_string(i); gDeferredPostTonemapProgram[i].mName = "Tonemapping Shader " + std::to_string(i);
gDeferredPostTonemapProgram[i].mFeatures.hasSrgb = true; gDeferredPostTonemapProgram[i].mFeatures.hasSrgb = true;
gDeferredPostTonemapProgram[i].mFeatures.hasLPM = true;
gDeferredPostTonemapProgram[i].mShaderFiles.clear(); gDeferredPostTonemapProgram[i].mShaderFiles.clear();
gDeferredPostTonemapProgram[i].mShaderFiles.push_back(make_pair("alchemy/postNoTCV.glsl", GL_VERTEX_SHADER)); gDeferredPostTonemapProgram[i].mShaderFiles.push_back(make_pair("alchemy/postNoTCV.glsl", GL_VERTEX_SHADER));
gDeferredPostTonemapProgram[i].mShaderFiles.push_back(make_pair("alchemy/toneMapF.glsl", GL_FRAGMENT_SHADER)); gDeferredPostTonemapProgram[i].mShaderFiles.push_back(make_pair("alchemy/toneMapF.glsl", GL_FRAGMENT_SHADER));
...@@ -2904,6 +2906,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() ...@@ -2904,6 +2906,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
mShaderList.push_back(&gDeferredPostColorGradeLUTProgram[i]); mShaderList.push_back(&gDeferredPostColorGradeLUTProgram[i]);
gDeferredPostColorGradeLUTProgram[i].mName = "Color Grading Shader " + std::to_string(i); gDeferredPostColorGradeLUTProgram[i].mName = "Color Grading Shader " + std::to_string(i);
gDeferredPostColorGradeLUTProgram[i].mFeatures.hasSrgb = true; gDeferredPostColorGradeLUTProgram[i].mFeatures.hasSrgb = true;
gDeferredPostColorGradeLUTProgram[i].mFeatures.hasLPM = true;
gDeferredPostColorGradeLUTProgram[i].mShaderFiles.clear(); gDeferredPostColorGradeLUTProgram[i].mShaderFiles.clear();
gDeferredPostColorGradeLUTProgram[i].mShaderFiles.push_back(make_pair("alchemy/postNoTCV.glsl", GL_VERTEX_SHADER)); gDeferredPostColorGradeLUTProgram[i].mShaderFiles.push_back(make_pair("alchemy/postNoTCV.glsl", GL_VERTEX_SHADER));
gDeferredPostColorGradeLUTProgram[i].mShaderFiles.push_back(make_pair("alchemy/toneMapF.glsl", GL_FRAGMENT_SHADER)); gDeferredPostColorGradeLUTProgram[i].mShaderFiles.push_back(make_pair("alchemy/toneMapF.glsl", GL_FRAGMENT_SHADER));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment