LayaBRDF.cginc 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. 
  2. half LayaPow5(half x)
  3. {
  4. return x * x * x*x * x;
  5. }
  6. float3 Laya_SafeNormalize(float3 inVec)
  7. {
  8. float dp3 = max(0.001f, dot(inVec, inVec));
  9. return inVec * rsqrt(dp3);
  10. }
  11. half LayaDisneyDiffuse(half NdotV, half NdotL, half LdotH, half perceptualRoughness)
  12. {
  13. half fd90 = 0.5 + 2 * LdotH * LdotH * perceptualRoughness;
  14. half lightScatter = (1 + (fd90 - 1) * LayaPow5(1 - NdotL));
  15. half viewScatter = (1 + (fd90 - 1) * LayaPow5(1 - NdotV));
  16. return lightScatter * viewScatter;
  17. }
  18. // Ref: http://jcgt.org/published/0003/02/03/paper.pdf
  19. float LayaSmithJointGGXVisibilityTerm(float NdotL, float NdotV, float roughness)
  20. {
  21. float a = roughness;
  22. float lambdaV = NdotL * (NdotV * (1 - a) + a);
  23. float lambdaL = NdotV * (NdotL * (1 - a) + a);
  24. return 0.5f / (lambdaV + lambdaL + 1e-5f);
  25. }
  26. float LayaGGXTerm(float NdotH, float roughness)
  27. {
  28. float a2 = roughness * roughness;
  29. float d = (NdotH * a2 - NdotH) * NdotH + 1.0f;
  30. return UNITY_INV_PI * a2 / (d * d + 1e-7f);
  31. }
  32. inline half3 LayaFresnelTerm(half3 F0, half cosA)
  33. {
  34. half t = Pow5(1 - cosA);
  35. return F0 + (1 - F0) * t;
  36. }
  37. inline half3 LayaFresnelLerp(half3 F0, half3 F90, half cosA)
  38. {
  39. half t = Pow5(1 - cosA);
  40. return lerp(F0, F90, t);
  41. }
  42. half4 BRDF1_Laya_PBS(half3 diffColor, half3 specColor, half oneMinusReflectivity, half smoothness,float3 normal, float3 viewDir,LayaLight light, LayaIndirect gi)
  43. {
  44. float perceptualRoughness = SmoothnessToPerceptualRoughness(smoothness);
  45. float3 halfDir = Laya_SafeNormalize(float3(light.dir) + viewDir);
  46. half nv = abs(dot(normal, viewDir));
  47. float nl = saturate(dot(normal, light.dir));
  48. float nh = saturate(dot(normal, halfDir));
  49. half lv = saturate(dot(light.dir, viewDir));
  50. half lh = saturate(dot(light.dir, halfDir));
  51. half diffuseTerm = LayaDisneyDiffuse(nv, nl, lh, perceptualRoughness) * nl;
  52. float roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
  53. roughness = max(roughness, 0.002);
  54. float V = LayaSmithJointGGXVisibilityTerm(nl, nv, roughness);
  55. float D = LayaGGXTerm(nh, roughness);
  56. float specularTerm = V * D * 3.14159265359;
  57. # ifdef UNITY_COLORSPACE_GAMMA
  58. specularTerm = sqrt(max(1e-4h, specularTerm));
  59. # endif
  60. specularTerm = max(0, specularTerm * nl);
  61. half surfaceReduction;
  62. # ifdef UNITY_COLORSPACE_GAMMA
  63. surfaceReduction = 1.0 - 0.28*roughness*perceptualRoughness;
  64. # else
  65. surfaceReduction = 1.0 / (roughness*roughness + 1.0);
  66. # endif
  67. specularTerm *= any(specColor) ? 1.0 : 0.0;
  68. half grazingTerm = saturate(smoothness + (1 - oneMinusReflectivity));
  69. half3 color = diffColor * (gi.diffuse)
  70. +(diffColor*light.color * diffuseTerm)
  71. + specularTerm * light.color * LayaFresnelTerm(specColor, lh)
  72. + surfaceReduction * gi.specular * LayaFresnelLerp(specColor, grazingTerm, nv);
  73. return half4(color, 1);
  74. }
  75. half3 LayaBRDF3_Direct(half3 diffColor, half3 specColor, half rlPow4, half smoothness)
  76. {
  77. half LUT_RANGE = 16.0;
  78. half specular = tex2D(unity_NHxRoughness, half2(rlPow4, SmoothnessToPerceptualRoughness(smoothness))).r * LUT_RANGE;
  79. return diffColor + specular * specColor;
  80. }
  81. half3 LayaBRDF3_Indirect(half3 diffColor, half3 specColor, LayaIndirect indirect, half grazingTerm, half fresnelTerm)
  82. {
  83. half3 c = indirect.diffuse * diffColor;
  84. c += indirect.specular * lerp(specColor, grazingTerm, fresnelTerm);
  85. return c;
  86. }
  87. half4 BRDF3_Laya_PBS(half3 diffColor, half3 specColor, half oneMinusReflectivity, half smoothness,
  88. float3 normal, float3 viewDir,
  89. LayaLight light, LayaIndirect gi)
  90. {
  91. float3 reflDir = reflect(viewDir, normal);
  92. half nl = saturate(dot(normal, light.dir));
  93. half nv = saturate(dot(normal, viewDir));
  94. half2 rlPow4AndFresnelTerm = Pow4(float2(dot(reflDir, light.dir), 1 - nv));
  95. half rlPow4 = rlPow4AndFresnelTerm.x;
  96. half fresnelTerm = rlPow4AndFresnelTerm.y;
  97. half grazingTerm = saturate(smoothness + (1 - oneMinusReflectivity));
  98. half3 color = BRDF3_Direct(diffColor, specColor, rlPow4, smoothness);
  99. color *= light.color * nl;
  100. color += BRDF3_Indirect(diffColor, specColor, gi, grazingTerm, fresnelTerm);
  101. return half4(color, 1);
  102. }