DRTVWR-559 Dynamic exposure followup -- stochastic sampling, weight based on luminance and distance to center of screen, rebalance night, don't rely on blending not clamping R16F.
parent
4f651bceab
commit
b130831106
|
|
@ -31,12 +31,22 @@ out vec4 frag_color;
|
|||
|
||||
uniform sampler2D diffuseRect;
|
||||
uniform sampler2D emissiveRect;
|
||||
uniform sampler2D exposureMap;
|
||||
|
||||
uniform float dt;
|
||||
uniform vec2 noiseVec;
|
||||
|
||||
// calculate luminance the same way LLColor4::calcHSL does
|
||||
float lum(vec3 col)
|
||||
{
|
||||
float mx = max(max(col.r, col.g), col.b);
|
||||
float mn = min(min(col.r, col.g), col.b);
|
||||
return (mx + mn) * 0.5;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
int samples = 16;
|
||||
float step = 1.0/(samples-4);
|
||||
float step = 1.0/32.0;
|
||||
|
||||
float start = step;
|
||||
float end = 1.0-step;
|
||||
|
|
@ -45,23 +55,38 @@ void main()
|
|||
|
||||
vec3 col;
|
||||
|
||||
vec2 nz = noiseVec * step * 0.5;
|
||||
|
||||
for (float x = start; x <= end; x += step)
|
||||
{
|
||||
for (float y = start; y <= end; y += step)
|
||||
{
|
||||
vec2 tc = vec2(x,y);
|
||||
w += 1.0;
|
||||
col += texture(diffuseRect, tc).rgb + texture(emissiveRect, tc).rgb;
|
||||
vec2 tc = vec2(x,y) + nz;
|
||||
vec3 c = texture(diffuseRect, tc).rgb + texture(emissiveRect, tc).rgb;
|
||||
float L = max(lum(c), 0.25);
|
||||
|
||||
float d = length(vec2(0.5)-tc);
|
||||
d = 1.0-d;
|
||||
d *= d;
|
||||
d *= d;
|
||||
d *= d;
|
||||
L *= d;
|
||||
|
||||
w += L;
|
||||
|
||||
col += c * L;
|
||||
}
|
||||
}
|
||||
|
||||
col /= w;
|
||||
|
||||
// calculate luminance the same way LLColor4::calcHSL does
|
||||
float mx = max(max(col.r, col.g), col.b);
|
||||
float mn = min(min(col.r, col.g), col.b);
|
||||
float lum = (mx + mn) * 0.5;
|
||||
float L = lum(col);
|
||||
|
||||
frag_color = vec4(lum, lum, lum, dt);
|
||||
float s = clamp(0.1/L, 0.5, 4.0);
|
||||
|
||||
float prev = texture(exposureMap, vec2(0.5,0.5)).r;
|
||||
s = mix(prev, s, min(dt*2.0, 0.04));
|
||||
|
||||
frag_color = vec4(s, s, s, dt);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -108,9 +108,8 @@ uniform float gamma;
|
|||
|
||||
vec3 toneMap(vec3 color)
|
||||
{
|
||||
float exp_sample = texture(exposureMap, vec2(0.5,0.5)).r;
|
||||
float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r;
|
||||
|
||||
float exp_scale = clamp(0.1/exp_sample, 0.5, 8.0);
|
||||
color *= exposure * exp_scale;
|
||||
|
||||
#ifdef TONEMAP_ACES_NARKOWICZ
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ void main()
|
|||
vary_LightNormPosDot = rel_pos_lightnorm_dot;
|
||||
|
||||
// Initialize temp variables
|
||||
vec3 sunlight = (sun_up_factor == 1) ? sunlight_color*2.0 : moonlight_color*0.5;
|
||||
vec3 sunlight = (sun_up_factor == 1) ? sunlight_color*2.0 : moonlight_color*0.75;
|
||||
|
||||
// Sunlight attenuation effect (hue and brightness) due to atmosphere
|
||||
// this is used later for sunlight modulation at various altitudes
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
|
|||
vec3 rel_pos_norm = normalize(rel_pos);
|
||||
float rel_pos_len = length(rel_pos);
|
||||
float scale = 2.0;
|
||||
vec3 sunlight = (sun_up_factor == 1) ? sunlight_color * scale: moonlight_color/scale;
|
||||
vec3 sunlight = (sun_up_factor == 1) ? sunlight_color * scale: moonlight_color*0.75;
|
||||
|
||||
// sunlight attenuation effect (hue and brightness) due to atmosphere
|
||||
// this is used later for sunlight modulation at various altitudes
|
||||
|
|
|
|||
|
|
@ -116,27 +116,7 @@
|
|||
#include "llenvironment.h"
|
||||
#include "llsettingsvo.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Debug indices is disabled for now for debug performance - djs 4/24/02
|
||||
//#define DEBUG_INDICES
|
||||
#else
|
||||
//#define DEBUG_INDICES
|
||||
#endif
|
||||
|
||||
// Expensive and currently broken
|
||||
//
|
||||
#define MATERIALS_IN_REFLECTIONS 0
|
||||
|
||||
// NOTE: Keep in sync with indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
|
||||
// NOTE: Unused consts are commented out since some compilers (on macOS) may complain about unused variables.
|
||||
// const S32 WATER_REFLECT_NONE_WATER_OPAQUE = -2;
|
||||
//const S32 WATER_REFLECT_NONE_WATER_TRANSPARENT = -1;
|
||||
//const S32 WATER_REFLECT_MINIMAL = 0;
|
||||
// const S32 WATER_REFLECT_TERRAIN = 1;
|
||||
//const S32 WATER_REFLECT_STATIC_OBJECTS = 2;
|
||||
//const S32 WATER_REFLECT_AVATARS = 3;
|
||||
//const S32 WATER_REFLECT_EVERYTHING = 4;
|
||||
|
||||
extern BOOL gSnapshot;
|
||||
bool gShiftFrame = false;
|
||||
|
||||
//cached settings
|
||||
|
|
@ -851,11 +831,6 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
|
|||
|
||||
mPostMap.allocate(resX, resY, GL_RGBA);
|
||||
|
||||
mExposureMap.allocate(1, 1, GL_R16F);
|
||||
mExposureMap.bindTarget();
|
||||
mExposureMap.clear();
|
||||
mExposureMap.flush();
|
||||
|
||||
//HACK make screenbuffer allocations start failing after 30 seconds
|
||||
if (gSavedSettings.getBOOL("SimulateFBOFailure"))
|
||||
{
|
||||
|
|
@ -1086,8 +1061,6 @@ void LLPipeline::releaseGLBuffers()
|
|||
|
||||
mSceneMap.release();
|
||||
|
||||
mExposureMap.release();
|
||||
|
||||
mPostMap.release();
|
||||
|
||||
for (U32 i = 0; i < 3; i++)
|
||||
|
|
@ -1110,6 +1083,10 @@ void LLPipeline::releaseLUTBuffers()
|
|||
}
|
||||
|
||||
mPbrBrdfLut.release();
|
||||
|
||||
mExposureMap.release();
|
||||
mLastExposure.release();
|
||||
|
||||
}
|
||||
|
||||
void LLPipeline::releaseShadowBuffers()
|
||||
|
|
@ -1286,6 +1263,13 @@ void LLPipeline::createLUTBuffers()
|
|||
|
||||
gDeferredGenBrdfLutProgram.unbind();
|
||||
mPbrBrdfLut.flush();
|
||||
|
||||
mExposureMap.allocate(1, 1, GL_R16F);
|
||||
mExposureMap.bindTarget();
|
||||
mExposureMap.clear();
|
||||
mExposureMap.flush();
|
||||
|
||||
mLastExposure.allocate(1, 1, GL_R16F);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -7407,30 +7391,50 @@ void LLPipeline::renderFinalize()
|
|||
// exposure sample
|
||||
{
|
||||
LL_PROFILE_GPU_ZONE("exposure sample");
|
||||
|
||||
{
|
||||
// copy last frame's exposure into mLastExposure
|
||||
mLastExposure.bindTarget();
|
||||
gCopyProgram.bind();
|
||||
gGL.getTexUnit(0)->bind(&mExposureMap);
|
||||
|
||||
mScreenTriangleVB->setBuffer();
|
||||
mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
|
||||
|
||||
mLastExposure.flush();
|
||||
}
|
||||
|
||||
|
||||
mExposureMap.bindTarget();
|
||||
|
||||
LLGLDepthTest depth(GL_FALSE, GL_FALSE);
|
||||
LLGLEnable blend(GL_BLEND);
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
|
||||
|
||||
gExposureProgram.bind();
|
||||
|
||||
S32 channel = 0;
|
||||
channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screenTarget()->getUsage());
|
||||
channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE);
|
||||
if (channel > -1)
|
||||
{
|
||||
screenTarget()->bindTexture(0, channel, LLTexUnit::TFO_POINT);
|
||||
}
|
||||
|
||||
channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE, screenTarget()->getUsage());
|
||||
channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
|
||||
if (channel > -1)
|
||||
{
|
||||
mGlow[1].bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
|
||||
mGlow[1].bindTexture(0, channel);
|
||||
}
|
||||
|
||||
channel = gExposureProgram.enableTexture(LLShaderMgr::EXPOSURE_MAP);
|
||||
if (channel > -1)
|
||||
{
|
||||
mLastExposure.bindTexture(0, channel);
|
||||
}
|
||||
|
||||
static LLStaticHashedString dt("dt");
|
||||
static LLStaticHashedString noiseVec("noiseVec");
|
||||
gExposureProgram.uniform1f(dt, gFrameIntervalSeconds);
|
||||
|
||||
gExposureProgram.uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0);
|
||||
|
||||
mScreenTriangleVB->setBuffer();
|
||||
mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
|
||||
|
||||
|
|
@ -7562,9 +7566,8 @@ void LLPipeline::renderFinalize()
|
|||
2.f / width * scale_x, 2.f / height * scale_y);
|
||||
|
||||
{
|
||||
// at this point we should pointed at the backbuffer
|
||||
llassert(LLRenderTarget::sCurFBO == 0);
|
||||
|
||||
// at this point we should pointed at the backbuffer (or a snapshot render target)
|
||||
llassert(gSnapshot || LLRenderTarget::sCurFBO == 0);
|
||||
LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
|
||||
S32 depth_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
|
||||
gGL.getTexUnit(depth_channel)->bind(&mRT->deferredScreen, true);
|
||||
|
|
@ -7577,8 +7580,8 @@ void LLPipeline::renderFinalize()
|
|||
}
|
||||
else
|
||||
{
|
||||
// at this point we should pointed at the backbuffer
|
||||
llassert(LLRenderTarget::sCurFBO == 0);
|
||||
// at this point we should pointed at the backbuffer (or a snapshot render target)
|
||||
llassert(gSnapshot || LLRenderTarget::sCurFBO == 0);
|
||||
|
||||
LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
|
||||
|
||||
|
|
|
|||
|
|
@ -679,6 +679,7 @@ public:
|
|||
|
||||
// exposure map for getting average color in scene
|
||||
LLRenderTarget mExposureMap;
|
||||
LLRenderTarget mLastExposure;
|
||||
|
||||
// tonemapped and gamma corrected render ready for post
|
||||
LLRenderTarget mPostMap;
|
||||
|
|
|
|||
Loading…
Reference in New Issue