Skip to content

Commit 9ceacd3

Browse files
committed
SSR cone-mip contact hardening
1 parent de769c3 commit 9ceacd3

11 files changed

Lines changed: 92 additions & 17 deletions

File tree

indra/llinventory/llsettingssky.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,17 @@ LLSettingsSky::validation_list_t LLSettingsSky::validationList()
866866
validation.push_back(Validator(SETTING_AMBIENT_SKY_SATURATION, false, LLSD::TypeReal,
867867
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
868868

869+
validation.push_back(Validator(SETTING_SKY_VERSION, false, LLSD::TypeInteger,
870+
boost::bind(&Validator::verifyIntegerRange, _1, _2, llsd::array(0, (S32)MAX_SKY_SETTINGS_VERSION))));
871+
validation.push_back(Validator(SETTING_SUN_BRIGHTNESS, false, LLSD::TypeReal));
872+
validation.push_back(Validator(SETTING_HDR_OFFSET, false, LLSD::TypeReal));
873+
validation.push_back(Validator(SETTING_HDR_MAX, false, LLSD::TypeReal));
874+
validation.push_back(Validator(SETTING_HDR_MIN, false, LLSD::TypeReal));
875+
validation.push_back(Validator(SETTING_HDR_TONEMAPPER, false, LLSD::TypeInteger,
876+
boost::bind(&Validator::verifyIntegerRange, _1, _2, llsd::array(0, 1))));
877+
validation.push_back(Validator(SETTING_HDR_TONEMAPPER_AMOUNT, false, LLSD::TypeReal,
878+
boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
879+
869880
validation.push_back(Validator(SETTING_RAYLEIGH_CONFIG, true, LLSD::TypeArray, &validateRayleighLayers));
870881
validation.push_back(Validator(SETTING_ABSORPTION_CONFIG, true, LLSD::TypeArray, &validateAbsorptionLayers));
871882
validation.push_back(Validator(SETTING_MIE_CONFIG, true, LLSD::TypeArray, &validateMieLayers));

indra/llrender/llshadermgr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,6 +1321,7 @@ void LLShaderMgr::initAttribsAndUniforms()
13211321
mReservedUniforms.push_back("environmentMap");
13221322
mReservedUniforms.push_back("sceneMap");
13231323
mReservedUniforms.push_back("sceneDepth");
1324+
mReservedUniforms.push_back("ssrConeMipMap");
13241325
mReservedUniforms.push_back("reflectionProbes");
13251326
mReservedUniforms.push_back("irradianceProbes");
13261327
mReservedUniforms.push_back("heroProbes");

indra/llrender/llshadermgr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ class LLShaderMgr
112112
ENVIRONMENT_MAP, // "environmentMap"
113113
SCENE_MAP, // "sceneMap"
114114
SCENE_DEPTH, // "sceneDepth"
115+
SSR_CONE_MIP_MAP, // "ssrConeMipMap"
115116
REFLECTION_PROBES, // "reflectionProbes"
116117
IRRADIANCE_PROBES, // "irradianceProbes"
117118
HERO_PROBE, // "heroProbes"

indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ float random (vec2 uv)
3030
return 0.f;
3131
}
3232

33-
float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, sampler2D source, float glossiness)
33+
float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, out float coneMipOut, sampler2D source, float glossiness)
3434
{
3535
collectedColor = vec4(0);
36+
coneMipOut = 0.0;
3637
return 0.f;
3738
}

indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@ uniform float max_probe_lod;
3636
uniform bool transparent_surface;
3737

3838
uniform float ssrMipScale;
39+
uniform sampler2D ssrConeMipMap;
3940

40-
float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, sampler2D source, float glossiness);
41+
float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, out float coneMipOut, sampler2D source, float glossiness);
4142

4243
uniform int classic_mode;
4344

@@ -822,11 +823,16 @@ void doProbeSample(inout vec3 ambenv, inout vec3 glossenv,
822823

823824
if (transparent)
824825
{
825-
tapScreenSpaceReflection(1, tc, pos.xyz, norm, ssr, sceneMap, glossiness);
826+
float unusedMip;
827+
tapScreenSpaceReflection(1, tc, pos.xyz, norm, ssr, unusedMip, sceneMap, glossiness);
826828
}
827829
else
828830
{
829-
ssr = textureLod(sceneMap, tc, roughness * ssrMipScale);
831+
// Contact hardening: read cone mip from MRT1 for LOD selection,
832+
// sample color+confidence from MRT0 mip chain.
833+
float coneMip = texture(ssrConeMipMap, tc).r * ssrMipScale;
834+
float ssrLod = clamp(coneMip, 0.0, ssrMipScale);
835+
ssr = textureLod(sceneMap, tc, ssrLod);
830836
}
831837

832838
if (ssr.a > 0.001)
@@ -953,11 +959,14 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout
953959

954960
if (transparent)
955961
{
956-
tapScreenSpaceReflection(1, tc, pos.xyz, norm, ssr, sceneMap, glossiness);
962+
float unusedMip;
963+
tapScreenSpaceReflection(1, tc, pos.xyz, norm, ssr, unusedMip, sceneMap, glossiness);
957964
}
958965
else
959966
{
960-
float ssrLod = clamp(log2(1.0 + roughness * roughness * ssrMipScale * 4.0), 0.0, ssrMipScale);
967+
// Contact hardening: read cone mip from MRT1, sample color from MRT0.
968+
float coneMip = texture(ssrConeMipMap, tc).r * ssrMipScale;
969+
float ssrLod = clamp(coneMip, 0.0, ssrMipScale);
961970
ssr = textureLod(sceneMap, tc, ssrLod);
962971
}
963972

indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflAlphaF.glsl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525

2626
/*[EXTRA_CODE_HERE]*/
2727

28-
out vec4 frag_color;
28+
layout(location = 0) out vec4 frag_color;
29+
layout(location = 1) out float frag_cone_mip;
2930

3031
in vec3 vary_position;
3132
in vec3 vary_normal;
@@ -41,7 +42,7 @@ uniform mat4 projection_matrix;
4142
uniform float roughnessFactor;
4243
uniform float minimum_alpha;
4344

44-
float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, sampler2D source, float glossiness);
45+
float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, out float coneMipOut, sampler2D source, float glossiness);
4546
void bayerDitherDiscard(float alpha, float threshold);
4647

4748
void main()
@@ -66,7 +67,9 @@ void main()
6667
vec3 norm = normalize(vary_normal);
6768

6869
vec4 ssrColor = vec4(0.0);
69-
tapScreenSpaceReflection(1, tc, vary_position, norm, ssrColor, sceneMap, glossiness);
70+
float coneMip = 0.0;
71+
tapScreenSpaceReflection(1, tc, vary_position, norm, ssrColor, coneMip, sceneMap, glossiness);
7072
frag_color = ssrColor;
7173
frag_color.a *= alpha;
74+
frag_cone_mip = coneMip;
7275
}

indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ vec4 getPosition(vec2 pos_screen);
4848

4949
float random (vec2 uv);
5050

51-
float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, sampler2D source, float glossiness);
51+
float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, out float coneMipOut, sampler2D source, float glossiness);
5252

5353
void main()
5454
{
@@ -68,8 +68,9 @@ void main()
6868
}
6969

7070
vec4 collectedColor = vec4(0);
71+
float coneMip = 0.0;
7172

72-
float w = tapScreenSpaceReflection(4, tc, pos, gb.normal, collectedColor, diffuseMap, 0.f);
73+
float w = tapScreenSpaceReflection(4, tc, pos, gb.normal, collectedColor, coneMip, diffuseMap, 0.f);
7374

7475
collectedColor.rgb *= specCol.rgb;
7576

indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflTraceF.glsl

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525

2626
/*[EXTRA_CODE_HERE]*/
2727

28-
out vec4 frag_color;
28+
layout(location = 0) out vec4 frag_color;
29+
layout(location = 1) out float frag_cone_mip;
2930

3031
in vec2 vary_fragcoord;
3132
in vec3 camera_ray;
@@ -36,7 +37,7 @@ GBufferInfo getGBuffer(vec2 screenpos);
3637
float getDepth(vec2 pos_screen);
3738
vec4 getPositionWithDepth(vec2 pos_screen, float depth);
3839

39-
float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, sampler2D source, float glossiness);
40+
float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, out float coneMipOut, sampler2D source, float glossiness);
4041

4142
void main()
4243
{
@@ -47,6 +48,7 @@ void main()
4748
if (depth >= 1.0)
4849
{
4950
frag_color = vec4(0.0);
51+
frag_cone_mip = 0.0;
5052
return;
5153
}
5254

@@ -60,6 +62,8 @@ void main()
6062
glossiness = gb.specular.a; // Legacy: a = glossiness
6163

6264
vec4 ssrColor = vec4(0.0);
63-
tapScreenSpaceReflection(1, tc, pos, gb.normal, ssrColor, sceneMap, glossiness);
65+
float coneMip = 0.0;
66+
tapScreenSpaceReflection(1, tc, pos, gb.normal, ssrColor, coneMip, sceneMap, glossiness);
6467
frag_color = ssrColor;
68+
frag_cone_mip = coneMip;
6569
}

indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflUtil.glsl

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ uniform float maxZDepth;
4343
uniform float maxRoughness;
4444
uniform vec2 ssrJitterOffset;
4545
uniform int hizMipCount;
46+
uniform float ssrMipScale;
4647

4748
vec4 getPositionWithDepth(vec2 pos_screen, float depth);
4849

@@ -225,9 +226,11 @@ float tapScreenSpaceReflection(
225226
vec3 viewPos,
226227
vec3 n,
227228
inout vec4 collectedColor,
229+
out float coneMipOut,
228230
sampler2D source,
229231
float glossiness)
230232
{
233+
coneMipOut = 0.0;
231234
float roughness = 1.0 - glossiness;
232235

233236
if (roughness >= maxRoughness)
@@ -271,6 +274,7 @@ float tapScreenSpaceReflection(
271274
int numSamples = max(1, int(glossySampleCount));
272275
vec3 accumColor = vec3(0.0);
273276
float accumFade = 0.0;
277+
float accumConeMip = 0.0;
274278
int hits = 0;
275279

276280
for (int s = 0; s < numSamples; s++)
@@ -398,7 +402,24 @@ float tapScreenSpaceReflection(
398402

399403
float sampleFade = edgeFade * zFade * fadeIn * rayFade * confidence * cameraFacingFade;
400404

405+
// Contact hardening (Godot cone model):
406+
// The roughness defines a reflection cone half-angle. The cone footprint
407+
// on screen grows with ray travel distance. Fit an inscribed sphere in
408+
// the cone to derive a blur radius, then convert to a mip level.
409+
float coneAngle = min(roughness, 0.999) * 3.14159265 * 0.5;
410+
float coneLen = rayLen * max(screen_res.x, screen_res.y); // UV → pixels
411+
float opLen = 2.0 * tan(coneAngle) * coneLen;
412+
float blurRadius = 0.0;
413+
if (coneLen > 0.0)
414+
{
415+
float a2 = opLen * opLen;
416+
float fh2 = 4.0 * coneLen * coneLen;
417+
blurRadius = (opLen * (sqrt(a2 + fh2) - opLen)) / (4.0 * coneLen);
418+
}
419+
float coneMip = log2(blurRadius / 16.0 + 1.0);
420+
401421
accumColor += sampledColor.rgb * sampleFade;
422+
accumConeMip += coneMip * sampleFade;
402423
accumFade += sampleFade;
403424
hits++;
404425
}
@@ -410,10 +431,17 @@ float tapScreenSpaceReflection(
410431
}
411432

412433
accumColor /= float(numSamples);
434+
accumConeMip /= float(numSamples);
413435
accumFade /= float(numSamples);
414436

415437
float combinedFade = accumFade * baseEdgeFade;
416438

439+
// Cone mip: weighted average, normalized to [0,1] for storage in MRT1.
440+
float avgConeMip = (accumFade > 0.001) ? accumConeMip / accumFade : 0.0;
441+
coneMipOut = clamp(avgConeMip / max(ssrMipScale, 1.0), 0.0, 1.0);
442+
443+
// RGB: color premultiplied by confidence (for correct mip chain filtering).
444+
// A: confidence (restored — used for premultiply recovery + occlusion blending).
417445
collectedColor = vec4(accumColor * baseEdgeFade, combinedFade);
418446
return 1.0;
419447
}

indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflWaterF.glsl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525

2626
/*[EXTRA_CODE_HERE]*/
2727

28-
out vec4 frag_color;
28+
layout(location = 0) out vec4 frag_color;
29+
layout(location = 1) out float frag_cone_mip;
2930

3031
uniform sampler2D bumpMap;
3132
uniform sampler2D bumpMap2;
@@ -42,7 +43,7 @@ in vec3 vary_position;
4243
in vec3 vary_normal;
4344
in vec3 vary_tangent;
4445

45-
float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, sampler2D source, float glossiness);
46+
float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, out float coneMipOut, sampler2D source, float glossiness);
4647

4748
uniform sampler2D sceneMap;
4849

@@ -92,6 +93,8 @@ void main()
9293
vec2 tc = (projPos.xy / projPos.w) * 0.5 + 0.5;
9394

9495
vec4 ssrColor = vec4(0.0);
95-
tapScreenSpaceReflection(1, tc, vary_position, wave_ibl, ssrColor, sceneMap, glossiness);
96+
float coneMip = 0.0;
97+
tapScreenSpaceReflection(1, tc, vary_position, wave_ibl, ssrColor, coneMip, sceneMap, glossiness);
9698
frag_color = ssrColor;
99+
frag_cone_mip = coneMip;
97100
}

0 commit comments

Comments
 (0)