浏览代码

Clean up BSDF.hlsl

/stochastic_alpha_test
Evgenii Golubev 7 年前
当前提交
00c2eb90
共有 2 个文件被更改,包括 89 次插入55 次删除
  1. 140
      ScriptableRenderPipeline/Core/ShaderLibrary/BSDF.hlsl
  2. 4
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl

140
ScriptableRenderPipeline/Core/ShaderLibrary/BSDF.hlsl


}
// Ref: Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs, p. 12.
float D_GGX_Visible(float NdotH, float NdotV, float roughness)
float D_GGX_Visible(float NdotH, float NdotV, float VdotH, float roughness)
}
// Precompute part of lambdaV
float GetSmithJointGGXPreLambdaV(float NdotV, float roughness)
{
float a2 = roughness * roughness;
return sqrt((-NdotV * a2 + NdotV) * NdotV + a2);
float V_SmithJointGGX(float NdotL, float NdotV, float roughness)
float V_SmithJointGGX(float NdotL, float NdotV, float roughness, float preLambdaV)
float a2 = roughness * roughness;
// lambda_v = (-1 + sqrt(a2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5f;
// lambda_l = (-1 + sqrt(a2 * (1 - NdotV2) / NdotV2 + 1)) * 0.5f;
// G = 1 / (1 + lambda_v + lambda_l);
// lambda_v = (-1 + sqrt(a2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5
// lambda_l = (-1 + sqrt(a2 * (1 - NdotV2) / NdotV2 + 1)) * 0.5
// G = 1 / (1 + lambda_v + lambda_l);
float a = roughness;
float a2 = a * a;
// Reorder code to be more optimal
float lambdaV = NdotL * sqrt((-NdotV * a2 + NdotV) * NdotV + a2);
// Reorder code to be more optimal:
float lambdaV = NdotL * preLambdaV;
float lambdaL = NdotV * sqrt((-NdotL * a2 + NdotL) * NdotL + a2);
// Simplify visibility term: (2.0 * NdotL * NdotV) / ((4.0 * NdotL * NdotV) * (lambda_v + lambda_l));

// Precompute part of lambdaV
float GetSmithJointGGXLambdaV(float NdotV, float roughness)
float V_SmithJointGGX(float NdotL, float NdotV, float roughness)
float a = roughness;
float a2 = a * a;
return sqrt((-NdotV * a2 + NdotV) * NdotV + a2);
float preLambdaV = GetSmithJointGGXPreLambdaV(NdotV, roughness);
return V_SmithJointGGX(NdotL, NdotV, roughness, preLambdaV);
float V_SmithJointGGX(float NdotL, float NdotV, float roughness, float lambdaV)
// Inline D_GGX() * V_SmithJointGGX() together for better code generation.
float DV_SmithJointGGX(float NdotH, float NdotL, float NdotV, float roughness, float preLambdaV)
float a = roughness;
float a2 = a * a;
// Reorder code to be more optimal
lambdaV *= NdotL;
float a2 = roughness * roughness;
float f = (NdotH * a2 - NdotH) * NdotH + 1.0;
float2 D = float2(a2, f * f); // Fraction without the constant (1/Pi)
float lambdaV = NdotL * preLambdaV;
// Simplify visibility term: (2.0 * NdotL * NdotV) / ((4.0 * NdotL * NdotV) * (lambda_v + lambda_l));
return 0.5 / (lambdaV + lambdaL);
float2 G = float2(1, lambdaV + lambdaL); // Fraction without the constant (0.5)
return (INV_PI * 0.5) * (D.x * G.y) / (D.y * G.y);
float V_SmithJointGGXApprox(float NdotL, float NdotV, float roughness)
float DV_SmithJointGGX(float NdotH, float NdotL, float NdotV, float roughness)
float a = roughness;
// Approximation of the above formulation (simplify the sqrt, not mathematically correct but close enough)
float lambdaV = NdotL * (NdotV * (1 - a) + a);
float lambdaL = NdotV * (NdotL * (1 - a) + a);
return 0.5 / (lambdaV + lambdaL);
float preLambdaV = GetSmithJointGGXPreLambdaV(NdotV, roughness);
return DV_SmithJointGGX(NdotH, NdotL, NdotV, roughness, preLambdaV);
}
// Precompute a part of LambdaV.

float GetSmithJointGGXApproxLambdaV(float NdotV, float roughness)
float GetSmithJointGGXPreLambdaVApprox(float NdotV, float roughness)
float V_SmithJointGGXApprox(float NdotL, float NdotV, float roughness, float lambdaV)
float V_SmithJointGGXApprox(float NdotL, float NdotV, float roughness, float preLambdaV)
// Approximation of the above formulation (simplify the sqrt, not mathematically correct but close enough)
lambdaV *= NdotL;
float lambdaV = NdotL * preLambdaV;
float V_SmithJointGGXApprox(float NdotL, float NdotV, float roughness)
{
float preLambdaV = GetSmithJointGGXPreLambdaVApprox(NdotV, roughness);
return V_SmithJointGGXApprox(NdotL, NdotV, roughness, preLambdaV);
}
float f = TdotH * TdotH / (roughnessT * roughnessT) + BdotH * BdotH / (roughnessB * roughnessB) + NdotH * NdotH;
float aT2 = roughnessT * roughnessT;
float aB2 = roughnessB * roughnessB;
float f = TdotH * TdotH / aT2 + BdotH * BdotH / aB2 + NdotH * NdotH;
return 1.0 / (roughnessT * roughnessB * f * f);
}

}
float GetSmithJointGGXAnisoPreLambdaV(float TdotV, float BdotV, float NdotV, float roughnessT, float roughnessB)
{
float aT2 = roughnessT * roughnessT;
float aB2 = roughnessB * roughnessB;
return sqrt(aT2 * TdotV * TdotV + aB2 * BdotV * BdotV + NdotV * NdotV);
}
float V_SmithJointGGXAniso(float TdotV, float BdotV, float NdotV, float TdotL, float BdotL, float NdotL, float roughnessT, float roughnessB)
float V_SmithJointGGXAniso(float TdotV, float BdotV, float NdotV, float TdotL, float BdotL, float NdotL, float roughnessT, float roughnessB, float preLambdaV)
float aT = roughnessT;
float aT2 = aT * aT;
float aB = roughnessB;
float aB2 = aB * aB;
float aT2 = roughnessT * roughnessT;
float aB2 = roughnessB * roughnessB;
float lambdaV = NdotL * sqrt(aT2 * TdotV * TdotV + aB2 * BdotV * BdotV + NdotV * NdotV);
float lambdaV = NdotL * preLambdaV;
float GetSmithJointGGXAnisoLambdaV(float TdotV, float BdotV, float NdotV, float roughnessT, float roughnessB)
float V_SmithJointGGXAniso(float TdotV, float BdotV, float NdotV, float TdotL, float BdotL, float NdotL, float roughnessT, float roughnessB)
float aT = roughnessT;
float aT2 = aT * aT;
float aB = roughnessB;
float aB2 = aB * aB;
return sqrt(aT2 * TdotV * TdotV + aB2 * BdotV * BdotV + NdotV * NdotV);
float preLambdaV = GetSmithJointGGXAnisoPreLambdaV(TdotV, BdotV, NdotV, roughnessT, roughnessB);
return V_SmithJointGGXAniso(TdotV, BdotV, NdotV, TdotL, BdotL, NdotL, roughnessT, roughnessB, preLambdaV);
float V_SmithJointGGXAnisoLambdaV(float TdotV, float BdotV, float NdotV, float TdotL, float BdotL, float NdotL, float roughnessT, float roughnessB, float lambdaV)
// Inline D_GGXAniso() * V_SmithJointGGXAniso() together for better code generation.
float DV_SmithJointGGX(float TdotH, float BdotH, float NdotH,
float TdotV, float BdotV, float NdotV,
float TdotL, float BdotL, float NdotL,
float roughnessT, float roughnessB, float preLambdaV)
float aT = roughnessT;
float aT2 = aT * aT;
float aB = roughnessB;
float aB2 = aB * aB;
float aT2 = roughnessT * roughnessT;
float aB2 = roughnessB * roughnessB;
float f = TdotH * TdotH / aT2 + BdotH * BdotH / aB2 + NdotH * NdotH;
float2 D = float2(1, roughnessT * roughnessB * f * f); // Fraction without the constant (1/Pi)
lambdaV *= NdotL;
float lambdaV = NdotL * preLambdaV;
return 0.5 / (lambdaV + lambdaL);
float2 G = float2(1, lambdaV + lambdaL); // Fraction without the constant (0.5)
return (INV_PI * 0.5) * (D.x * G.y) / (D.y * G.y);
}
float DV_SmithJointGGX(float TdotH, float BdotH, float NdotH,
float TdotV, float BdotV, float NdotV,
float TdotL, float BdotL, float NdotL,
float roughnessT, float roughnessB)
{
float preLambdaV = GetSmithJointGGXAnisoPreLambdaV(TdotV, BdotV, NdotV, roughnessT, roughnessB);
return DV_SmithJointGGX(TdotH, BdotH, NdotH,
TdotV, BdotV, NdotV,
TdotL, BdotL, NdotL,
roughnessT, roughnessB, preLambdaV);
}
//-----------------------------------------------------------------------------

4
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


NdotV = max(NdotV, MIN_N_DOT_V); // Use the modified (clamped) version
// GGX iso
preLightData.ggxLambdaV = GetSmithJointGGXLambdaV(NdotV, bsdfData.roughness);
preLightData.ggxLambdaV = GetSmithJointGGXPreLambdaV(NdotV, bsdfData.roughness);
// GGX aniso
preLightData.TdotV = 0.0;

preLightData.TdotV = dot(bsdfData.tangentWS, V);
preLightData.BdotV = dot(bsdfData.bitangentWS, V);
preLightData.anisoGGXLambdaV = GetSmithJointGGXAnisoLambdaV(preLightData.TdotV, preLightData.BdotV, NdotV, bsdfData.roughnessT, bsdfData.roughnessB);
preLightData.anisoGGXLambdaV = GetSmithJointGGXAnisoPreLambdaV(preLightData.TdotV, preLightData.BdotV, NdotV, bsdfData.roughnessT, bsdfData.roughnessB);
// For positive anisotropy values: tangent = highlight stretch (anisotropy) direction, bitangent = grain (brush) direction.
float3 grainDirWS = (bsdfData.anisotropy >= 0) ? bsdfData.bitangentWS : bsdfData.tangentWS;
float3 anisoIblNormalWS = GetAnisotropicModifiedNormal(grainDirWS, iblNormalWS, V, abs(bsdfData.anisotropy));

正在加载...
取消
保存