summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2025-11-11 19:47:11 -0800
committeryum <yum.food.vr@gmail.com>2025-11-11 19:47:11 -0800
commitc88f634f9bfcb51cd116fc73147f44a0273d43a9 (patch)
tree787abdfb318f31f0b8c16d07e7d6bef2dd4e8594
parent3e9d00aaf3bdaa23ee5f762c85273de70c993fe5 (diff)
more brdf twiddling
-rw-r--r--brdf.cginc35
1 files changed, 21 insertions, 14 deletions
diff --git a/brdf.cginc b/brdf.cginc
index 804cfe9..70bca86 100644
--- a/brdf.cginc
+++ b/brdf.cginc
@@ -7,17 +7,26 @@
#include "lysenko.cginc"
#include "math.cginc"
+float pow5(float x) {
+ float x2 = x * x;
+ return x2 * x2 * x;
+}
+
// Schlick "An Inexpensive BRDF Model for Physically-based Rendering".
// Equation 24.
// f0: Reflectance at normal incidence. Typically around 0.04.
// f90: Reflectance at grazing incidence. Typically around 1.0.
float F_Schlick(float LoH, float f0, float f90) {
- float term = 1.0f - LoH;
- float term2 = term * term;
- float term5 = term2 * term2 * term;
+ float term5 = pow5(1.0f - LoH);
return f0 + (f90 - f0) * term5;
}
+float3 F_Schlick(float LoH, float3 f0, float f90) {
+ float term5 = pow5(1.0f - LoH);
+ float3 f90v = float3(f90, f90, f90);
+ return f0 + (f90v - f0) * term5;
+}
+
// Walter "Microfacet Models for Refraction through Rough Surfaces"
// Equation 33.
// In the paper:
@@ -166,7 +175,7 @@ float4 brdf(Pbr pbr, LightData data) {
// Direct
{
- float3 remainder = 1.0f;
+ float3 layer_attenuation = 1.0f;
#if defined(_CLEARCOAT)
float Fcc = F_Schlick(data.direct.LoH, cc_f0, f90);
@@ -177,7 +186,7 @@ float4 brdf(Pbr pbr, LightData data) {
direct_specular_cc *= cc_energy_comp;
direct_specular_cc = max(0, direct_specular_cc);
specular += direct_specular_cc;
- remainder = saturate(remainder - direct_specular_cc);
+ layer_attenuation *= saturate(1.0f - Fcc * pbr.cc_strength);
#endif
#if defined(_CLOTH_SHEEN)
@@ -189,24 +198,22 @@ float4 brdf(Pbr pbr, LightData data) {
float3 direct_specular_cl = DFGcl * data.direct.color * pbr.cl_strength * pbr.cl_color * data.direct.NoL;
direct_specular_cl = max(0, direct_specular_cl);
specular += direct_specular_cl;
- remainder -= direct_specular_cl;
#endif
- float F = F_Schlick(data.direct.LoH, f0, f90);
+ float3 F = F_Schlick(data.direct.LoH, f0_color, f90);
float D = D_GGX(pbr.roughness, data.direct.NoH);
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);
+ float3 direct_specular = (D * G) * F;
+ direct_specular *= data.direct.color * data.direct.NoL;
direct_specular *= energy_comp;
+ direct_specular *= layer_attenuation;
direct_specular = max(0, direct_specular);
specular += direct_specular;
- remainder = saturate(remainder - direct_specular);
float Fd = Fd_OrenNayar(pbr.roughness, data.common.NoV, data.direct.NoL, data.direct.LoV) / PI;
- float3 direct_diffuse = Fd * remainder * (1.0f - pbr.metallic) * pbr.albedo.xyz * data.direct.color;
+ float3 direct_diffuse = Fd * (1.0f - pbr.metallic) * pbr.albedo.xyz * data.direct.color;
+ direct_diffuse *= layer_attenuation;
direct_diffuse = max(0, direct_diffuse);
diffuse += direct_diffuse;
}
@@ -239,7 +246,7 @@ float4 brdf(Pbr pbr, LightData data) {
float3 f0_spec = lerp(f0, pbr.albedo.xyz, pbr.metallic);
float3 ibl_specular_reflectance = lerp(dfg.xxx, dfg.yyy, f0_spec);
float3 indirect_specular = data.indirect.specular * ibl_specular_reflectance * energy_comp;
- const float F = F_Schlick(data.indirect.NoL, f0_spec, f90);
+ const float3 F = F_Schlick(data.indirect.NoL, f0_spec, f90);
const float3 is_conserved = indirect_specular * F;
specular += is_conserved;