您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

198 行
6.6 KiB

// ------------------------------------------------------------------
// Diffuse
// From UE4 - Used for Cloth (Deprecated)
float3 Diffuse_Lambert(float3 DiffuseColor)
{
return DiffuseColor * (1 / UNITY_PI);
}
// ------------------------------------------------------------------
// Fresnel
// From UE4 - Used for Cloth
// [Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering"]
float3 F_Schlick(float3 SpecularColor, float VoH)
{
float Fc = Pow5(1 - VoH); // 1 sub, 3 mul
//return Fc + (1 - Fc) * SpecularColor; // 1 add, 3 mad
// Anything less than 2% is physically impossible and is instead considered to be shadowing
return saturate(50.0 * SpecularColor.g) * Fc + (1 - Fc) * SpecularColor;
}
// ------------------------------------------------------------------
// Distribution
// From UE4 - USed for Cloth
// GGX / Trowbridge-Reitz
// [Walter et al. 2007, "Microfacet models for refraction through rough surfaces"]
float D_GGX(float roughness, float NdotH)
{
float a = roughness * roughness;
float a2 = a * a;
float d = (NdotH * a2 - NdotH) * NdotH + 1; // 2 mad
return a2 / (UNITY_PI*d*d); // 4 mul, 1 rcp
}
// Anisotropic GGX
// Taken from HDRenderPipeline
float D_GGXAnisotropic(float TdotH, float BdotH, float NdotH, float roughnessT, float roughnessB)
{
float f = TdotH * TdotH / (roughnessT * roughnessT) + BdotH * BdotH / (roughnessB * roughnessB) + NdotH * NdotH;
return 1.0 / (roughnessT * roughnessB * f * f);
}
// From UE4 - Used for Cloth
float D_InvGGX(float roughness, float NdotH)
{
float a = roughness * roughness;
float a2 = a * a;
float A = 4;
float d = (NdotH - a2 * NdotH) * NdotH + a2;
return 1/(UNITY_PI * (1 + A*a2)) * (1 + 4 * a2*a2 / (d*d)); //RCP
}
// ------------------------------------------------------------------
// Visibility
// From UE4 - Used for Cloth
// Appoximation of joint Smith term for GGX
// [Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs"]
float Vis_SmithJointApprox(float Roughness, float NoV, float NoL)
{
float a = (Roughness*Roughness);
float Vis_SmithV = NoL * (NoV * (1 - a) + a);
float Vis_SmithL = NoV * (NoL * (1 - a) + a);
// Note: will generate NaNs with Roughness = 0. MinRoughness is used to prevent this
return 0.5 * 1/(Vis_SmithV + Vis_SmithL); //RCP
}
// From UE4 - Used for Cloth
float Vis_Cloth(float NoV, float NoL)
{
return 1/(4 * (NoL + NoV - NoL * NoV)); //RCP
}
// ------------------------------------------------------------------
// SORT THESE
// Smith Joint GGX Anisotropic Visibility
// Taken from https://cedec.cesa.or.jp/2015/session/ENG/14698.html
float SmithJointGGXAnisotropic(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;
float lambdaV = NdotL * sqrt(aT2 * TdotV * TdotV + aB2 * BdotV * BdotV + NdotV * NdotV);
float lambdaL = NdotV * sqrt(aT2 * TdotL * TdotL + aB2 * BdotL * BdotL + NdotL * NdotL);
return 0.5 / (lambdaV + lambdaL);
}
// Convert Anistropy to roughness
void ConvertAnisotropyToRoughness(float roughness, float anisotropy, out float roughnessT, out float roughnessB)
{
// (0 <= anisotropy <= 1), therefore (0 <= anisoAspect <= 1)
// The 0.9 factor limits the aspect ratio to 10:1.
float anisoAspect = sqrt(1.0 - 0.9 * anisotropy);
roughnessT = roughness / anisoAspect; // Distort along tangent (rougher)
roughnessB = roughness * anisoAspect; // Straighten along bitangent (smoother)
}
// Schlick Fresnel
float FresnelSchlick(float f0, float f90, float u)
{
float x = 1.0 - u;
float x5 = x * x;
x5 = x5 * x5 * x;
return (f90 - f0) * x5 + f0; // sub mul mul mul sub mad
}
//Clamp roughness
float ClampRoughnessForAnalyticalLights(float roughness)
{
return max(roughness, 0.000001);
}
//Calculate tangent warp for IBL (Reference Version - not used)
float3 SpecularGGXIBLRef(float3 viewDir, float3 normalDir, float3 tangentDir, float3 bitangentDir, float roughnessT, float roughnessB)
{
return float3(1, 1, 1);
//Hidden in UnityAnisotropicLighting.cginc
}
// Sample Anisotropic Direction for IBL (Reference Version - not used)
void SampleAnisoGGXDir(float2 u, float3 viewDir, float3 normalDir, float3 tangent, float3 bitangent, float roughnessT, float roughnessB, out float3 halfDir, out float3 lightDir)
{
// AnisoGGX NDF sampling
halfDir = sqrt(u.x / (1.0 - u.x)) * (roughnessT * cos((UNITY_PI * 2) * u.y) * tangent + roughnessB * sin((UNITY_PI * 2) * u.y) * bitangent) + normalDir;
halfDir = normalize(halfDir);
// Convert sample from half angle to incident angle
lightDir = 2.0 * saturate(dot(viewDir, halfDir)) * halfDir - viewDir;
}
// Ref: Donald Revie - Implementing Fur Using Deferred Shading (GPU Pro 2)
// The grain direction (e.g. hair or brush direction) is assumed to be orthogonal to the normal.
// The returned normal is NOT normalized.
float3 ComputeGrainNormal(float3 grainDir, float3 V)
{
float3 B = cross(-V, grainDir);
return cross(B, grainDir);
}
//Modify Normal for Anisotropic IBL (Realtime version)
// Fake anisotropic by distorting the normal.
// The grain direction (e.g. hair or brush direction) is assumed to be orthogonal to N.
// Anisotropic ratio (0->no isotropic; 1->full anisotropy in tangent direction)
float3 GetAnisotropicModifiedNormal(float3 grainDir, float3 N, float3 V, float anisotropy)
{
float3 grainNormal = ComputeGrainNormal(grainDir, V);
// TODO: test whether normalizing 'grainNormal' is worth it.
return normalize(lerp(N, grainNormal, anisotropy));
}
/// REGION END - ANISOTROPY
/// REGION START - SUBSURFACE SCATTERING
half Fresnel(half3 H, half3 V, half F0)
{
half base = 1.0 - dot(V, H);
half exponential = pow(base, 5.0);
return exponential + F0 * (1.0 - exponential);
}
/*
inline half3 KelemenSzirmayKalosSpecular(half3 normal, half3 lightDir, half3 viewDir, float roughness, float rho_s)
{
half3 result = half3(0, 0, 0);
half NdotL = dot(normal, lightDir);
if (NdotL > 0.0)
{
half3 h = lightDir + viewDir;
half3 H = normalize(h);
half NdotH = dot(normal, H);
half PH = pow(2.0 * tex2D(_BeckmannPrecomputedTex, half2(NdotH, roughness)).r, 10.0);
half F = Fresnel(H, viewDir, 0.028);
half frSpec = max(PH * F / dot(h, h), 0);
half term = NdotL * rho_s * frSpec;
result = half3(term, term, term);
}
return result;
}*/
/*
half3 SkinDiffuse(float curv, float3 NdotL)
{
float3 lookup = NdotL * 0.5 + 0.5;
float3 diffuse;
diffuse.r = tex2D(_DiffusionProfileTexture, float2(lookup.r, curv)).r;
diffuse.g = tex2D(_DiffusionProfileTexture, float2(lookup.g, curv)).g;
diffuse.b = tex2D(_DiffusionProfileTexture, float2(lookup.b, curv)).b;
return diffuse;
}*/
/// REGION END - SUBSURFACE SCATTERING