diff options
Diffstat (limited to 'brdf.cginc')
| -rw-r--r-- | brdf.cginc | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/brdf.cginc b/brdf.cginc new file mode 100644 index 0000000..d36d82b --- /dev/null +++ b/brdf.cginc @@ -0,0 +1,58 @@ +#ifndef __BRDF_INC +#define __BRDF_INC + +#include "pbr.cginc" +#include "lighting.cginc" +#include "lysenko.cginc" +#include "math.cginc" + +float fresnel(float LoH) { + // Schlick's approximation + float n1 = 1.0; + float n2 = 1.33; + float r0 = (n1 - n2) / (n1 + n2); + r0 = r0 * r0; + + float term = 1.0 - LoH; + float term2 = term * term; + float term5 = term2 * term2 * term; + return r0 + (1.0 - r0) * term5; +} + +float4 brdf(Pbr pbr, LightData data) { + float3 specular = 0; + float3 diffuse = 0; + + // Direct + if (true) { + float F = fresnel(data.direct.LoH); + float D = D_GGX(pbr.roughness, data.direct.NoH, data.direct.H); + float V = V_SmithGGXCorrelated_Fast(pbr.roughness, data.common.NoV, data.direct.NoL); + + float denom = 4.0f * data.common.NoV * data.direct.NoL; + float FDV = denom > _BRDF_Specular_Min_Denom ? F * D * V / denom : 0.0f; + specular += FDV * data.direct.color * data.direct.NoL; + + float Fd = Fd_OrenNayar(pbr.roughness, data.common.NoV, data.direct.NoL, data.direct.LoV); + float3 remainder = (1.0f - F); + diffuse += (Fd / PI) * remainder * pbr.albedo.xyz * data.direct.color; + remainder *= (1.0f - (Fd / PI) * pbr.albedo); + } + + // Indirect + if (true) { + float F = fresnel(data.indirect.LoH); + + specular += F * data.indirect.specular; + + float Fd = 1.0 / PI; + float3 remainder = (1.0f - F); + diffuse += Fd * remainder * pbr.albedo.xyz * data.indirect.diffuse; + remainder *= (1.0f - Fd * pbr.albedo); + } + + return float4(diffuse + specular, 1); +} + +#endif // __BRDF_INC + |
