您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
76 行
2.8 KiB
76 行
2.8 KiB
#ifndef LIGHTWEIGHT_BRDF_INCLUDED
|
|
#define LIGHTWEIGHT_BRDF_INCLUDED
|
|
|
|
#define PI 3.14159265359f
|
|
|
|
half MetallicSetup_Reflectivity()
|
|
{
|
|
return 1.0h - OneMinusReflectivityFromMetallic(_Metallic);
|
|
}
|
|
|
|
half3 LightweightBRDFDirect(half3 diffColor, half3 specColor, half smoothness, half RdotL)
|
|
{
|
|
#ifndef _SPECULARHIGHLIGHTS_OFF
|
|
half RdotLPow4 = Pow4(RdotL);
|
|
half LUT_RANGE = 16.0; // must match range in NHxRoughness() function in GeneratedTextures.cpp
|
|
// Lookup texture to save instructions
|
|
half perceptualRoughness = 1.0 - smoothness;
|
|
half specular = tex2D(unity_NHxRoughness, half2(RdotLPow4, perceptualRoughness)).UNITY_ATTEN_CHANNEL * LUT_RANGE;
|
|
return diffColor + specular * specColor;
|
|
#else
|
|
return diffColor;
|
|
#endif
|
|
}
|
|
|
|
// Based on Minimalist CookTorrance BRDF
|
|
// Implementation is slightly different from original derivation: http://www.thetenthplanet.de/archives/255
|
|
//
|
|
// * NDF [Modified] GGX
|
|
// * Modified Kelemen and Szirmay-Kalos for Visibility term
|
|
// * Fresnel approximated with 1/LdotH
|
|
half3 LightweightBDRF(half3 diffColor, half3 specColor, half oneMinusReflectivity, half perceptualRoughness, half3 normal, half3 lightDirection, half3 viewDir)
|
|
{
|
|
#ifndef _SPECULARHIGHLIGHTS_OFF
|
|
half3 halfDir = Unity_SafeNormalize(lightDirection + viewDir);
|
|
|
|
half NoH = saturate(dot(normal, halfDir));
|
|
half LoH = saturate(dot(lightDirection, halfDir));
|
|
|
|
// Specular term
|
|
half roughness = perceptualRoughness * perceptualRoughness;
|
|
|
|
// GGX Distribution multiplied by combined approximation of Visibility and Fresnel
|
|
// See "Optimizing PBR for Mobile" from Siggraph 2015 moving mobile graphics course
|
|
// https://community.arm.com/events/1155
|
|
half a2 = roughness * roughness;
|
|
half d = NoH * NoH * (a2 - 1.h) + 1.00001h;
|
|
|
|
half LoH2 = LoH * LoH;
|
|
half specularTerm = a2 / ((d * d) * max(0.1h, LoH2) * (roughness + 0.5h) * 4);
|
|
|
|
// on mobiles (where half actually means something) denominator have risk of overflow
|
|
// clamp below was added specifically to "fix" that, but dx compiler (we convert bytecode to metal/gles)
|
|
// sees that specularTerm have only non-negative terms, so it skips max(0,..) in clamp (leaving only min(100,...))
|
|
#if defined (SHADER_API_MOBILE)
|
|
specularTerm = specularTerm - 1e-4h;
|
|
#endif
|
|
|
|
#if defined (SHADER_API_MOBILE)
|
|
specularTerm = clamp(specularTerm, 0.0, 100.0); // Prevent FP16 overflow on mobiles
|
|
#endif
|
|
|
|
return diffColor + specularTerm * specColor;
|
|
#else
|
|
return diffColor;
|
|
#endif
|
|
}
|
|
|
|
half3 LightweightBRDFIndirect(half3 diffColor, half3 specColor, UnityIndirect indirect, float roughness, half grazingTerm, half fresnelTerm)
|
|
{
|
|
half3 c = indirect.diffuse * diffColor;
|
|
float surfaceReduction = 1.0 / (roughness * roughness + 1.0);
|
|
c += surfaceReduction * indirect.specular * lerp(specColor, grazingTerm, fresnelTerm);
|
|
return c;
|
|
}
|
|
|
|
#endif
|