bsdf_microfacet_multi.h 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771
  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. CCL_NAMESPACE_BEGIN
  17. /* Most of the code is based on the supplemental implementations from
  18. * https://eheitzresearch.wordpress.com/240-2/. */
  19. /* === GGX Microfacet distribution functions === */
  20. /* Isotropic GGX microfacet distribution */
  21. ccl_device_forceinline float D_ggx(float3 wm, float alpha)
  22. {
  23. wm.z *= wm.z;
  24. alpha *= alpha;
  25. float tmp = (1.0f - wm.z) + alpha * wm.z;
  26. return alpha / max(M_PI_F * tmp * tmp, 1e-7f);
  27. }
  28. /* Anisotropic GGX microfacet distribution */
  29. ccl_device_forceinline float D_ggx_aniso(const float3 wm, const float2 alpha)
  30. {
  31. float slope_x = -wm.x / alpha.x;
  32. float slope_y = -wm.y / alpha.y;
  33. float tmp = wm.z * wm.z + slope_x * slope_x + slope_y * slope_y;
  34. return 1.0f / max(M_PI_F * tmp * tmp * alpha.x * alpha.y, 1e-7f);
  35. }
  36. /* Sample slope distribution (based on page 14 of the supplemental implementation). */
  37. ccl_device_forceinline float2 mf_sampleP22_11(const float cosI,
  38. const float randx,
  39. const float randy)
  40. {
  41. if (cosI > 0.9999f || fabsf(cosI) < 1e-6f) {
  42. const float r = sqrtf(randx / max(1.0f - randx, 1e-7f));
  43. const float phi = M_2PI_F * randy;
  44. return make_float2(r * cosf(phi), r * sinf(phi));
  45. }
  46. const float sinI = safe_sqrtf(1.0f - cosI * cosI);
  47. const float tanI = sinI / cosI;
  48. const float projA = 0.5f * (cosI + 1.0f);
  49. if (projA < 0.0001f)
  50. return make_float2(0.0f, 0.0f);
  51. const float A = 2.0f * randx * projA / cosI - 1.0f;
  52. float tmp = A * A - 1.0f;
  53. if (fabsf(tmp) < 1e-7f)
  54. return make_float2(0.0f, 0.0f);
  55. tmp = 1.0f / tmp;
  56. const float D = safe_sqrtf(tanI * tanI * tmp * tmp - (A * A - tanI * tanI) * tmp);
  57. const float slopeX2 = tanI * tmp + D;
  58. const float slopeX = (A < 0.0f || slopeX2 > 1.0f / tanI) ? (tanI * tmp - D) : slopeX2;
  59. float U2;
  60. if (randy >= 0.5f)
  61. U2 = 2.0f * (randy - 0.5f);
  62. else
  63. U2 = 2.0f * (0.5f - randy);
  64. const float z = (U2 * (U2 * (U2 * 0.27385f - 0.73369f) + 0.46341f)) /
  65. (U2 * (U2 * (U2 * 0.093073f + 0.309420f) - 1.0f) + 0.597999f);
  66. const float slopeY = z * sqrtf(1.0f + slopeX * slopeX);
  67. if (randy >= 0.5f)
  68. return make_float2(slopeX, slopeY);
  69. else
  70. return make_float2(slopeX, -slopeY);
  71. }
  72. /* Visible normal sampling for the GGX distribution
  73. * (based on page 7 of the supplemental implementation). */
  74. ccl_device_forceinline float3 mf_sample_vndf(const float3 wi,
  75. const float2 alpha,
  76. const float randx,
  77. const float randy)
  78. {
  79. const float3 wi_11 = normalize(make_float3(alpha.x * wi.x, alpha.y * wi.y, wi.z));
  80. const float2 slope_11 = mf_sampleP22_11(wi_11.z, randx, randy);
  81. const float3 cossin_phi = safe_normalize(make_float3(wi_11.x, wi_11.y, 0.0f));
  82. const float slope_x = alpha.x * (cossin_phi.x * slope_11.x - cossin_phi.y * slope_11.y);
  83. const float slope_y = alpha.y * (cossin_phi.y * slope_11.x + cossin_phi.x * slope_11.y);
  84. kernel_assert(isfinite(slope_x));
  85. return normalize(make_float3(-slope_x, -slope_y, 1.0f));
  86. }
  87. /* === Phase functions: Glossy and Glass === */
  88. /* Phase function for reflective materials. */
  89. ccl_device_forceinline float3 mf_sample_phase_glossy(const float3 wi,
  90. float3 *weight,
  91. const float3 wm)
  92. {
  93. return -wi + 2.0f * wm * dot(wi, wm);
  94. }
  95. ccl_device_forceinline float3 mf_eval_phase_glossy(const float3 w,
  96. const float lambda,
  97. const float3 wo,
  98. const float2 alpha)
  99. {
  100. if (w.z > 0.9999f)
  101. return make_float3(0.0f, 0.0f, 0.0f);
  102. const float3 wh = normalize(wo - w);
  103. if (wh.z < 0.0f)
  104. return make_float3(0.0f, 0.0f, 0.0f);
  105. float pArea = (w.z < -0.9999f) ? 1.0f : lambda * w.z;
  106. const float dotW_WH = dot(-w, wh);
  107. if (dotW_WH < 0.0f)
  108. return make_float3(0.0f, 0.0f, 0.0f);
  109. float phase = max(0.0f, dotW_WH) * 0.25f / max(pArea * dotW_WH, 1e-7f);
  110. if (alpha.x == alpha.y)
  111. phase *= D_ggx(wh, alpha.x);
  112. else
  113. phase *= D_ggx_aniso(wh, alpha);
  114. return make_float3(phase, phase, phase);
  115. }
  116. /* Phase function for dielectric transmissive materials, including both reflection and refraction
  117. * according to the dielectric fresnel term. */
  118. ccl_device_forceinline float3 mf_sample_phase_glass(
  119. const float3 wi, const float eta, const float3 wm, const float randV, bool *outside)
  120. {
  121. float cosI = dot(wi, wm);
  122. float f = fresnel_dielectric_cos(cosI, eta);
  123. if (randV < f) {
  124. *outside = true;
  125. return -wi + 2.0f * wm * cosI;
  126. }
  127. *outside = false;
  128. float inv_eta = 1.0f / eta;
  129. float cosT = -safe_sqrtf(1.0f - (1.0f - cosI * cosI) * inv_eta * inv_eta);
  130. return normalize(wm * (cosI * inv_eta + cosT) - wi * inv_eta);
  131. }
  132. ccl_device_forceinline float3 mf_eval_phase_glass(const float3 w,
  133. const float lambda,
  134. const float3 wo,
  135. const bool wo_outside,
  136. const float2 alpha,
  137. const float eta)
  138. {
  139. if (w.z > 0.9999f)
  140. return make_float3(0.0f, 0.0f, 0.0f);
  141. float pArea = (w.z < -0.9999f) ? 1.0f : lambda * w.z;
  142. float v;
  143. if (wo_outside) {
  144. const float3 wh = normalize(wo - w);
  145. if (wh.z < 0.0f)
  146. return make_float3(0.0f, 0.0f, 0.0f);
  147. const float dotW_WH = dot(-w, wh);
  148. v = fresnel_dielectric_cos(dotW_WH, eta) * max(0.0f, dotW_WH) * D_ggx(wh, alpha.x) * 0.25f /
  149. (pArea * dotW_WH);
  150. }
  151. else {
  152. float3 wh = normalize(wo * eta - w);
  153. if (wh.z < 0.0f)
  154. wh = -wh;
  155. const float dotW_WH = dot(-w, wh), dotWO_WH = dot(wo, wh);
  156. if (dotW_WH < 0.0f)
  157. return make_float3(0.0f, 0.0f, 0.0f);
  158. float temp = dotW_WH + eta * dotWO_WH;
  159. v = (1.0f - fresnel_dielectric_cos(dotW_WH, eta)) * max(0.0f, dotW_WH) * max(0.0f, -dotWO_WH) *
  160. D_ggx(wh, alpha.x) / (pArea * temp * temp);
  161. }
  162. return make_float3(v, v, v);
  163. }
  164. /* === Utility functions for the random walks === */
  165. /* Smith Lambda function for GGX (based on page 12 of the supplemental implementation). */
  166. ccl_device_forceinline float mf_lambda(const float3 w, const float2 alpha)
  167. {
  168. if (w.z > 0.9999f)
  169. return 0.0f;
  170. else if (w.z < -0.9999f)
  171. return -0.9999f;
  172. const float inv_wz2 = 1.0f / max(w.z * w.z, 1e-7f);
  173. const float2 wa = make_float2(w.x, w.y) * alpha;
  174. float v = sqrtf(1.0f + dot(wa, wa) * inv_wz2);
  175. if (w.z <= 0.0f)
  176. v = -v;
  177. return 0.5f * (v - 1.0f);
  178. }
  179. /* Height distribution CDF (based on page 4 of the supplemental implementation). */
  180. ccl_device_forceinline float mf_invC1(const float h)
  181. {
  182. return 2.0f * saturate(h) - 1.0f;
  183. }
  184. ccl_device_forceinline float mf_C1(const float h)
  185. {
  186. return saturate(0.5f * (h + 1.0f));
  187. }
  188. /* Masking function (based on page 16 of the supplemental implementation). */
  189. ccl_device_forceinline float mf_G1(const float3 w, const float C1, const float lambda)
  190. {
  191. if (w.z > 0.9999f)
  192. return 1.0f;
  193. if (w.z < 1e-5f)
  194. return 0.0f;
  195. return powf(C1, lambda);
  196. }
  197. /* Sampling from the visible height distribution (based on page 17 of the supplemental
  198. * implementation). */
  199. ccl_device_forceinline bool mf_sample_height(
  200. const float3 w, float *h, float *C1, float *G1, float *lambda, const float U)
  201. {
  202. if (w.z > 0.9999f)
  203. return false;
  204. if (w.z < -0.9999f) {
  205. *C1 *= U;
  206. *h = mf_invC1(*C1);
  207. *G1 = mf_G1(w, *C1, *lambda);
  208. }
  209. else if (fabsf(w.z) >= 0.0001f) {
  210. if (U > 1.0f - *G1)
  211. return false;
  212. if (*lambda >= 0.0f) {
  213. *C1 = 1.0f;
  214. }
  215. else {
  216. *C1 *= powf(1.0f - U, -1.0f / *lambda);
  217. }
  218. *h = mf_invC1(*C1);
  219. *G1 = mf_G1(w, *C1, *lambda);
  220. }
  221. return true;
  222. }
  223. /* === PDF approximations for the different phase functions. ===
  224. * As explained in bsdf_microfacet_multi_impl.h, using approximations with MIS still produces an
  225. * unbiased result. */
  226. /* Approximation for the albedo of the single-scattering GGX distribution,
  227. * the missing energy is then approximated as a diffuse reflection for the PDF. */
  228. ccl_device_forceinline float mf_ggx_albedo(float r)
  229. {
  230. float albedo = 0.806495f * expf(-1.98712f * r * r) + 0.199531f;
  231. albedo -= ((((((1.76741f * r - 8.43891f) * r + 15.784f) * r - 14.398f) * r + 6.45221f) * r -
  232. 1.19722f) *
  233. r +
  234. 0.027803f) *
  235. r +
  236. 0.00568739f;
  237. return saturate(albedo);
  238. }
  239. ccl_device_inline float mf_ggx_transmission_albedo(float a, float ior)
  240. {
  241. if (ior < 1.0f) {
  242. ior = 1.0f / ior;
  243. }
  244. a = saturate(a);
  245. ior = clamp(ior, 1.0f, 3.0f);
  246. float I_1 = 0.0476898f * expf(-0.978352f * (ior - 0.65657f) * (ior - 0.65657f)) -
  247. 0.033756f * ior + 0.993261f;
  248. float R_1 = (((0.116991f * a - 0.270369f) * a + 0.0501366f) * a - 0.00411511f) * a + 1.00008f;
  249. float I_2 = (((-2.08704f * ior + 26.3298f) * ior - 127.906f) * ior + 292.958f) * ior - 287.946f +
  250. 199.803f / (ior * ior) - 101.668f / (ior * ior * ior);
  251. float R_2 = ((((5.3725f * a - 24.9307f) * a + 22.7437f) * a - 3.40751f) * a + 0.0986325f) * a +
  252. 0.00493504f;
  253. return saturate(1.0f + I_2 * R_2 * 0.0019127f - (1.0f - I_1) * (1.0f - R_1) * 9.3205f);
  254. }
  255. ccl_device_forceinline float mf_ggx_pdf(const float3 wi, const float3 wo, const float alpha)
  256. {
  257. float D = D_ggx(normalize(wi + wo), alpha);
  258. float lambda = mf_lambda(wi, make_float2(alpha, alpha));
  259. float singlescatter = 0.25f * D / max((1.0f + lambda) * wi.z, 1e-7f);
  260. float multiscatter = wo.z * M_1_PI_F;
  261. float albedo = mf_ggx_albedo(alpha);
  262. return albedo * singlescatter + (1.0f - albedo) * multiscatter;
  263. }
  264. ccl_device_forceinline float mf_ggx_aniso_pdf(const float3 wi, const float3 wo, const float2 alpha)
  265. {
  266. float D = D_ggx_aniso(normalize(wi + wo), alpha);
  267. float lambda = mf_lambda(wi, alpha);
  268. float singlescatter = 0.25f * D / max((1.0f + lambda) * wi.z, 1e-7f);
  269. float multiscatter = wo.z * M_1_PI_F;
  270. float albedo = mf_ggx_albedo(sqrtf(alpha.x * alpha.y));
  271. return albedo * singlescatter + (1.0f - albedo) * multiscatter;
  272. }
  273. ccl_device_forceinline float mf_glass_pdf(const float3 wi,
  274. const float3 wo,
  275. const float alpha,
  276. const float eta)
  277. {
  278. bool reflective = (wi.z * wo.z > 0.0f);
  279. float wh_len;
  280. float3 wh = normalize_len(wi + (reflective ? wo : (wo * eta)), &wh_len);
  281. if (wh.z < 0.0f)
  282. wh = -wh;
  283. float3 r_wi = (wi.z < 0.0f) ? -wi : wi;
  284. float lambda = mf_lambda(r_wi, make_float2(alpha, alpha));
  285. float D = D_ggx(wh, alpha);
  286. float fresnel = fresnel_dielectric_cos(dot(r_wi, wh), eta);
  287. float multiscatter = fabsf(wo.z * M_1_PI_F);
  288. if (reflective) {
  289. float singlescatter = 0.25f * D / max((1.0f + lambda) * r_wi.z, 1e-7f);
  290. float albedo = mf_ggx_albedo(alpha);
  291. return fresnel * (albedo * singlescatter + (1.0f - albedo) * multiscatter);
  292. }
  293. else {
  294. float singlescatter = fabsf(dot(r_wi, wh) * dot(wo, wh) * D * eta * eta /
  295. max((1.0f + lambda) * r_wi.z * wh_len * wh_len, 1e-7f));
  296. float albedo = mf_ggx_transmission_albedo(alpha, eta);
  297. return (1.0f - fresnel) * (albedo * singlescatter + (1.0f - albedo) * multiscatter);
  298. }
  299. }
  300. /* === Actual random walk implementations === */
  301. /* One version of mf_eval and mf_sample per phase function. */
  302. #define MF_NAME_JOIN(x, y) x##_##y
  303. #define MF_NAME_EVAL(x, y) MF_NAME_JOIN(x, y)
  304. #define MF_FUNCTION_FULL_NAME(prefix) MF_NAME_EVAL(prefix, MF_PHASE_FUNCTION)
  305. #define MF_PHASE_FUNCTION glass
  306. #define MF_MULTI_GLASS
  307. #include "kernel/closure/bsdf_microfacet_multi_impl.h"
  308. #define MF_PHASE_FUNCTION glossy
  309. #define MF_MULTI_GLOSSY
  310. #include "kernel/closure/bsdf_microfacet_multi_impl.h"
  311. ccl_device void bsdf_microfacet_multi_ggx_blur(ShaderClosure *sc, float roughness)
  312. {
  313. MicrofacetBsdf *bsdf = (MicrofacetBsdf *)sc;
  314. bsdf->alpha_x = fmaxf(roughness, bsdf->alpha_x);
  315. bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y);
  316. }
  317. /* === Closure implementations === */
  318. /* Multiscattering GGX Glossy closure */
  319. ccl_device int bsdf_microfacet_multi_ggx_common_setup(MicrofacetBsdf *bsdf)
  320. {
  321. bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
  322. bsdf->alpha_y = clamp(bsdf->alpha_y, 1e-4f, 1.0f);
  323. bsdf->extra->color.x = saturate(bsdf->extra->color.x);
  324. bsdf->extra->color.y = saturate(bsdf->extra->color.y);
  325. bsdf->extra->color.z = saturate(bsdf->extra->color.z);
  326. bsdf->extra->cspec0.x = saturate(bsdf->extra->cspec0.x);
  327. bsdf->extra->cspec0.y = saturate(bsdf->extra->cspec0.y);
  328. bsdf->extra->cspec0.z = saturate(bsdf->extra->cspec0.z);
  329. return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
  330. }
  331. ccl_device int bsdf_microfacet_multi_ggx_aniso_setup(MicrofacetBsdf *bsdf)
  332. {
  333. if (is_zero(bsdf->T))
  334. bsdf->T = make_float3(1.0f, 0.0f, 0.0f);
  335. bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
  336. return bsdf_microfacet_multi_ggx_common_setup(bsdf);
  337. }
  338. ccl_device int bsdf_microfacet_multi_ggx_aniso_fresnel_setup(MicrofacetBsdf *bsdf,
  339. const ShaderData *sd)
  340. {
  341. if (is_zero(bsdf->T))
  342. bsdf->T = make_float3(1.0f, 0.0f, 0.0f);
  343. bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID;
  344. float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
  345. float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
  346. bsdf->sample_weight *= F;
  347. return bsdf_microfacet_multi_ggx_common_setup(bsdf);
  348. }
  349. ccl_device int bsdf_microfacet_multi_ggx_setup(MicrofacetBsdf *bsdf)
  350. {
  351. bsdf->alpha_y = bsdf->alpha_x;
  352. bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
  353. return bsdf_microfacet_multi_ggx_common_setup(bsdf);
  354. }
  355. ccl_device int bsdf_microfacet_multi_ggx_fresnel_setup(MicrofacetBsdf *bsdf, const ShaderData *sd)
  356. {
  357. bsdf->alpha_y = bsdf->alpha_x;
  358. bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID;
  359. float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
  360. float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
  361. bsdf->sample_weight *= F;
  362. return bsdf_microfacet_multi_ggx_common_setup(bsdf);
  363. }
  364. ccl_device int bsdf_microfacet_multi_ggx_refraction_setup(MicrofacetBsdf *bsdf)
  365. {
  366. bsdf->alpha_y = bsdf->alpha_x;
  367. bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
  368. return bsdf_microfacet_multi_ggx_common_setup(bsdf);
  369. }
  370. ccl_device float3 bsdf_microfacet_multi_ggx_eval_transmit(const ShaderClosure *sc,
  371. const float3 I,
  372. const float3 omega_in,
  373. float *pdf,
  374. ccl_addr_space uint *lcg_state)
  375. {
  376. *pdf = 0.0f;
  377. return make_float3(0.0f, 0.0f, 0.0f);
  378. }
  379. ccl_device float3 bsdf_microfacet_multi_ggx_eval_reflect(const ShaderClosure *sc,
  380. const float3 I,
  381. const float3 omega_in,
  382. float *pdf,
  383. ccl_addr_space uint *lcg_state)
  384. {
  385. const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
  386. if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
  387. return make_float3(0.0f, 0.0f, 0.0f);
  388. }
  389. bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID);
  390. bool is_aniso = (bsdf->alpha_x != bsdf->alpha_y);
  391. float3 X, Y, Z;
  392. Z = bsdf->N;
  393. if (is_aniso)
  394. make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
  395. else
  396. make_orthonormals(Z, &X, &Y);
  397. float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
  398. float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
  399. if (is_aniso)
  400. *pdf = mf_ggx_aniso_pdf(localI, localO, make_float2(bsdf->alpha_x, bsdf->alpha_y));
  401. else
  402. *pdf = mf_ggx_pdf(localI, localO, bsdf->alpha_x);
  403. return mf_eval_glossy(localI,
  404. localO,
  405. true,
  406. bsdf->extra->color,
  407. bsdf->alpha_x,
  408. bsdf->alpha_y,
  409. lcg_state,
  410. bsdf->ior,
  411. use_fresnel,
  412. bsdf->extra->cspec0);
  413. }
  414. ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals *kg,
  415. const ShaderClosure *sc,
  416. float3 Ng,
  417. float3 I,
  418. float3 dIdx,
  419. float3 dIdy,
  420. float randu,
  421. float randv,
  422. float3 *eval,
  423. float3 *omega_in,
  424. float3 *domega_in_dx,
  425. float3 *domega_in_dy,
  426. float *pdf,
  427. ccl_addr_space uint *lcg_state)
  428. {
  429. const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
  430. float3 X, Y, Z;
  431. Z = bsdf->N;
  432. if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
  433. *omega_in = 2 * dot(Z, I) * Z - I;
  434. *pdf = 1e6f;
  435. *eval = make_float3(1e6f, 1e6f, 1e6f);
  436. #ifdef __RAY_DIFFERENTIALS__
  437. *domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx;
  438. *domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy;
  439. #endif
  440. return LABEL_REFLECT | LABEL_SINGULAR;
  441. }
  442. bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID);
  443. bool is_aniso = (bsdf->alpha_x != bsdf->alpha_y);
  444. if (is_aniso)
  445. make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
  446. else
  447. make_orthonormals(Z, &X, &Y);
  448. float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
  449. float3 localO;
  450. *eval = mf_sample_glossy(localI,
  451. &localO,
  452. bsdf->extra->color,
  453. bsdf->alpha_x,
  454. bsdf->alpha_y,
  455. lcg_state,
  456. bsdf->ior,
  457. use_fresnel,
  458. bsdf->extra->cspec0);
  459. if (is_aniso)
  460. *pdf = mf_ggx_aniso_pdf(localI, localO, make_float2(bsdf->alpha_x, bsdf->alpha_y));
  461. else
  462. *pdf = mf_ggx_pdf(localI, localO, bsdf->alpha_x);
  463. *eval *= *pdf;
  464. *omega_in = X * localO.x + Y * localO.y + Z * localO.z;
  465. #ifdef __RAY_DIFFERENTIALS__
  466. *domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx;
  467. *domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy;
  468. #endif
  469. return LABEL_REFLECT | LABEL_GLOSSY;
  470. }
  471. /* Multiscattering GGX Glass closure */
  472. ccl_device int bsdf_microfacet_multi_ggx_glass_setup(MicrofacetBsdf *bsdf)
  473. {
  474. bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
  475. bsdf->alpha_y = bsdf->alpha_x;
  476. bsdf->ior = max(0.0f, bsdf->ior);
  477. bsdf->extra->color.x = saturate(bsdf->extra->color.x);
  478. bsdf->extra->color.y = saturate(bsdf->extra->color.y);
  479. bsdf->extra->color.z = saturate(bsdf->extra->color.z);
  480. bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
  481. return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
  482. }
  483. ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(MicrofacetBsdf *bsdf,
  484. const ShaderData *sd)
  485. {
  486. bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
  487. bsdf->alpha_y = bsdf->alpha_x;
  488. bsdf->ior = max(0.0f, bsdf->ior);
  489. bsdf->extra->color.x = saturate(bsdf->extra->color.x);
  490. bsdf->extra->color.y = saturate(bsdf->extra->color.y);
  491. bsdf->extra->color.z = saturate(bsdf->extra->color.z);
  492. bsdf->extra->cspec0.x = saturate(bsdf->extra->cspec0.x);
  493. bsdf->extra->cspec0.y = saturate(bsdf->extra->cspec0.y);
  494. bsdf->extra->cspec0.z = saturate(bsdf->extra->cspec0.z);
  495. bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID;
  496. float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
  497. float F = average(interpolate_fresnel_color(sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0));
  498. bsdf->sample_weight *= F;
  499. return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
  500. }
  501. ccl_device float3 bsdf_microfacet_multi_ggx_glass_eval_transmit(const ShaderClosure *sc,
  502. const float3 I,
  503. const float3 omega_in,
  504. float *pdf,
  505. ccl_addr_space uint *lcg_state)
  506. {
  507. const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
  508. if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
  509. return make_float3(0.0f, 0.0f, 0.0f);
  510. }
  511. float3 X, Y, Z;
  512. Z = bsdf->N;
  513. make_orthonormals(Z, &X, &Y);
  514. float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
  515. float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
  516. *pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior);
  517. return mf_eval_glass(localI,
  518. localO,
  519. false,
  520. bsdf->extra->color,
  521. bsdf->alpha_x,
  522. bsdf->alpha_y,
  523. lcg_state,
  524. bsdf->ior,
  525. false,
  526. bsdf->extra->color);
  527. }
  528. ccl_device float3 bsdf_microfacet_multi_ggx_glass_eval_reflect(const ShaderClosure *sc,
  529. const float3 I,
  530. const float3 omega_in,
  531. float *pdf,
  532. ccl_addr_space uint *lcg_state)
  533. {
  534. const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
  535. if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
  536. return make_float3(0.0f, 0.0f, 0.0f);
  537. }
  538. bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID);
  539. float3 X, Y, Z;
  540. Z = bsdf->N;
  541. make_orthonormals(Z, &X, &Y);
  542. float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
  543. float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z));
  544. *pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior);
  545. return mf_eval_glass(localI,
  546. localO,
  547. true,
  548. bsdf->extra->color,
  549. bsdf->alpha_x,
  550. bsdf->alpha_y,
  551. lcg_state,
  552. bsdf->ior,
  553. use_fresnel,
  554. bsdf->extra->cspec0);
  555. }
  556. ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals *kg,
  557. const ShaderClosure *sc,
  558. float3 Ng,
  559. float3 I,
  560. float3 dIdx,
  561. float3 dIdy,
  562. float randu,
  563. float randv,
  564. float3 *eval,
  565. float3 *omega_in,
  566. float3 *domega_in_dx,
  567. float3 *domega_in_dy,
  568. float *pdf,
  569. ccl_addr_space uint *lcg_state)
  570. {
  571. const MicrofacetBsdf *bsdf = (const MicrofacetBsdf *)sc;
  572. float3 X, Y, Z;
  573. Z = bsdf->N;
  574. if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
  575. float3 R, T;
  576. #ifdef __RAY_DIFFERENTIALS__
  577. float3 dRdx, dRdy, dTdx, dTdy;
  578. #endif
  579. bool inside;
  580. float fresnel = fresnel_dielectric(bsdf->ior,
  581. Z,
  582. I,
  583. &R,
  584. &T,
  585. #ifdef __RAY_DIFFERENTIALS__
  586. dIdx,
  587. dIdy,
  588. &dRdx,
  589. &dRdy,
  590. &dTdx,
  591. &dTdy,
  592. #endif
  593. &inside);
  594. *pdf = 1e6f;
  595. *eval = make_float3(1e6f, 1e6f, 1e6f);
  596. if (randu < fresnel) {
  597. *omega_in = R;
  598. #ifdef __RAY_DIFFERENTIALS__
  599. *domega_in_dx = dRdx;
  600. *domega_in_dy = dRdy;
  601. #endif
  602. return LABEL_REFLECT | LABEL_SINGULAR;
  603. }
  604. else {
  605. *omega_in = T;
  606. #ifdef __RAY_DIFFERENTIALS__
  607. *domega_in_dx = dTdx;
  608. *domega_in_dy = dTdy;
  609. #endif
  610. return LABEL_TRANSMIT | LABEL_SINGULAR;
  611. }
  612. }
  613. bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID);
  614. make_orthonormals(Z, &X, &Y);
  615. float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z));
  616. float3 localO;
  617. *eval = mf_sample_glass(localI,
  618. &localO,
  619. bsdf->extra->color,
  620. bsdf->alpha_x,
  621. bsdf->alpha_y,
  622. lcg_state,
  623. bsdf->ior,
  624. use_fresnel,
  625. bsdf->extra->cspec0);
  626. *pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior);
  627. *eval *= *pdf;
  628. *omega_in = X * localO.x + Y * localO.y + Z * localO.z;
  629. if (localO.z * localI.z > 0.0f) {
  630. #ifdef __RAY_DIFFERENTIALS__
  631. *domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx;
  632. *domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy;
  633. #endif
  634. return LABEL_REFLECT | LABEL_GLOSSY;
  635. }
  636. else {
  637. #ifdef __RAY_DIFFERENTIALS__
  638. float cosI = dot(Z, I);
  639. float dnp = max(sqrtf(1.0f - (bsdf->ior * bsdf->ior * (1.0f - cosI * cosI))), 1e-7f);
  640. *domega_in_dx = -(bsdf->ior * dIdx) +
  641. ((bsdf->ior - bsdf->ior * bsdf->ior * cosI / dnp) * dot(dIdx, Z)) * Z;
  642. *domega_in_dy = -(bsdf->ior * dIdy) +
  643. ((bsdf->ior - bsdf->ior * bsdf->ior * cosI / dnp) * dot(dIdy, Z)) * Z;
  644. #endif
  645. return LABEL_TRANSMIT | LABEL_GLOSSY;
  646. }
  647. }
  648. CCL_NAMESPACE_END