bsdf_principled_sheen.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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. #ifndef __BSDF_PRINCIPLED_SHEEN_H__
  17. #define __BSDF_PRINCIPLED_SHEEN_H__
  18. /* DISNEY PRINCIPLED SHEEN BRDF
  19. *
  20. * Shading model by Brent Burley (Disney): "Physically Based Shading at Disney" (2012)
  21. */
  22. CCL_NAMESPACE_BEGIN
  23. typedef ccl_addr_space struct PrincipledSheenBsdf {
  24. SHADER_CLOSURE_BASE;
  25. } PrincipledSheenBsdf;
  26. static_assert(sizeof(ShaderClosure) >= sizeof(PrincipledSheenBsdf),
  27. "PrincipledSheenBsdf is too large!");
  28. ccl_device float3 calculate_principled_sheen_brdf(
  29. const PrincipledSheenBsdf *bsdf, float3 N, float3 V, float3 L, float3 H, float *pdf)
  30. {
  31. float NdotL = dot(N, L);
  32. float NdotV = dot(N, V);
  33. if (NdotL < 0 || NdotV < 0) {
  34. *pdf = 0.0f;
  35. return make_float3(0.0f, 0.0f, 0.0f);
  36. }
  37. float LdotH = dot(L, H);
  38. float value = schlick_fresnel(LdotH) * NdotL;
  39. return make_float3(value, value, value);
  40. }
  41. ccl_device int bsdf_principled_sheen_setup(PrincipledSheenBsdf *bsdf)
  42. {
  43. bsdf->type = CLOSURE_BSDF_PRINCIPLED_SHEEN_ID;
  44. return SD_BSDF | SD_BSDF_HAS_EVAL;
  45. }
  46. ccl_device float3 bsdf_principled_sheen_eval_reflect(const ShaderClosure *sc,
  47. const float3 I,
  48. const float3 omega_in,
  49. float *pdf)
  50. {
  51. const PrincipledSheenBsdf *bsdf = (const PrincipledSheenBsdf *)sc;
  52. float3 N = bsdf->N;
  53. float3 V = I; // outgoing
  54. float3 L = omega_in; // incoming
  55. float3 H = normalize(L + V);
  56. if (dot(N, omega_in) > 0.0f) {
  57. *pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F;
  58. return calculate_principled_sheen_brdf(bsdf, N, V, L, H, pdf);
  59. }
  60. else {
  61. *pdf = 0.0f;
  62. return make_float3(0.0f, 0.0f, 0.0f);
  63. }
  64. }
  65. ccl_device float3 bsdf_principled_sheen_eval_transmit(const ShaderClosure *sc,
  66. const float3 I,
  67. const float3 omega_in,
  68. float *pdf)
  69. {
  70. return make_float3(0.0f, 0.0f, 0.0f);
  71. }
  72. ccl_device int bsdf_principled_sheen_sample(const ShaderClosure *sc,
  73. float3 Ng,
  74. float3 I,
  75. float3 dIdx,
  76. float3 dIdy,
  77. float randu,
  78. float randv,
  79. float3 *eval,
  80. float3 *omega_in,
  81. float3 *domega_in_dx,
  82. float3 *domega_in_dy,
  83. float *pdf)
  84. {
  85. const PrincipledSheenBsdf *bsdf = (const PrincipledSheenBsdf *)sc;
  86. float3 N = bsdf->N;
  87. sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
  88. if (dot(Ng, *omega_in) > 0) {
  89. float3 H = normalize(I + *omega_in);
  90. *eval = calculate_principled_sheen_brdf(bsdf, N, I, *omega_in, H, pdf);
  91. #ifdef __RAY_DIFFERENTIALS__
  92. // TODO: find a better approximation for the diffuse bounce
  93. *domega_in_dx = -((2 * dot(N, dIdx)) * N - dIdx);
  94. *domega_in_dy = -((2 * dot(N, dIdy)) * N - dIdy);
  95. #endif
  96. }
  97. else {
  98. *pdf = 0.0f;
  99. }
  100. return LABEL_REFLECT | LABEL_DIFFUSE;
  101. }
  102. CCL_NAMESPACE_END
  103. #endif /* __BSDF_PRINCIPLED_SHEEN_H__ */