node_principled_bsdf.osl 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * Copyright 2011-2017 Blender Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "stdosl.h"
  17. #include "node_fresnel.h"
  18. shader node_principled_bsdf(string distribution = "Multiscatter GGX",
  19. string subsurface_method = "burley",
  20. color BaseColor = color(0.8, 0.8, 0.8),
  21. float Subsurface = 0.0,
  22. vector SubsurfaceRadius = vector(1.0, 1.0, 1.0),
  23. color SubsurfaceColor = color(0.7, 0.1, 0.1),
  24. float Metallic = 0.0,
  25. float Specular = 0.5,
  26. float SpecularTint = 0.0,
  27. float Roughness = 0.5,
  28. float Anisotropic = 0.0,
  29. float AnisotropicRotation = 0.0,
  30. float Sheen = 0.0,
  31. float SheenTint = 0.5,
  32. float Clearcoat = 0.0,
  33. float ClearcoatRoughness = 0.03,
  34. float IOR = 1.45,
  35. float Transmission = 0.0,
  36. float TransmissionRoughness = 0.0,
  37. normal Normal = N,
  38. normal ClearcoatNormal = N,
  39. normal Tangent = normalize(dPdu),
  40. output closure color BSDF = 0)
  41. {
  42. float f = max(IOR, 1e-5);
  43. float diffuse_weight = (1.0 - clamp(Metallic, 0.0, 1.0)) * (1.0 - clamp(Transmission, 0.0, 1.0));
  44. float final_transmission = clamp(Transmission, 0.0, 1.0) * (1.0 - clamp(Metallic, 0.0, 1.0));
  45. float specular_weight = (1.0 - final_transmission);
  46. vector T = Tangent;
  47. float m_cdlum = luminance(BaseColor);
  48. color m_ctint = m_cdlum > 0.0 ? BaseColor / m_cdlum :
  49. color(0.0, 0.0, 0.0); // normalize lum. to isolate hue+sat
  50. /* rotate tangent */
  51. if (AnisotropicRotation != 0.0)
  52. T = rotate(T, AnisotropicRotation * M_2PI, point(0.0, 0.0, 0.0), Normal);
  53. if (diffuse_weight > 1e-5) {
  54. if (Subsurface > 1e-5) {
  55. color mixed_ss_base_color = SubsurfaceColor * Subsurface + BaseColor * (1.0 - Subsurface);
  56. if (subsurface_method == "burley") {
  57. BSDF = mixed_ss_base_color * bssrdf("principled",
  58. Normal,
  59. Subsurface * SubsurfaceRadius,
  60. SubsurfaceColor,
  61. "roughness",
  62. Roughness);
  63. }
  64. else {
  65. BSDF = mixed_ss_base_color * bssrdf("principled_random_walk",
  66. Normal,
  67. Subsurface * SubsurfaceRadius,
  68. mixed_ss_base_color,
  69. "roughness",
  70. Roughness);
  71. }
  72. }
  73. else {
  74. BSDF = BaseColor * principled_diffuse(Normal, Roughness);
  75. }
  76. if (Sheen > 1e-5) {
  77. color sheen_color = color(1.0, 1.0, 1.0) * (1.0 - SheenTint) + m_ctint * SheenTint;
  78. BSDF = BSDF + sheen_color * Sheen * principled_sheen(Normal);
  79. }
  80. BSDF = BSDF * diffuse_weight;
  81. }
  82. if (specular_weight > 1e-5) {
  83. float aspect = sqrt(1.0 - Anisotropic * 0.9);
  84. float r2 = Roughness * Roughness;
  85. float alpha_x = r2 / aspect;
  86. float alpha_y = r2 * aspect;
  87. color tmp_col = color(1.0, 1.0, 1.0) * (1.0 - SpecularTint) + m_ctint * SpecularTint;
  88. color Cspec0 = (Specular * 0.08 * tmp_col) * (1.0 - Metallic) + BaseColor * Metallic;
  89. if (distribution == "GGX" || Roughness <= 0.075) {
  90. BSDF = BSDF + specular_weight *
  91. microfacet_ggx_aniso_fresnel(Normal,
  92. T,
  93. alpha_x,
  94. alpha_y,
  95. (2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0,
  96. BaseColor,
  97. Cspec0);
  98. }
  99. else {
  100. BSDF = BSDF + specular_weight * microfacet_multi_ggx_aniso_fresnel(
  101. Normal,
  102. T,
  103. alpha_x,
  104. alpha_y,
  105. (2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0,
  106. BaseColor,
  107. Cspec0);
  108. }
  109. }
  110. if (final_transmission > 1e-5) {
  111. color Cspec0 = BaseColor * SpecularTint + color(1.0, 1.0, 1.0) * (1.0 - SpecularTint);
  112. float eta = backfacing() ? 1.0 / f : f;
  113. if (distribution == "GGX" || Roughness <= 5e-2) {
  114. float cosNO = dot(Normal, I);
  115. float Fr = fresnel_dielectric_cos(cosNO, eta);
  116. float refl_roughness = Roughness;
  117. if (Roughness <= 1e-2)
  118. refl_roughness = 0.0;
  119. float transmission_roughness = refl_roughness;
  120. if (distribution == "GGX")
  121. transmission_roughness = 1.0 - (1.0 - refl_roughness) * (1.0 - TransmissionRoughness);
  122. BSDF = BSDF +
  123. final_transmission *
  124. (Fr * microfacet_ggx_fresnel(
  125. Normal, refl_roughness * refl_roughness, eta, BaseColor, Cspec0) +
  126. (1.0 - Fr) * BaseColor *
  127. microfacet_ggx_refraction(
  128. Normal, transmission_roughness * transmission_roughness, eta));
  129. }
  130. else {
  131. BSDF = BSDF +
  132. final_transmission * microfacet_multi_ggx_glass_fresnel(
  133. Normal, Roughness * Roughness, eta, BaseColor, Cspec0);
  134. }
  135. }
  136. if (Clearcoat > 1e-5) {
  137. BSDF = BSDF + principled_clearcoat(
  138. ClearcoatNormal, Clearcoat, ClearcoatRoughness * ClearcoatRoughness);
  139. }
  140. }