bsdf_phong_ramp.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. * Adapted from Open Shading Language with this license:
  3. *
  4. * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
  5. * All Rights Reserved.
  6. *
  7. * Modifications Copyright 2012, Blender Foundation.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions are
  11. * met:
  12. * * Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * * Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. * * Neither the name of Sony Pictures Imageworks nor the names of its
  18. * contributors may be used to endorse or promote products derived from
  19. * this software without specific prior written permission.
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. */
  32. #ifndef __BSDF_PHONG_RAMP_H__
  33. #define __BSDF_PHONG_RAMP_H__
  34. CCL_NAMESPACE_BEGIN
  35. #ifdef __OSL__
  36. typedef ccl_addr_space struct PhongRampBsdf {
  37. SHADER_CLOSURE_BASE;
  38. float exponent;
  39. float3 *colors;
  40. } PhongRampBsdf;
  41. static_assert(sizeof(ShaderClosure) >= sizeof(PhongRampBsdf), "PhongRampBsdf is too large!");
  42. ccl_device float3 bsdf_phong_ramp_get_color(const float3 colors[8], float pos)
  43. {
  44. int MAXCOLORS = 8;
  45. float npos = pos * (float)(MAXCOLORS - 1);
  46. int ipos = float_to_int(npos);
  47. if (ipos < 0)
  48. return colors[0];
  49. if (ipos >= (MAXCOLORS - 1))
  50. return colors[MAXCOLORS - 1];
  51. float offset = npos - (float)ipos;
  52. return colors[ipos] * (1.0f - offset) + colors[ipos + 1] * offset;
  53. }
  54. ccl_device int bsdf_phong_ramp_setup(PhongRampBsdf *bsdf)
  55. {
  56. bsdf->type = CLOSURE_BSDF_PHONG_RAMP_ID;
  57. bsdf->exponent = max(bsdf->exponent, 0.0f);
  58. return SD_BSDF | SD_BSDF_HAS_EVAL;
  59. }
  60. ccl_device float3 bsdf_phong_ramp_eval_reflect(const ShaderClosure *sc,
  61. const float3 I,
  62. const float3 omega_in,
  63. float *pdf)
  64. {
  65. const PhongRampBsdf *bsdf = (const PhongRampBsdf *)sc;
  66. float m_exponent = bsdf->exponent;
  67. float cosNI = dot(bsdf->N, omega_in);
  68. float cosNO = dot(bsdf->N, I);
  69. if (cosNI > 0 && cosNO > 0) {
  70. // reflect the view vector
  71. float3 R = (2 * cosNO) * bsdf->N - I;
  72. float cosRI = dot(R, omega_in);
  73. if (cosRI > 0) {
  74. float cosp = powf(cosRI, m_exponent);
  75. float common = 0.5f * M_1_PI_F * cosp;
  76. float out = cosNI * (m_exponent + 2) * common;
  77. *pdf = (m_exponent + 1) * common;
  78. return bsdf_phong_ramp_get_color(bsdf->colors, cosp) * out;
  79. }
  80. }
  81. return make_float3(0.0f, 0.0f, 0.0f);
  82. }
  83. ccl_device float3 bsdf_phong_ramp_eval_transmit(const ShaderClosure *sc,
  84. const float3 I,
  85. const float3 omega_in,
  86. float *pdf)
  87. {
  88. return make_float3(0.0f, 0.0f, 0.0f);
  89. }
  90. ccl_device int bsdf_phong_ramp_sample(const ShaderClosure *sc,
  91. float3 Ng,
  92. float3 I,
  93. float3 dIdx,
  94. float3 dIdy,
  95. float randu,
  96. float randv,
  97. float3 *eval,
  98. float3 *omega_in,
  99. float3 *domega_in_dx,
  100. float3 *domega_in_dy,
  101. float *pdf)
  102. {
  103. const PhongRampBsdf *bsdf = (const PhongRampBsdf *)sc;
  104. float cosNO = dot(bsdf->N, I);
  105. float m_exponent = bsdf->exponent;
  106. if (cosNO > 0) {
  107. // reflect the view vector
  108. float3 R = (2 * cosNO) * bsdf->N - I;
  109. # ifdef __RAY_DIFFERENTIALS__
  110. *domega_in_dx = (2 * dot(bsdf->N, dIdx)) * bsdf->N - dIdx;
  111. *domega_in_dy = (2 * dot(bsdf->N, dIdy)) * bsdf->N - dIdy;
  112. # endif
  113. float3 T, B;
  114. make_orthonormals(R, &T, &B);
  115. float phi = M_2PI_F * randu;
  116. float cosTheta = powf(randv, 1 / (m_exponent + 1));
  117. float sinTheta2 = 1 - cosTheta * cosTheta;
  118. float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0;
  119. *omega_in = (cosf(phi) * sinTheta) * T + (sinf(phi) * sinTheta) * B + (cosTheta)*R;
  120. if (dot(Ng, *omega_in) > 0.0f) {
  121. // common terms for pdf and eval
  122. float cosNI = dot(bsdf->N, *omega_in);
  123. // make sure the direction we chose is still in the right hemisphere
  124. if (cosNI > 0) {
  125. float cosp = powf(cosTheta, m_exponent);
  126. float common = 0.5f * M_1_PI_F * cosp;
  127. *pdf = (m_exponent + 1) * common;
  128. float out = cosNI * (m_exponent + 2) * common;
  129. *eval = bsdf_phong_ramp_get_color(bsdf->colors, cosp) * out;
  130. }
  131. }
  132. }
  133. return LABEL_REFLECT | LABEL_GLOSSY;
  134. }
  135. #endif /* __OSL__ */
  136. CCL_NAMESPACE_END
  137. #endif /* __BSDF_PHONG_RAMP_H__ */