From fad8e126677034ec84733a3cc3020fa9e6aff076 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sat, 13 Dec 2025 20:52:36 -0600 Subject: [PATCH 1/5] take ibl amount into account for translucent opacity --- Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp | 6 +++--- Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp | 6 +++--- .../BaseGame/game/core/rendering/shaders/gl/lighting.glsl | 5 +++-- .../BaseGame/game/core/rendering/shaders/lighting.hlsl | 5 +++-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp index 548eb0217..6c545b40f 100644 --- a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp +++ b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp @@ -3055,7 +3055,7 @@ void ReflectionProbeFeatGLSL::processPix(Vector& componentList Var *ibl = (Var *)LangElement::find("ibl"); if (!ibl) { - ibl = new Var("ibl", "float3"); + ibl = new Var("ibl", "float4"); } Var* eyePos = (Var*)LangElement::find("eyePosWorld"); @@ -3086,7 +3086,7 @@ void ReflectionProbeFeatGLSL::processPix(Vector& componentList //Reflection vec String computeForwardProbes = String(" @ = computeForwardProbes(@,@,@,@,@,@,@,@,@,\r\n\t\t"); computeForwardProbes += String("@,@,@,@,@,@,\r\n\t\t"); - computeForwardProbes += String("@,@).rgb; \r\n"); + computeForwardProbes += String("@,@); \r\n"); meta->addStatement(new GenOp(computeForwardProbes.c_str(), new DecOp(ibl), surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray, eyePos, skylightCubemapIdx, SkylightDamp, BRDFTexture, WetnessTexture, accumTime, dampness, @@ -3100,7 +3100,7 @@ void ReflectionProbeFeatGLSL::processPix(Vector& componentList ambient->constSortPos = cspPass; } meta->addStatement(new GenOp(" @.rgb *= @.rgb;\r\n", ibl, ambient)); - meta->addStatement(new GenOp(" @.rgb = @.rgb;\r\n", curColor, ibl)); + meta->addStatement(new GenOp(" @ = @;\r\n", curColor, ibl)); output = meta; } diff --git a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp index d65cced8f..9d6ea1923 100644 --- a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp +++ b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp @@ -3143,7 +3143,7 @@ void ReflectionProbeFeatHLSL::processPix(Vector &componentList Var* ibl = (Var*)LangElement::find("ibl"); if (!ibl) { - ibl = new Var("ibl", "float3"); + ibl = new Var("ibl", "float4"); } Var* eyePos = (Var*)LangElement::find("eyePosWorld"); @@ -3174,7 +3174,7 @@ void ReflectionProbeFeatHLSL::processPix(Vector &componentList String computeForwardProbes = String(" @ = computeForwardProbes(@,@,@,@,@,@,@,@,@,\r\n\t\t"); computeForwardProbes += String("@,@,TORQUE_SAMPLER2D_MAKEARG(@),TORQUE_SAMPLER2D_MAKEARG(@), @, @,\r\n\t\t"); - computeForwardProbes += String("TORQUE_SAMPLERCUBEARRAY_MAKEARG(@),TORQUE_SAMPLERCUBEARRAY_MAKEARG(@)).rgb; \r\n"); + computeForwardProbes += String("TORQUE_SAMPLERCUBEARRAY_MAKEARG(@),TORQUE_SAMPLERCUBEARRAY_MAKEARG(@)); \r\n"); meta->addStatement(new GenOp(computeForwardProbes.c_str(), new DecOp(ibl), surface, cubeMips, numProbes, worldToObjArray, probeConfigData, inProbePosArray, refScaleArray, inRefPosArray, eyePos, skylightCubemapIdx, SkylightDamp, BRDFTexture, WetnessTexture, accumTime, dampness, @@ -3188,7 +3188,7 @@ void ReflectionProbeFeatHLSL::processPix(Vector &componentList ambient->constSortPos = cspPass; } meta->addStatement(new GenOp(" @.rgb *= @.rgb;\r\n", ibl, ambient)); - meta->addStatement(new GenOp(" @.rgb = @.rgb;\r\n", curColor, ibl)); + meta->addStatement(new GenOp(" @ = @;\r\n", curColor, ibl)); output = meta; } diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl index 5e0caa346..3daeb12c7 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl @@ -605,10 +605,11 @@ vec4 computeForwardProbes(Surface surface, finalColor *= surface.ao; if(isCapturing == 1) - return vec4(lerp((finalColor), surface.baseColor.rgb,surface.metalness),0); + return vec4(lerp((finalColor), surface.baseColor.rgb,surface.metalness),surface.baseColor.a); else { - return vec4(finalColor, 0); + float reflectionOpacity = min(max(surface.baseColor.a,length(specular+irradiance)),1.0); + return vec4(finalColor, reflectionOpacity); } } diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl index 8a4c5be23..fc0abf7a1 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl @@ -610,10 +610,11 @@ float4 computeForwardProbes(Surface surface, finalColor *= surface.ao; if(isCapturing == 1) - return float4(lerp((finalColor), surface.baseColor.rgb,surface.metalness),0); + return float4(lerp((finalColor), surface.baseColor.rgb,surface.metalness),surface.baseColor.a); else { - return float4(finalColor, 0); + float reflectionOpacity = min(max(surface.baseColor.a,length(specular+irradiance)),1.0); + return float4(finalColor, reflectionOpacity); } } From 2199fb688171ad7d48ffdaf72d7e7adf557ba0c1 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sun, 14 Dec 2025 02:29:31 -0600 Subject: [PATCH 2/5] use a nonlinear reflectionopacity curve, and the greater of metalness or reflectionopacity for ibl overtaking albedo --- .../game/core/rendering/shaders/gl/lighting.glsl | 9 +++++---- .../game/core/rendering/shaders/lighting.hlsl | 13 +++++++------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl index 3daeb12c7..35940b5a1 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl @@ -592,9 +592,11 @@ vec4 computeForwardProbes(Surface surface, specular = mix(specular,textureLod(specularCubemapAR, vec4(surface.R, skylightCubemapIdx), lod).xyz, alpha); } + float reflectionOpacity = clamp(surface.baseColor.a, pow(max(length(specular),length(irradiance)),2.2),1.0); + float reflectionInfluence = max(surface.metalness, reflectionOpacity); vec2 envBRDF = textureLod(BRDFTexture, vec2(surface.NdotV, surface.roughness),0).rg; - vec3 diffuse = irradiance * lerp(surface.baseColor.rgb, vec3(0.04f,0.04f,0.04f), surface.metalness); - vec3 specularCol = ((specular * surface.baseColor.rgb) * envBRDF.x + envBRDF.y)*surface.metalness; + vec3 diffuse = irradiance * lerp(surface.baseColor.rgb, vec3(0.04f,0.04f,0.04f), reflectionInfluence); + vec3 specularCol = ((specular * surface.baseColor.rgb) * envBRDF.x + envBRDF.y)*reflectionInfluence; float horizonOcclusion = 1.3; float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N)); @@ -608,8 +610,7 @@ vec4 computeForwardProbes(Surface surface, return vec4(lerp((finalColor), surface.baseColor.rgb,surface.metalness),surface.baseColor.a); else { - float reflectionOpacity = min(max(surface.baseColor.a,length(specular+irradiance)),1.0); - return vec4(finalColor, reflectionOpacity); + return vec4(finalColor, reflectionInfluence); } } diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl index fc0abf7a1..25c9f446c 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl @@ -597,24 +597,25 @@ float4 computeForwardProbes(Surface surface, specular = lerp(specular,TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, surface.R, skylightCubemapIdx, lod).xyz,alpha); } + float reflectionOpacity = clamp(surface.baseColor.a, pow(max(length(specular),length(irradiance)),2.2),1.0); + float reflectionInfluence = max(surface.metalness, reflectionOpacity); float2 envBRDF = TORQUE_TEX2DLOD(BRDFTexture, float4(surface.NdotV, surface.roughness,0,0)).rg; - float3 diffuse = irradiance * lerp(surface.baseColor.rgb, 0.04f, surface.metalness); - float3 specularCol = ((specular * surface.baseColor.rgb) * envBRDF.x + envBRDF.y)*surface.metalness; + float3 diffuse = irradiance * lerp(surface.baseColor.rgb, 0.04f, reflectionInfluence); + float3 specularCol = ((specular * surface.baseColor.rgb) * envBRDF.x + envBRDF.y)*reflectionInfluence; float horizonOcclusion = 1.3; float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N)); horizon *= horizon; // Final color output after environment lighting - float3 finalColor = diffuse + specularCol; + float3 finalColor = diffuse + specularCol* horizon; finalColor *= surface.ao; if(isCapturing == 1) - return float4(lerp((finalColor), surface.baseColor.rgb,surface.metalness),surface.baseColor.a); + return float4(lerp((finalColor), surface.baseColor.rgb, surface.metalness),surface.baseColor.a); else { - float reflectionOpacity = min(max(surface.baseColor.a,length(specular+irradiance)),1.0); - return float4(finalColor, reflectionOpacity); + return float4(finalColor, reflectionInfluence); } } From f00b1d955f62d6e457e440b41f349142582e2de8 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sun, 14 Dec 2025 12:40:19 -0600 Subject: [PATCH 3/5] revisions to ensure high saturation reflections overtake albedo --- .../game/core/rendering/shaders/gl/lighting.glsl | 11 +++++++---- .../game/core/rendering/shaders/lighting.hlsl | 9 ++++++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl index 35940b5a1..2292d3f23 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl @@ -592,11 +592,14 @@ vec4 computeForwardProbes(Surface surface, specular = mix(specular,textureLod(specularCubemapAR, vec4(surface.R, skylightCubemapIdx), lod).xyz, alpha); } - float reflectionOpacity = clamp(surface.baseColor.a, pow(max(length(specular),length(irradiance)),2.2),1.0); - float reflectionInfluence = max(surface.metalness, reflectionOpacity); + float reflectionOpacity = clamp(surface.baseColor.a, max(length(specular),length(irradiance)),1.0); + float reflectionInfluence = max(surface.metalness, reflectionOpacity); + surface.metalness = reflectionInfluence; + surface.baseColor.rgb = lerp(surface.baseColor.rgb, vec3(1.0,1.0,1.0), reflectionInfluence); + updateSurface(surface); vec2 envBRDF = textureLod(BRDFTexture, vec2(surface.NdotV, surface.roughness),0).rg; - vec3 diffuse = irradiance * lerp(surface.baseColor.rgb, vec3(0.04f,0.04f,0.04f), reflectionInfluence); - vec3 specularCol = ((specular * surface.baseColor.rgb) * envBRDF.x + envBRDF.y)*reflectionInfluence; + vec3 diffuse = irradiance * lerp(surface.baseColor.rgb, vec3(0.04f,0.04f,0.04f), surface.metalness); + vec3 specularCol = ((specular * surface.f0) * envBRDF.x + envBRDF.y)*surface.metalness; float horizonOcclusion = 1.3; float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N)); diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl index 25c9f446c..6c646ad91 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl @@ -597,11 +597,14 @@ float4 computeForwardProbes(Surface surface, specular = lerp(specular,TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, surface.R, skylightCubemapIdx, lod).xyz,alpha); } - float reflectionOpacity = clamp(surface.baseColor.a, pow(max(length(specular),length(irradiance)),2.2),1.0); + float reflectionOpacity = clamp(surface.baseColor.a, max(length(specular),length(irradiance)),1.0); float reflectionInfluence = max(surface.metalness, reflectionOpacity); + surface.metalness = reflectionInfluence; + surface.baseColor.rgb = lerp(surface.baseColor.rgb, float3(1.0,1.0,1.0), reflectionInfluence); + surface.Update(); float2 envBRDF = TORQUE_TEX2DLOD(BRDFTexture, float4(surface.NdotV, surface.roughness,0,0)).rg; - float3 diffuse = irradiance * lerp(surface.baseColor.rgb, 0.04f, reflectionInfluence); - float3 specularCol = ((specular * surface.baseColor.rgb) * envBRDF.x + envBRDF.y)*reflectionInfluence; + float3 diffuse = irradiance * lerp(surface.baseColor.rgb, 0.04f, surface.metalness); + float3 specularCol = ((specular * surface.f0) * envBRDF.x + envBRDF.y)*surface.metalness; float horizonOcclusion = 1.3; float horizon = saturate( 1 + horizonOcclusion * dot(surface.R, surface.N)); From 5893355d0a13fd4a419abe07704ddfac97cd35e7 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sun, 14 Dec 2025 14:01:48 -0600 Subject: [PATCH 4/5] simplify calcs, account for roughness for better defered vs translucent pairing outcomes when fed textures --- .../BaseGame/game/core/rendering/shaders/gl/lighting.glsl | 6 ++---- .../BaseGame/game/core/rendering/shaders/lighting.hlsl | 7 ++----- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl index 2292d3f23..8c4df444e 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl @@ -593,9 +593,7 @@ vec4 computeForwardProbes(Surface surface, } float reflectionOpacity = clamp(surface.baseColor.a, max(length(specular),length(irradiance)),1.0); - float reflectionInfluence = max(surface.metalness, reflectionOpacity); - surface.metalness = reflectionInfluence; - surface.baseColor.rgb = lerp(surface.baseColor.rgb, vec3(1.0,1.0,1.0), reflectionInfluence); + surface.baseColor.rgb = lerp(surface.baseColor.rgb, vec3(1.0,1.0,1.0), reflectionOpacity*surface.roughness); updateSurface(surface); vec2 envBRDF = textureLod(BRDFTexture, vec2(surface.NdotV, surface.roughness),0).rg; vec3 diffuse = irradiance * lerp(surface.baseColor.rgb, vec3(0.04f,0.04f,0.04f), surface.metalness); @@ -613,7 +611,7 @@ vec4 computeForwardProbes(Surface surface, return vec4(lerp((finalColor), surface.baseColor.rgb,surface.metalness),surface.baseColor.a); else { - return vec4(finalColor, reflectionInfluence); + return vec4(finalColor, reflectionOpacity); } } diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl index 6c646ad91..dcdc12d4a 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl @@ -596,11 +596,8 @@ float4 computeForwardProbes(Surface surface, irradiance = lerp(irradiance,TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, surface.N, skylightCubemapIdx, 0).xyz,alpha); specular = lerp(specular,TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, surface.R, skylightCubemapIdx, lod).xyz,alpha); } - float reflectionOpacity = clamp(surface.baseColor.a, max(length(specular),length(irradiance)),1.0); - float reflectionInfluence = max(surface.metalness, reflectionOpacity); - surface.metalness = reflectionInfluence; - surface.baseColor.rgb = lerp(surface.baseColor.rgb, float3(1.0,1.0,1.0), reflectionInfluence); + surface.baseColor.rgb = lerp(surface.baseColor.rgb, float3(1.0,1.0,1.0), reflectionOpacity*surface.roughness); surface.Update(); float2 envBRDF = TORQUE_TEX2DLOD(BRDFTexture, float4(surface.NdotV, surface.roughness,0,0)).rg; float3 diffuse = irradiance * lerp(surface.baseColor.rgb, 0.04f, surface.metalness); @@ -618,7 +615,7 @@ float4 computeForwardProbes(Surface surface, return float4(lerp((finalColor), surface.baseColor.rgb, surface.metalness),surface.baseColor.a); else { - return float4(finalColor, reflectionInfluence); + return float4(finalColor, reflectionOpacity); } } From 681caf9392371b8b9dee0292c43f119b0aedb58c Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sun, 14 Dec 2025 15:33:30 -0600 Subject: [PATCH 5/5] brdf calc fixes from mar, rake roughness into account for translucent reflections --- .../game/core/rendering/shaders/gl/lighting.glsl | 8 +++++--- .../BaseGame/game/core/rendering/shaders/lighting.hlsl | 9 ++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl index 8c4df444e..7ded966fe 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl @@ -226,9 +226,11 @@ float getDistanceAtt( vec3 unormalizedLightVector , float invSqrAttRadius ) vec3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight) { + if (surface.depth >= 0.9999f) + return float3(0.0,0.0,0.0); + // Compute Fresnel term vec3 F = F_Schlick(surface.f0, surfaceToLight.HdotV); - F += lerp(vec3(0.04f,0.04f,0.04f), surface.baseColor.rgb, surface.metalness); // GGX Normal Distribution Function float D = D_GGX(surfaceToLight.NdotH, surface.linearRoughness); @@ -592,8 +594,8 @@ vec4 computeForwardProbes(Surface surface, specular = mix(specular,textureLod(specularCubemapAR, vec4(surface.R, skylightCubemapIdx), lod).xyz, alpha); } - float reflectionOpacity = clamp(surface.baseColor.a, max(length(specular),length(irradiance)),1.0); - surface.baseColor.rgb = lerp(surface.baseColor.rgb, vec3(1.0,1.0,1.0), reflectionOpacity*surface.roughness); + float reflectionOpacity = clamp(surface.baseColor.a, max(length(specular),length(irradiance))*surface.roughness,1.0); + surface.baseColor.rgb = lerp(surface.baseColor.rgb, vec3(reflectionOpacity,reflectionOpacity,reflectionOpacity), surface.roughness); updateSurface(surface); vec2 envBRDF = textureLod(BRDFTexture, vec2(surface.NdotV, surface.roughness),0).rg; vec3 diffuse = irradiance * lerp(surface.baseColor.rgb, vec3(0.04f,0.04f,0.04f), surface.metalness); diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl index dcdc12d4a..41181b894 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl @@ -226,9 +226,11 @@ float getDistanceAtt( float3 unormalizedLightVector , float invSqrAttRadius ) float3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight) { + if (surface.depth >= 0.9999f) + return float3(0.0,0.0,0.0); + // Compute Fresnel term float3 F = F_Schlick(surface.f0, surfaceToLight.HdotV); - F += lerp(0.04f, surface.baseColor.rgb, surface.metalness); // GGX Normal Distribution Function float D = D_GGX(surfaceToLight.NdotH, surface.linearRoughness); @@ -596,8 +598,9 @@ float4 computeForwardProbes(Surface surface, irradiance = lerp(irradiance,TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, surface.N, skylightCubemapIdx, 0).xyz,alpha); specular = lerp(specular,TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, surface.R, skylightCubemapIdx, lod).xyz,alpha); } - float reflectionOpacity = clamp(surface.baseColor.a, max(length(specular),length(irradiance)),1.0); - surface.baseColor.rgb = lerp(surface.baseColor.rgb, float3(1.0,1.0,1.0), reflectionOpacity*surface.roughness); + + float reflectionOpacity = clamp(surface.baseColor.a, max(length(specular),length(irradiance))*surface.roughness,1.0); + surface.baseColor.rgb = lerp(surface.baseColor.rgb, float3(reflectionOpacity,reflectionOpacity,reflectionOpacity), surface.roughness); surface.Update(); float2 envBRDF = TORQUE_TEX2DLOD(BRDFTexture, float4(surface.NdotV, surface.roughness,0,0)).rg; float3 diffuse = irradiance * lerp(surface.baseColor.rgb, 0.04f, surface.metalness);