Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion features/Hair Specular/Shaders/Hair/Hair.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ namespace Hair

const float3 Lp = L - NdotL * N;
const float3 Vp = V - NdotL * N;
const float cosPhi = dot(Lp, Vp) * rsqrt(dot(Lp, Lp) * dot(Vp, Vp) + 1e-4);
const float cosPhi = dot(Lp, Vp) * rsqrt(dot(Lp, Lp) * dot(Vp, Vp) + EPSILON_DIVISION);
const float cosHalfPhi = sqrt(saturate(0.5 + 0.5 * cosPhi));

float n_prime = 1.19 / cosThetaD + 0.36 * cosThetaD;
Expand Down
20 changes: 10 additions & 10 deletions package/Shaders/Common/BRDF.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace BRDF

float2 cos_alpha_beta = NdotV < NdotL ? float2(NdotV, NdotL) : float2(NdotL, NdotV);
float2 sin_alpha_beta = sqrt(saturate(1.0 - cos_alpha_beta * cos_alpha_beta));
float C = sin_alpha_beta.x * sin_alpha_beta.y / (1e-6 + cos_alpha_beta.y);
float C = sin_alpha_beta.x * sin_alpha_beta.y / (EPSILON_DIVISION + cos_alpha_beta.y);

return (1 / Math::PI) * (A + B * max(0.0, gamma) * C);
}
Expand Down Expand Up @@ -131,10 +131,10 @@ namespace BRDF
// [Estevez et al. 2017, "Production Friendly Microfacet Sheen BRDF"]
float D_Charlie(float roughness, float NdotH)
{
float invAlpha = pow(roughness, -4);
float invAlpha = pow(abs(roughness), -4);
float cos2h = NdotH * NdotH;
float sin2h = max(1.0 - cos2h, 1e-5);
return (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / Math::TAU;
float sin2h = 1.0 - cos2h;
return (2.0 + invAlpha) * pow(abs(sin2h), invAlpha * 0.5) / Math::TAU;
}

// Smith term for GGX
Expand All @@ -145,7 +145,7 @@ namespace BRDF
float a2 = a * a;
float Vis_SmithV = NdotV + sqrt(a2 + (1.0 - a2) * NdotV * NdotV);
float Vis_SmithL = NdotL + sqrt(a2 + (1.0 - a2) * NdotL * NdotL);
return rcp(Vis_SmithV * Vis_SmithL);
return rcp(max(Vis_SmithV * Vis_SmithL, EPSILON_DIVISION));
}

// Appoximation of joint Smith term for GGX
Expand All @@ -155,7 +155,7 @@ namespace BRDF
float a = roughness * roughness;
float Vis_SmithV = NdotL * (NdotV * (1.0 + a) + a);
float Vis_SmithL = NdotV * (NdotL * (1.0 + a) + a);
return rcp(Vis_SmithV + Vis_SmithL) * 0.5;
return rcp(max(Vis_SmithV + Vis_SmithL, EPSILON_DIVISION)) * 0.5;
}

float Vis_SmithJoint(float roughness, float NdotV, float NdotL)
Expand All @@ -164,14 +164,14 @@ namespace BRDF
float a2 = a * a;
float Vis_SmithV = NdotL * sqrt(a2 + (1.0 - a2) * NdotV * NdotV);
float Vis_SmithL = NdotV * sqrt(a2 + (1.0 - a2) * NdotL * NdotL);
return rcp(Vis_SmithV + Vis_SmithL) * 0.5;
return rcp(max(Vis_SmithV + Vis_SmithL, EPSILON_DIVISION)) * 0.5;
}

float Vis_SmithJointAniso(float alphaX, float alphaY, float NdotL, float NdotV, float XdotL, float YdotL, float XdotV, float YdotV)
{
float Vis_SmithV = NdotL * length(float3(alphaX * XdotV, alphaY * YdotV, NdotV));
float Vis_SmithL = NdotV * length(float3(alphaX * XdotL, alphaY * YdotL, NdotL));
return rcp(Vis_SmithV + Vis_SmithL) * 0.5;
return rcp(max(Vis_SmithV + Vis_SmithL, EPSILON_DIVISION)) * 0.5;
}

// [Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF"]
Expand All @@ -192,13 +192,13 @@ namespace BRDF
{
float visV = NdotV < 0.5 ? exp(Vis_Charlie_L(NdotV, roughness)) : exp(2.0 * Vis_Charlie_L(0.5, roughness) - Vis_Charlie_L(1.0 - NdotV, roughness));
float visL = NdotL < 0.5 ? exp(Vis_Charlie_L(NdotL, roughness)) : exp(2.0 * Vis_Charlie_L(0.5, roughness) - Vis_Charlie_L(1.0 - NdotL, roughness));
return rcp(((1.0 + visV + visL) * (4.0 * NdotL * NdotV)));
return rcp(((1.0 + visV + visL) * max(4.0 * NdotL * NdotV, EPSILON_DIVISION)));
}

// [Neubelt et al. 2013, "Crafting a Next-gen Material Pipeline for The Order: 1886"]
float Vis_Neubelt(float NdotV, float NdotL)
{
return rcp(4.0 * (NdotL + NdotV - NdotL * NdotV));
return rcp(4.0 * max(NdotL + NdotV - NdotL * NdotV, EPSILON_DIVISION));
}

// [Lazarov 2013, "Getting More Physical in Call of Duty: Black Ops II"]
Expand Down
3 changes: 3 additions & 0 deletions package/Shaders/Common/Math.hlsli
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#ifndef __MATH_DEPENDENCY_HLSL__
#define __MATH_DEPENDENCY_HLSL__

#define EPSILON_DOT_CLAMP 1e-5f // For dot product clamping
#define EPSILON_DIVISION 1e-6f // For division to avoid division by zero

namespace Math
{
static const float4x4 IdentityMatrix = {
Expand Down
16 changes: 8 additions & 8 deletions package/Shaders/Common/PBR.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ namespace PBR

const float3 Lp = L - NdotL * N;
const float3 Vp = V - NdotL * N;
const float cosPhi = dot(Lp, Vp) * rsqrt(dot(Lp, Lp) * dot(Vp, Vp) + 1e-4);
const float cosPhi = dot(Lp, Vp) * rsqrt(dot(Lp, Lp) * dot(Vp, Vp) + EPSILON_DIVISION);
const float cosHalfPhi = sqrt(saturate(0.5 + 0.5 * cosPhi));

float n_prime = 1.19 / cosThetaD + 0.36 * cosThetaD;
Expand Down Expand Up @@ -309,8 +309,8 @@ namespace PBR
float NdotH = dot(N, H);
float VdotH = dot(V, H);

float satNdotL = clamp(NdotL, 1e-5, 1);
float satNdotV = saturate(abs(NdotV) + 1e-5);
float satNdotL = clamp(NdotL, EPSILON_DOT_CLAMP, 1);
float satNdotV = saturate(abs(NdotV) + EPSILON_DOT_CLAMP);
float satVdotL = saturate(VdotL);
float satNdotH = saturate(NdotH);
float satVdotH = saturate(VdotH);
Expand Down Expand Up @@ -364,8 +364,8 @@ namespace PBR
float coatVdotH = satVdotH;
[branch] if ((PBRFlags & Flags::CoatNormal) != 0)
{
coatNdotL = clamp(dot(coatN, coatL), 1e-5, 1);
coatNdotV = saturate(abs(dot(coatN, coatV)) + 1e-5);
coatNdotL = clamp(dot(coatN, coatL), EPSILON_DOT_CLAMP, 1);
coatNdotV = saturate(abs(dot(coatN, coatV)) + EPSILON_DOT_CLAMP);
coatNdotH = saturate(dot(coatN, coatH));
coatVdotH = saturate(dot(coatV, coatH));
}
Expand All @@ -390,8 +390,8 @@ namespace PBR
const float wetnessF0 = 0.02;

float3 H = normalize(V + L);
float NdotL = clamp(dot(N, L), 1e-5, 1);
float NdotV = saturate(abs(dot(N, V)) + 1e-5);
float NdotL = clamp(dot(N, L), EPSILON_DOT_CLAMP, 1);
float NdotV = saturate(abs(dot(N, V)) + EPSILON_DOT_CLAMP);
float NdotH = saturate(dot(N, H));
float VdotH = saturate(dot(V, H));

Expand Down Expand Up @@ -483,7 +483,7 @@ namespace PBR
const float wetnessStrength = 1;
const float wetnessF0 = 0.02;

float NdotV = saturate(abs(dot(N, V)) + 1e-5);
float NdotV = saturate(abs(dot(N, V)) + EPSILON_DOT_CLAMP);
float2 specularBRDF = BRDF::EnvBRDFApproxLazarov(roughness, NdotV);
float3 specularLobeWeight = wetnessF0 * specularBRDF.x + specularBRDF.y;

Expand Down