summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2025-11-11 16:45:24 -0800
committeryum <yum.food.vr@gmail.com>2025-11-11 16:45:24 -0800
commitaf1d995a9ea92de599caae0977c0a43ee4c27140 (patch)
tree53d737762091ff9213c7a173d6507b9c3e7b398d
parentfb48528cbb1881ff8ac96a1cd05c2c7aa326b203 (diff)
fix rough material energy compensation
-rw-r--r--brdf.cginc28
1 files changed, 18 insertions, 10 deletions
diff --git a/brdf.cginc b/brdf.cginc
index 8352c08..1cb4d33 100644
--- a/brdf.cginc
+++ b/brdf.cginc
@@ -136,6 +136,17 @@ float4 brdf(Pbr pbr, LightData data) {
data.direct.LoH = 1;
#endif
+ float2 dfg_uv = float2(pbr.roughness, data.common.NoV);
+ float3 dfg;
+ [branch]
+ if (textureExists(_DFG_LUT)) {
+ dfg = _DFG_LUT.SampleLevel(bilinear_clamp_s, dfg_uv, 0).rgb;
+ } else {
+ dfg = float3(1, 1, 1);
+ }
+
+ float3 F0_color = lerp(float3(f0, f0, f0), pbr.albedo.xyz, pbr.metallic);
+
// Direct
{
float3 remainder = 1.0f;
@@ -169,8 +180,13 @@ float4 brdf(Pbr pbr, LightData data) {
float G = G_GGXSmith(pbr.roughness, data.direct.NoL, data.common.NoV);
float FDG = F * D * G;
+ FDG = FDG * dfg.x + dfg.y;
float3 direct_specular = FDG * remainder * data.direct.color * data.direct.NoL * lerp(1.0f, pbr.albedo.xyz, pbr.metallic);
+ float Ess = max(dfg.y, 1e-4f);
+ float invEss = rcp(Ess);
+ float3 energy_comp = 1.0f + F0_color * (invEss - 1.0f);
+ direct_specular *= energy_comp;
direct_specular = max(0, direct_specular);
specular += direct_specular;
remainder = saturate(remainder - direct_specular);
@@ -182,10 +198,9 @@ float4 brdf(Pbr pbr, LightData data) {
}
// Indirect
-#if defined(FORWARD_BASE_PASS)
+#if !defined(FURNACE_TEST_DIRECT) && defined(FORWARD_BASE_PASS)
{
float3 remainder = 1.0f;
- float2 dfg_uv = float2(pbr.roughness, data.common.NoV);
#if defined(_CLEARCOAT)
float cc_f0 = 0.04f;
@@ -207,13 +222,6 @@ float4 brdf(Pbr pbr, LightData data) {
// Standard PBR IBL using split-sum approximation
// Specular lobe
- float2 dfg;
- [branch]
- if (textureExists(_DFG_LUT)) {
- dfg = _DFG_LUT.SampleLevel(bilinear_clamp_s, dfg_uv, 0).rg;
- } else {
- dfg = float2(0, 1);
- }
float3 f0_spec = lerp(f0, pbr.albedo.xyz, pbr.metallic);
float3 ibl_specular_reflectance = f0_spec * dfg.x + dfg.y;
float3 indirect_specular = data.indirect.specular * ibl_specular_reflectance;
@@ -223,7 +231,7 @@ float4 brdf(Pbr pbr, LightData data) {
const float F = F_Schlick(data.indirect.NoL, f0_spec, f90);
specular += surface_reduction * indirect_specular * F;
remainder -= F;
-
+
// Diffuse is Lambertian, which is pre-integrated into the SH diffuse probe
float3 indirect_diffuse = pbr.albedo.xyz * data.indirect.diffuse * remainder * (1.0 - pbr.metallic);
diffuse += indirect_diffuse;