bsdf_microfacet_multi_impl.h 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /*
  2. * Copyright 2011-2016 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. /* Evaluate the BSDF from wi to wo.
  17. * Evaluation is split into the analytical single-scattering BSDF and the multi-scattering BSDF,
  18. * which is evaluated stochastically through a random walk. At each bounce (except for the first
  19. * one), the amount of reflection from here towards wo is evaluated before bouncing again.
  20. *
  21. * Because of the random walk, the evaluation is not deterministic, but its expected value is equal
  22. * to the correct BSDF, which is enough for Monte-Carlo rendering. The PDF also can't be determined
  23. * analytically, so the single-scattering PDF plus a diffuse term to account for the
  24. * multi-scattered energy is used. In combination with MIS, that is enough to produce an unbiased
  25. * result, although the balance heuristic isn't necessarily optimal anymore.
  26. */
  27. ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi,
  28. float3 wo,
  29. const bool wo_outside,
  30. const float3 color,
  31. const float alpha_x,
  32. const float alpha_y,
  33. ccl_addr_space uint *lcg_state,
  34. const float eta,
  35. bool use_fresnel,
  36. const float3 cspec0)
  37. {
  38. /* Evaluating for a shallower incoming direction produces less noise, and the properties of the
  39. * BSDF guarantee reciprocity. */
  40. bool swapped = false;
  41. #ifdef MF_MULTI_GLASS
  42. if (wi.z * wo.z < 0.0f) {
  43. /* Glass transmission is a special case and requires the directions to change hemisphere. */
  44. if (-wo.z < wi.z) {
  45. swapped = true;
  46. float3 tmp = -wo;
  47. wo = -wi;
  48. wi = tmp;
  49. }
  50. }
  51. else
  52. #endif
  53. if (wo.z < wi.z) {
  54. swapped = true;
  55. float3 tmp = wo;
  56. wo = wi;
  57. wi = tmp;
  58. }
  59. if (wi.z < 1e-5f || (wo.z < 1e-5f && wo_outside) || (wo.z > -1e-5f && !wo_outside))
  60. return make_float3(0.0f, 0.0f, 0.0f);
  61. const float2 alpha = make_float2(alpha_x, alpha_y);
  62. float lambda_r = mf_lambda(-wi, alpha);
  63. float shadowing_lambda = mf_lambda(wo_outside ? wo : -wo, alpha);
  64. /* Analytically compute single scattering for lower noise. */
  65. float3 eval;
  66. float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
  67. const float3 wh = normalize(wi + wo);
  68. #ifdef MF_MULTI_GLASS
  69. eval = mf_eval_phase_glass(-wi, lambda_r, wo, wo_outside, alpha, eta);
  70. if (wo_outside)
  71. eval *= -lambda_r / (shadowing_lambda - lambda_r);
  72. else
  73. eval *= -lambda_r * beta(-lambda_r, shadowing_lambda + 1.0f);
  74. #else /* MF_MULTI_GLOSSY */
  75. const float G2 = 1.0f / (1.0f - (lambda_r + 1.0f) + shadowing_lambda);
  76. float val = G2 * 0.25f / wi.z;
  77. if (alpha.x == alpha.y)
  78. val *= D_ggx(wh, alpha.x);
  79. else
  80. val *= D_ggx_aniso(wh, alpha);
  81. eval = make_float3(val, val, val);
  82. #endif
  83. float F0 = fresnel_dielectric_cos(1.0f, eta);
  84. if (use_fresnel) {
  85. throughput = interpolate_fresnel_color(wi, wh, eta, F0, cspec0);
  86. eval *= throughput;
  87. }
  88. float3 wr = -wi;
  89. float hr = 1.0f;
  90. float C1_r = 1.0f;
  91. float G1_r = 0.0f;
  92. bool outside = true;
  93. for (int order = 0; order < 10; order++) {
  94. /* Sample microfacet height. */
  95. float height_rand = lcg_step_float_addrspace(lcg_state);
  96. if (!mf_sample_height(wr, &hr, &C1_r, &G1_r, &lambda_r, height_rand))
  97. break;
  98. /* Sample microfacet normal. */
  99. float vndf_rand_y = lcg_step_float_addrspace(lcg_state);
  100. float vndf_rand_x = lcg_step_float_addrspace(lcg_state);
  101. float3 wm = mf_sample_vndf(-wr, alpha, vndf_rand_x, vndf_rand_y);
  102. #ifdef MF_MULTI_GLASS
  103. if (order == 0 && use_fresnel) {
  104. /* Evaluate amount of scattering towards wo on this microfacet. */
  105. float3 phase;
  106. if (outside)
  107. phase = mf_eval_phase_glass(wr, lambda_r, wo, wo_outside, alpha, eta);
  108. else
  109. phase = mf_eval_phase_glass(wr, lambda_r, -wo, !wo_outside, alpha, 1.0f / eta);
  110. eval = throughput * phase *
  111. mf_G1(wo_outside ? wo : -wo,
  112. mf_C1((outside == wo_outside) ? hr : -hr),
  113. shadowing_lambda);
  114. }
  115. #endif
  116. if (order > 0) {
  117. /* Evaluate amount of scattering towards wo on this microfacet. */
  118. float3 phase;
  119. #ifdef MF_MULTI_GLASS
  120. if (outside)
  121. phase = mf_eval_phase_glass(wr, lambda_r, wo, wo_outside, alpha, eta);
  122. else
  123. phase = mf_eval_phase_glass(wr, lambda_r, -wo, !wo_outside, alpha, 1.0f / eta);
  124. #else /* MF_MULTI_GLOSSY */
  125. phase = mf_eval_phase_glossy(wr, lambda_r, wo, alpha) * throughput;
  126. #endif
  127. eval += throughput * phase *
  128. mf_G1(wo_outside ? wo : -wo,
  129. mf_C1((outside == wo_outside) ? hr : -hr),
  130. shadowing_lambda);
  131. }
  132. if (order + 1 < 10) {
  133. /* Bounce from the microfacet. */
  134. #ifdef MF_MULTI_GLASS
  135. bool next_outside;
  136. float3 wi_prev = -wr;
  137. float phase_rand = lcg_step_float_addrspace(lcg_state);
  138. wr = mf_sample_phase_glass(-wr, outside ? eta : 1.0f / eta, wm, phase_rand, &next_outside);
  139. if (!next_outside) {
  140. outside = !outside;
  141. wr = -wr;
  142. hr = -hr;
  143. }
  144. if (use_fresnel && !next_outside) {
  145. throughput *= color;
  146. }
  147. else if (use_fresnel && order > 0) {
  148. throughput *= interpolate_fresnel_color(wi_prev, wm, eta, F0, cspec0);
  149. }
  150. #else /* MF_MULTI_GLOSSY */
  151. if (use_fresnel && order > 0) {
  152. throughput *= interpolate_fresnel_color(-wr, wm, eta, F0, cspec0);
  153. }
  154. wr = mf_sample_phase_glossy(-wr, &throughput, wm);
  155. #endif
  156. lambda_r = mf_lambda(wr, alpha);
  157. if (!use_fresnel)
  158. throughput *= color;
  159. C1_r = mf_C1(hr);
  160. G1_r = mf_G1(wr, C1_r, lambda_r);
  161. }
  162. }
  163. if (swapped)
  164. eval *= fabsf(wi.z / wo.z);
  165. return eval;
  166. }
  167. /* Perform a random walk on the microsurface starting from wi, returning the direction in which the
  168. * walk escaped the surface in wo. The function returns the throughput between wi and wo. Without
  169. * reflection losses due to coloring or fresnel absorption in conductors, the sampling is optimal.
  170. */
  171. ccl_device_forceinline float3 MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi,
  172. float3 *wo,
  173. const float3 color,
  174. const float alpha_x,
  175. const float alpha_y,
  176. ccl_addr_space uint *lcg_state,
  177. const float eta,
  178. bool use_fresnel,
  179. const float3 cspec0)
  180. {
  181. const float2 alpha = make_float2(alpha_x, alpha_y);
  182. float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
  183. float3 wr = -wi;
  184. float lambda_r = mf_lambda(wr, alpha);
  185. float hr = 1.0f;
  186. float C1_r = 1.0f;
  187. float G1_r = 0.0f;
  188. bool outside = true;
  189. float F0 = fresnel_dielectric_cos(1.0f, eta);
  190. if (use_fresnel) {
  191. throughput = interpolate_fresnel_color(wi, normalize(wi + wr), eta, F0, cspec0);
  192. }
  193. int order;
  194. for (order = 0; order < 10; order++) {
  195. /* Sample microfacet height. */
  196. float height_rand = lcg_step_float_addrspace(lcg_state);
  197. if (!mf_sample_height(wr, &hr, &C1_r, &G1_r, &lambda_r, height_rand)) {
  198. /* The random walk has left the surface. */
  199. *wo = outside ? wr : -wr;
  200. return throughput;
  201. }
  202. /* Sample microfacet normal. */
  203. float vndf_rand_y = lcg_step_float_addrspace(lcg_state);
  204. float vndf_rand_x = lcg_step_float_addrspace(lcg_state);
  205. float3 wm = mf_sample_vndf(-wr, alpha, vndf_rand_x, vndf_rand_y);
  206. /* First-bounce color is already accounted for in mix weight. */
  207. if (!use_fresnel && order > 0)
  208. throughput *= color;
  209. /* Bounce from the microfacet. */
  210. #ifdef MF_MULTI_GLASS
  211. bool next_outside;
  212. float3 wi_prev = -wr;
  213. float phase_rand = lcg_step_float_addrspace(lcg_state);
  214. wr = mf_sample_phase_glass(-wr, outside ? eta : 1.0f / eta, wm, phase_rand, &next_outside);
  215. if (!next_outside) {
  216. hr = -hr;
  217. wr = -wr;
  218. outside = !outside;
  219. }
  220. if (use_fresnel) {
  221. if (!next_outside) {
  222. throughput *= color;
  223. }
  224. else {
  225. float3 t_color = interpolate_fresnel_color(wi_prev, wm, eta, F0, cspec0);
  226. if (order == 0)
  227. throughput = t_color;
  228. else
  229. throughput *= t_color;
  230. }
  231. }
  232. #else /* MF_MULTI_GLOSSY */
  233. if (use_fresnel) {
  234. float3 t_color = interpolate_fresnel_color(-wr, wm, eta, F0, cspec0);
  235. if (order == 0)
  236. throughput = t_color;
  237. else
  238. throughput *= t_color;
  239. }
  240. wr = mf_sample_phase_glossy(-wr, &throughput, wm);
  241. #endif
  242. /* Update random walk parameters. */
  243. lambda_r = mf_lambda(wr, alpha);
  244. G1_r = mf_G1(wr, C1_r, lambda_r);
  245. }
  246. *wo = make_float3(0.0f, 0.0f, 1.0f);
  247. return make_float3(0.0f, 0.0f, 0.0f);
  248. }
  249. #undef MF_MULTI_GLASS
  250. #undef MF_MULTI_GLOSSY
  251. #undef MF_PHASE_FUNCTION