BRDF分为漫反射和高光反射部分
漫反射部分
unity采用的是Disney漫反射模型
half DisneyDiffuse(half NdotV, half NdotL, half LdotH, half roughness)
{
half nlPow5 = Pow5 (1-NdotL);
half nvPow5 = Pow5 (1-NdotV);
half Fd90 = 0.5 + 2 * LdotH * LdotH * roughness;
half disneyDiffuse = (1 + (Fd90-1) * nlPow5) * (1 + (Fd90-1) * nvPow5);
half diffuseTerm = disneyDiffuse * NdotL;
return diffuseTerm;
}
高光反射部分
spec term比较多,分GDF三大部分
//G
//------------------------------------------------------------------------------------------------------------------------
//Geometric Shadowing Functions
float ImplicitGeometricShadowingFunction (float NdotL, float NdotV){
float Gs = (NdotL*NdotV);
return Gs;
}
float AshikhminShirleyGeometricShadowingFunction (float NdotL, float NdotV, float LdotH){
float Gs = NdotL*NdotV/(LdotH*max(NdotL,NdotV));
return (Gs);
}
float AshikhminPremozeGeometricShadowingFunction (float NdotL, float NdotV){
float Gs = NdotL*NdotV/(NdotL+NdotV - NdotL*NdotV);
return (Gs);
}
float DuerGeometricShadowingFunction (float3 lightDirection,float3 viewDirection, float3 normalDirection,float NdotL, float NdotV){
float3 LpV = lightDirection + viewDirection;
float Gs = dot(LpV,LpV) * pow(dot(LpV,normalDirection),-4);
return (Gs);
}
float NeumannGeometricShadowingFunction (float NdotL, float NdotV){
float Gs = (NdotL*NdotV)/max(NdotL, NdotV);
return (Gs);
}
float KelemenGeometricShadowingFunction (float NdotL, float NdotV, float LdotH, float VdotH){
// float Gs = (NdotL*NdotV)/ (LdotH * LdotH); //this
float Gs = (NdotL*NdotV)/(VdotH * VdotH); //or this?
return (Gs);
}
float ModifiedKelemenGeometricShadowingFunction (float NdotV, float NdotL, float roughness)
{
float c = 0.797884560802865; // c = sqrt(2 / Pi)
float k = roughness * roughness * c;
float gH = NdotV * k +(1-k);
return (gH * gH * NdotL);
}
float CookTorrenceGeometricShadowingFunction (float NdotL, float NdotV, float VdotH, float NdotH){
float Gs = min(1.0, min(2*NdotH*NdotV / VdotH, 2*NdotH*NdotL / VdotH));
return (Gs);
}
float WardGeometricShadowingFunction (float NdotL, float NdotV, float VdotH, float NdotH){
float Gs = pow( NdotL * NdotV, 0.5);
return (Gs);
}
float KurtGeometricShadowingFunction (float NdotL, float NdotV, float VdotH, float alpha){
float Gs = (VdotH*pow(NdotL*NdotV, alpha))/ NdotL * NdotV;
return (Gs);
}
//F
//------------------------------------------------------------------------------------------------------------------------
//schlick functions
float SchlickFresnel(float i){
float x = clamp(1.0-i, 0.0, 1.0);
float x2 = x*x;
return x2*x2*x;
}
float3 FresnelLerp (float3 x, float3 y, float d)
{
float t = SchlickFresnel(d);
return lerp (x, y, t);
}
float3 SchlickFresnelFunction(float3 SpecularColor,float LdotH){
return SpecularColor + (1 - SpecularColor)* SchlickFresnel(LdotH);
}
float SchlickIORFresnelFunction(float ior,float LdotH){
float f0 = pow((ior-1)/(ior+1),2);
return f0 + (1 - f0) * SchlickFresnel(LdotH);
}
float SphericalGaussianFresnelFunction(float LdotH,float SpecularColor)
{
float power = ((-5.55473 * LdotH) - 6.98316) * LdotH;
return SpecularColor + (1 - SpecularColor) * pow(2,power);
}
//D
//------------------------------------------------------------------------------------------------------------------------
//Normal Distribution Functions
float BlinnPhongNormalDistribution(float NdotH, float specularpower, float speculargloss){
float Distribution = pow(NdotH,speculargloss) * specularpower;
Distribution *= (2+specularpower) / (2*3.1415926535);
return Distribution;
}
float PhongNormalDistribution(float RdotV, float specularpower, float speculargloss){
float Distribution = pow(RdotV,speculargloss) * specularpower;
Distribution *= (2+specularpower) / (2*3.1415926535);
return Distribution;
}
float BeckmannNormalDistribution(float roughness, float NdotH)
{
float roughnessSqr = roughness*roughness;
float NdotHSqr = NdotH*NdotH;
return max(0.000001,(1.0 / (3.1415926535*roughnessSqr*NdotHSqr*NdotHSqr))* exp((NdotHSqr-1)/(roughnessSqr*NdotHSqr)));
}
float GaussianNormalDistribution(float roughness, float NdotH)
{
float roughnessSqr = roughness*roughness;
float thetaH = acos(NdotH);
return exp(-thetaH*thetaH/roughnessSqr);
}
float GGXNormalDistribution(float roughness, float NdotH)
{
float roughnessSqr = roughness*roughness;
float NdotHSqr = NdotH*NdotH;
float TanNdotHSqr = (1-NdotHSqr)/NdotHSqr;
return (1.0/3.1415926535) * sqr(roughness/(NdotHSqr * (roughnessSqr + TanNdotHSqr)));
// float denom = NdotHSqr * (roughnessSqr-1)
}
float TrowbridgeReitzNormalDistribution(float NdotH, float roughness){
float roughnessSqr = roughness*roughness;
float Distribution = NdotH*NdotH * (roughnessSqr-1.0) + 1.0;
return roughnessSqr / (3.1415926535 * Distribution*Distribution);
}
float TrowbridgeReitzAnisotropicNormalDistribution(float anisotropic, float NdotH, float HdotX, float HdotY){
float aspect = sqrt(1.0h-anisotropic * 0.9h);
float X = max(.001, sqr(1.0-_Glossiness)/aspect) * 5;
float Y = max(.001, sqr(1.0-_Glossiness)*aspect) * 5;
return 1.0 / (3.1415926535 * X*Y * sqr(sqr(HdotX/X) + sqr(HdotY/Y) + NdotH*NdotH));
}
float WardAnisotropicNormalDistribution(float anisotropic, float NdotL, float NdotV, float NdotH, float HdotX, float HdotY){
float aspect = sqrt(1.0h-anisotropic * 0.9h);
float X = max(.001, sqr(1.0-_Glossiness)/aspect) * 5;
float Y = max(.001, sqr(1.0-_Glossiness)*aspect) * 5;
float exponent = -(sqr(HdotX/X) + sqr(HdotY/Y)) / sqr(NdotH);
float Distribution = 1.0 / ( 3.14159265 * X * Y * sqrt(NdotL * NdotV));
Distribution *= exp(exponent);
return Distribution;
}