DRTVWR-559 Fix for irradiance maps going black at 128x128 radiance map resolution. Improve radiance map anti-aliasing and default to 128x128 everywhere.

master
Dave Parks 2023-02-23 11:47:24 -06:00
parent 93a82d4b75
commit e5e94b5fa8
10 changed files with 121 additions and 102 deletions

View File

@ -10391,7 +10391,7 @@
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>256</integer>
<integer>128</integer>
</map>
<key>RenderReflectionProbeAmbianceScale</key>
<map>

View File

@ -0,0 +1,53 @@
/**
* @file gaussianF.glsl
*
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2023, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
out vec4 frag_color;
uniform sampler2D diffuseRect;
uniform float resScale;
// texture direction, will be <1, 0> or <0, 1>
uniform vec2 direction;
in vec2 vary_texcoord0;
// get linear depth value given a depth buffer sample d and znear and zfar values
float linearDepth(float d, float znear, float zfar);
void main()
{
vec3 col = vec3(0,0,0);
float w[] = { 0.0002, 0.0060, 0.0606, 0.2417, 0.3829, 0.2417, 0.0606, 0.0060, 0.0002 };
for (int i = 0; i < 9; ++i)
{
vec2 tc = vary_texcoord0 + (i-4)*direction*resScale;
col += texture(diffuseRect, tc).rgb * w[i];
}
frag_color = vec4(col, 0.0);
}

View File

@ -23,18 +23,8 @@
* $/LicenseInfo$
*/
#extension GL_ARB_texture_rectangle : enable
/*[EXTRA_CODE_HERE]*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
// NOTE screenMap should always be texture channel 0 and
// depthmap should always be channel 1
uniform sampler2D diffuseRect;
uniform sampler2D depthMap;
@ -42,48 +32,13 @@ uniform float resScale;
uniform float znear;
uniform float zfar;
VARYING vec2 vary_texcoord0;
in vec2 vary_texcoord0;
// get linear depth value given a depth buffer sample d and znear and zfar values
float linearDepth(float d, float znear, float zfar);
void main()
{
#if 0
float w[9];
float c = 1.0/16.0; //corner weight
float e = 1.0/8.0; //edge weight
float m = 1.0/4.0; //middle weight
//float wsum = c*4+e*4+m;
w[0] = c; w[1] = e; w[2] = c;
w[3] = e; w[4] = m; w[5] = e;
w[6] = c; w[7] = e; w[8] = c;
vec2 tc[9];
float ed = 1;
float cd = 1;
tc[0] = vec2(-cd, cd); tc[1] = vec2(0, ed); tc[2] = vec2(cd, cd);
tc[3] = vec2(-ed, 0); tc[4] = vec2(0, 0); tc[5] = vec2(ed, 0);
tc[6] = vec2(-cd, -cd); tc[7] = vec2(0, -ed); tc[8] = vec2(cd, -1);
vec3 color = vec3(0,0,0);
for (int i = 0; i < 9; ++i)
{
color += texture2D(screenMap, vary_texcoord0.xy+tc[i]).rgb * w[i];
//color += texture2D(screenMap, vary_texcoord0.xy+tc[i]*2.0).rgb * w[i]*0.5;
}
//color /= wsum;
frag_color = vec4(color, 1.0);
#else
float depth = texture(depthMap, vary_texcoord0.xy).r;
float dist = linearDepth(depth, znear, zfar);
@ -94,7 +49,6 @@ void main()
v = normalize(v);
dist /= v.z;
vec3 col = texture2D(diffuseRect, vary_texcoord0.xy).rgb;
frag_color = vec4(col, dist/256.0);
#endif
vec3 col = texture(diffuseRect, vary_texcoord0.xy).rgb;
frag_color = vec4(col, dist/256.0);
}

View File

@ -25,17 +25,16 @@
uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
ATTRIBUTE vec2 texcoord0;
ATTRIBUTE vec4 diffuse_color;
in vec3 position;
in vec4 diffuse_color;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
out vec4 vertex_color;
out vec2 vary_texcoord0;
void main()
{
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
vary_texcoord0 = texcoord0;
vary_texcoord0 = position.xy*0.5+0.5;
vertex_color = diffuse_color;
}

View File

@ -176,7 +176,6 @@ float computeLod(float pdf)
vec4 filterColor(vec3 N)
{
//return textureLod(uCubeMap, N, 3.0).rgb;
vec4 color = vec4(0.f);
for(int i = 0; i < u_sampleCount; ++i)
@ -192,7 +191,7 @@ vec4 filterColor(vec3 N)
// apply the bias to the lod
lod += u_lodBias;
lod = clamp(lod, 0, 7);
lod = clamp(lod, 0, max_probe_lod);
// sample lambertian at a lower resolution to avoid fireflies
vec4 lambertian = textureLod(reflectionProbes, vec4(H, sourceIdx), lod);

View File

@ -1,4 +1,4 @@
version 48
version 49
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@ -71,7 +71,7 @@ RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
RenderGLContextCoreProfile 1 1
RenderGLMultiThreaded 1 0
RenderReflectionProbeResolution 1 256
RenderReflectionProbeResolution 1 128
RenderScreenSpaceReflections 1 1
@ -279,12 +279,6 @@ RenderUseAdvancedAtmospherics 1 0
list VRAMGT512
RenderCompressTextures 1 0
//
// VRAM < 2GB
//
list VRAMLT2GB
RenderReflectionProbeResolution 1 128
//
// "Default" setups for safe, low, medium, high
//

View File

@ -95,7 +95,7 @@ void LLReflectionMapManager::update()
if (!mRenderTarget.isComplete())
{
U32 color_fmt = GL_RGB16;
U32 targetRes = mProbeResolution * 2; // super sample
U32 targetRes = mProbeResolution * 4; // super sample
mRenderTarget.allocate(targetRes, targetRes, color_fmt, true);
}
@ -502,8 +502,6 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
// downsample to placeholder map
{
gReflectionMipProgram.bind();
gGL.matrixMode(gGL.MM_MODELVIEW);
gGL.pushMatrix();
gGL.loadIdentity();
@ -515,21 +513,50 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
gGL.flush();
U32 res = mProbeResolution * 2;
S32 mips = log2((F32)mProbeResolution) + 0.5f;
S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE);
S32 depthChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_TEXTURE);
static LLStaticHashedString resScale("resScale");
static LLStaticHashedString direction("direction");
static LLStaticHashedString znear("znear");
static LLStaticHashedString zfar("zfar");
LLRenderTarget* screen_rt = &gPipeline.mAuxillaryRT.screen;
LLRenderTarget* depth_rt = &gPipeline.mAuxillaryRT.deferredScreen;
// perform a gaussian blur on the super sampled render before downsampling
{
gGaussianProgram.bind();
gGaussianProgram.uniform1f(resScale, 1.f / (mProbeResolution * 2));
S32 diffuseChannel = gGaussianProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE);
// horizontal
gGaussianProgram.uniform2f(direction, 1.f, 0.f);
gGL.getTexUnit(diffuseChannel)->bind(screen_rt);
mRenderTarget.bindTarget();
gPipeline.mScreenTriangleVB->setBuffer();
gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
mRenderTarget.flush();
// vertical
gGaussianProgram.uniform2f(direction, 0.f, 1.f);
gGL.getTexUnit(diffuseChannel)->bind(&mRenderTarget);
screen_rt->bindTarget();
gPipeline.mScreenTriangleVB->setBuffer();
gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
screen_rt->flush();
}
S32 mips = log2((F32)mProbeResolution) + 0.5f;
gReflectionMipProgram.bind();
S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE);
S32 depthChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_TEXTURE);
for (int i = 0; i < mMipChain.size(); ++i)
{
LL_PROFILE_GPU_ZONE("probe mip");
mMipChain[i].bindTarget();
if (i == 0)
{
gGL.getTexUnit(diffuseChannel)->bind(screen_rt);
}
else
@ -539,30 +566,13 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
gGL.getTexUnit(depthChannel)->bind(depth_rt, true);
static LLStaticHashedString resScale("resScale");
static LLStaticHashedString znear("znear");
static LLStaticHashedString zfar("zfar");
gReflectionMipProgram.uniform1f(resScale, (F32) (1 << i));
gReflectionMipProgram.uniform1f(resScale, 1.f/(mProbeResolution*2));
gReflectionMipProgram.uniform1f(znear, probe->getNearClip());
gReflectionMipProgram.uniform1f(zfar, MAX_FAR_CLIP);
gGL.begin(gGL.QUADS);
gGL.texCoord2f(0, 0);
gGL.vertex2f(-1, -1);
gGL.texCoord2f(1.f, 0);
gGL.vertex2f(1, -1);
gGL.texCoord2f(1.f, 1.f);
gGL.vertex2f(1, 1);
gGL.texCoord2f(0, 1.f);
gGL.vertex2f(-1, 1);
gGL.end();
gGL.flush();
gPipeline.mScreenTriangleVB->setBuffer();
gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
res /= 2;
S32 mip = i - (mMipChain.size() - mips);

View File

@ -73,6 +73,7 @@ LLGLSLShader gSkinnedOcclusionProgram;
LLGLSLShader gOcclusionCubeProgram;
LLGLSLShader gGlowCombineProgram;
LLGLSLShader gReflectionMipProgram;
LLGLSLShader gGaussianProgram;
LLGLSLShader gRadianceGenProgram;
LLGLSLShader gIrradianceGenProgram;
LLGLSLShader gGlowCombineFXAAProgram;
@ -3185,12 +3186,20 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
gReflectionMipProgram.mShaderFiles.push_back(make_pair("interface/reflectionmipF.glsl", GL_FRAGMENT_SHADER));
gReflectionMipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gReflectionMipProgram.createShader(NULL, NULL);
if (success)
{
gReflectionMipProgram.bind();
gReflectionMipProgram.uniform1i(sScreenMap, 0);
gReflectionMipProgram.unbind();
}
}
if (success)
{
gGaussianProgram.mName = "Reflection Mip Shader";
gGaussianProgram.mFeatures.isDeferred = true;
gGaussianProgram.mFeatures.hasGamma = true;
gGaussianProgram.mFeatures.hasAtmospherics = true;
gGaussianProgram.mFeatures.calculatesAtmospherics = true;
gGaussianProgram.mShaderFiles.clear();
gGaussianProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER));
gGaussianProgram.mShaderFiles.push_back(make_pair("interface/gaussianF.glsl", GL_FRAGMENT_SHADER));
gGaussianProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gGaussianProgram.createShader(NULL, NULL);
}
if (success && gGLManager.mHasCubeMapArray)

View File

@ -151,6 +151,7 @@ extern LLGLSLShader gOcclusionProgram;
extern LLGLSLShader gOcclusionCubeProgram;
extern LLGLSLShader gGlowCombineProgram;
extern LLGLSLShader gReflectionMipProgram;
extern LLGLSLShader gGaussianProgram;
extern LLGLSLShader gRadianceGenProgram;
extern LLGLSLShader gIrradianceGenProgram;
extern LLGLSLShader gGlowCombineFXAAProgram;

View File

@ -802,7 +802,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
gCubeSnapshot = TRUE;
mReflectionMapManager.initReflectionMaps();
mRT = &mAuxillaryRT;
U32 res = mReflectionMapManager.mProbeResolution * 2; //multiply by 2 because probes will be super sampled
U32 res = mReflectionMapManager.mProbeResolution * 4; //multiply by 4 because probes will be 16x super sampled
allocateScreenBuffer(res, res, samples);
mRT = &mMainRT;
gCubeSnapshot = FALSE;