osl_closures.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908
  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 2011-2018, 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. #include <OSL/genclosure.h>
  33. #include <OSL/oslclosure.h>
  34. #include "kernel/osl/osl_closures.h"
  35. #include "kernel/osl/osl_shader.h"
  36. #include "util/util_math.h"
  37. #include "util/util_param.h"
  38. #include "kernel/kernel_types.h"
  39. #include "kernel/kernel_compat_cpu.h"
  40. #include "kernel/split/kernel_split_data_types.h"
  41. #include "kernel/kernel_globals.h"
  42. #include "kernel/kernel_montecarlo.h"
  43. #include "kernel/kernel_random.h"
  44. #include "kernel/closure/alloc.h"
  45. #include "kernel/closure/bsdf_util.h"
  46. #include "kernel/closure/bsdf_ashikhmin_velvet.h"
  47. #include "kernel/closure/bsdf_diffuse.h"
  48. #include "kernel/closure/bsdf_microfacet.h"
  49. #include "kernel/closure/bsdf_microfacet_multi.h"
  50. #include "kernel/closure/bsdf_oren_nayar.h"
  51. #include "kernel/closure/bsdf_reflection.h"
  52. #include "kernel/closure/bsdf_refraction.h"
  53. #include "kernel/closure/bsdf_transparent.h"
  54. #include "kernel/closure/bsdf_ashikhmin_shirley.h"
  55. #include "kernel/closure/bsdf_toon.h"
  56. #include "kernel/closure/bsdf_hair.h"
  57. #include "kernel/closure/bsdf_hair_principled.h"
  58. #include "kernel/closure/bsdf_principled_diffuse.h"
  59. #include "kernel/closure/bsdf_principled_sheen.h"
  60. #include "kernel/closure/volume.h"
  61. CCL_NAMESPACE_BEGIN
  62. using namespace OSL;
  63. /* BSDF class definitions */
  64. BSDF_CLOSURE_CLASS_BEGIN(Diffuse, diffuse, DiffuseBsdf, LABEL_DIFFUSE)
  65. CLOSURE_FLOAT3_PARAM(DiffuseClosure, params.N),
  66. BSDF_CLOSURE_CLASS_END(Diffuse, diffuse)
  67. BSDF_CLOSURE_CLASS_BEGIN(Translucent, translucent, DiffuseBsdf, LABEL_DIFFUSE)
  68. CLOSURE_FLOAT3_PARAM(TranslucentClosure, params.N),
  69. BSDF_CLOSURE_CLASS_END(Translucent, translucent)
  70. BSDF_CLOSURE_CLASS_BEGIN(OrenNayar, oren_nayar, OrenNayarBsdf, LABEL_DIFFUSE)
  71. CLOSURE_FLOAT3_PARAM(OrenNayarClosure, params.N),
  72. CLOSURE_FLOAT_PARAM(OrenNayarClosure, params.roughness),
  73. BSDF_CLOSURE_CLASS_END(OrenNayar, oren_nayar)
  74. BSDF_CLOSURE_CLASS_BEGIN(Reflection, reflection, MicrofacetBsdf, LABEL_SINGULAR)
  75. CLOSURE_FLOAT3_PARAM(ReflectionClosure, params.N),
  76. BSDF_CLOSURE_CLASS_END(Reflection, reflection)
  77. BSDF_CLOSURE_CLASS_BEGIN(Refraction, refraction, MicrofacetBsdf, LABEL_SINGULAR)
  78. CLOSURE_FLOAT3_PARAM(RefractionClosure, params.N),
  79. CLOSURE_FLOAT_PARAM(RefractionClosure, params.ior),
  80. BSDF_CLOSURE_CLASS_END(Refraction, refraction)
  81. BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, VelvetBsdf, LABEL_DIFFUSE)
  82. CLOSURE_FLOAT3_PARAM(AshikhminVelvetClosure, params.N),
  83. CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, params.sigma),
  84. BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet)
  85. BSDF_CLOSURE_CLASS_BEGIN(AshikhminShirley,
  86. ashikhmin_shirley_aniso,
  87. MicrofacetBsdf,
  88. LABEL_GLOSSY | LABEL_REFLECT)
  89. CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, params.N),
  90. CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, params.T),
  91. CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, params.alpha_x),
  92. CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, params.alpha_y),
  93. BSDF_CLOSURE_CLASS_END(AshikhminShirley, ashikhmin_shirley_aniso)
  94. BSDF_CLOSURE_CLASS_BEGIN(DiffuseToon, diffuse_toon, ToonBsdf, LABEL_DIFFUSE)
  95. CLOSURE_FLOAT3_PARAM(DiffuseToonClosure, params.N),
  96. CLOSURE_FLOAT_PARAM(DiffuseToonClosure, params.size),
  97. CLOSURE_FLOAT_PARAM(DiffuseToonClosure, params.smooth),
  98. BSDF_CLOSURE_CLASS_END(DiffuseToon, diffuse_toon)
  99. BSDF_CLOSURE_CLASS_BEGIN(GlossyToon, glossy_toon, ToonBsdf, LABEL_GLOSSY)
  100. CLOSURE_FLOAT3_PARAM(GlossyToonClosure, params.N),
  101. CLOSURE_FLOAT_PARAM(GlossyToonClosure, params.size),
  102. CLOSURE_FLOAT_PARAM(GlossyToonClosure, params.smooth),
  103. BSDF_CLOSURE_CLASS_END(GlossyToon, glossy_toon)
  104. BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX,
  105. microfacet_ggx,
  106. MicrofacetBsdf,
  107. LABEL_GLOSSY | LABEL_REFLECT)
  108. CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, params.N),
  109. CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, params.alpha_x),
  110. BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx)
  111. BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXAniso,
  112. microfacet_ggx_aniso,
  113. MicrofacetBsdf,
  114. LABEL_GLOSSY | LABEL_REFLECT)
  115. CLOSURE_FLOAT3_PARAM(MicrofacetGGXAnisoClosure, params.N),
  116. CLOSURE_FLOAT3_PARAM(MicrofacetGGXAnisoClosure, params.T),
  117. CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, params.alpha_x),
  118. CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, params.alpha_y),
  119. BSDF_CLOSURE_CLASS_END(MicrofacetGGXAniso, microfacet_ggx_aniso)
  120. BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann,
  121. microfacet_beckmann,
  122. MicrofacetBsdf,
  123. LABEL_GLOSSY | LABEL_REFLECT)
  124. CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, params.N),
  125. CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, params.alpha_x),
  126. BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann)
  127. BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannAniso,
  128. microfacet_beckmann_aniso,
  129. MicrofacetBsdf,
  130. LABEL_GLOSSY | LABEL_REFLECT)
  131. CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannAnisoClosure, params.N),
  132. CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannAnisoClosure, params.T),
  133. CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, params.alpha_x),
  134. CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, params.alpha_y),
  135. BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannAniso, microfacet_beckmann_aniso)
  136. BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction,
  137. microfacet_ggx_refraction,
  138. MicrofacetBsdf,
  139. LABEL_GLOSSY | LABEL_TRANSMIT)
  140. CLOSURE_FLOAT3_PARAM(MicrofacetGGXRefractionClosure, params.N),
  141. CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, params.alpha_x),
  142. CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, params.ior),
  143. BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction)
  144. BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction,
  145. microfacet_beckmann_refraction,
  146. MicrofacetBsdf,
  147. LABEL_GLOSSY | LABEL_TRANSMIT)
  148. CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannRefractionClosure, params.N),
  149. CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, params.alpha_x),
  150. CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, params.ior),
  151. BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction)
  152. BSDF_CLOSURE_CLASS_BEGIN(HairReflection, hair_reflection, HairBsdf, LABEL_GLOSSY)
  153. CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.N),
  154. CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.roughness1),
  155. CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.roughness2),
  156. CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.T),
  157. CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.offset),
  158. BSDF_CLOSURE_CLASS_END(HairReflection, hair_reflection)
  159. BSDF_CLOSURE_CLASS_BEGIN(HairTransmission, hair_transmission, HairBsdf, LABEL_GLOSSY)
  160. CLOSURE_FLOAT3_PARAM(HairTransmissionClosure, params.N),
  161. CLOSURE_FLOAT_PARAM(HairTransmissionClosure, params.roughness1),
  162. CLOSURE_FLOAT_PARAM(HairTransmissionClosure, params.roughness2),
  163. CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.T),
  164. CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.offset),
  165. BSDF_CLOSURE_CLASS_END(HairTransmission, hair_transmission)
  166. BSDF_CLOSURE_CLASS_BEGIN(PrincipledDiffuse,
  167. principled_diffuse,
  168. PrincipledDiffuseBsdf,
  169. LABEL_DIFFUSE)
  170. CLOSURE_FLOAT3_PARAM(PrincipledDiffuseClosure, params.N),
  171. CLOSURE_FLOAT_PARAM(PrincipledDiffuseClosure, params.roughness),
  172. BSDF_CLOSURE_CLASS_END(PrincipledDiffuse, principled_diffuse)
  173. BSDF_CLOSURE_CLASS_BEGIN(PrincipledSheen,
  174. principled_sheen,
  175. PrincipledSheenBsdf,
  176. LABEL_DIFFUSE)
  177. CLOSURE_FLOAT3_PARAM(PrincipledSheenClosure, params.N),
  178. BSDF_CLOSURE_CLASS_END(PrincipledSheen, principled_sheen)
  179. /* PRINCIPLED HAIR BSDF */
  180. class PrincipledHairClosure : public CBSDFClosure {
  181. public:
  182. PrincipledHairBSDF params;
  183. PrincipledHairBSDF *alloc(ShaderData *sd, int path_flag, float3 weight)
  184. {
  185. PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)bsdf_alloc_osl(
  186. sd, sizeof(PrincipledHairBSDF), weight, &params);
  187. if (!bsdf) {
  188. return NULL;
  189. }
  190. PrincipledHairExtra *extra = (PrincipledHairExtra *)closure_alloc_extra(
  191. sd, sizeof(PrincipledHairExtra));
  192. if (!extra) {
  193. return NULL;
  194. }
  195. bsdf->extra = extra;
  196. return bsdf;
  197. }
  198. void setup(ShaderData *sd, int path_flag, float3 weight)
  199. {
  200. if (!skip(sd, path_flag, LABEL_GLOSSY)) {
  201. PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)alloc(sd, path_flag, weight);
  202. if (!bsdf) {
  203. return;
  204. }
  205. sd->flag |= (bsdf) ? bsdf_principled_hair_setup(sd, bsdf) : 0;
  206. }
  207. }
  208. };
  209. static ClosureParam *closure_bsdf_principled_hair_params()
  210. {
  211. static ClosureParam params[] = {CLOSURE_FLOAT3_PARAM(PrincipledHairClosure, params.N),
  212. CLOSURE_FLOAT3_PARAM(PrincipledHairClosure, params.sigma),
  213. CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.v),
  214. CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.s),
  215. CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.m0_roughness),
  216. CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.alpha),
  217. CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.eta),
  218. CLOSURE_STRING_KEYPARAM(PrincipledHairClosure, label, "label"),
  219. CLOSURE_FINISH_PARAM(PrincipledHairClosure)};
  220. return params;
  221. }
  222. CCLOSURE_PREPARE(closure_bsdf_principled_hair_prepare, PrincipledHairClosure)
  223. /* DISNEY PRINCIPLED CLEARCOAT */
  224. class PrincipledClearcoatClosure : public CBSDFClosure {
  225. public:
  226. MicrofacetBsdf params;
  227. float clearcoat, clearcoat_roughness;
  228. MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
  229. {
  230. MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
  231. sd, sizeof(MicrofacetBsdf), weight, &params);
  232. if (!bsdf) {
  233. return NULL;
  234. }
  235. MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
  236. if (!extra) {
  237. return NULL;
  238. }
  239. bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
  240. bsdf->extra = extra;
  241. bsdf->ior = 1.5f;
  242. bsdf->alpha_x = clearcoat_roughness;
  243. bsdf->alpha_y = clearcoat_roughness;
  244. bsdf->extra->color = make_float3(0.0f, 0.0f, 0.0f);
  245. bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f);
  246. bsdf->extra->clearcoat = clearcoat;
  247. return bsdf;
  248. }
  249. void setup(ShaderData *sd, int path_flag, float3 weight)
  250. {
  251. MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
  252. if (!bsdf) {
  253. return;
  254. }
  255. sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd);
  256. }
  257. };
  258. ClosureParam *closure_bsdf_principled_clearcoat_params()
  259. {
  260. static ClosureParam params[] = {
  261. CLOSURE_FLOAT3_PARAM(PrincipledClearcoatClosure, params.N),
  262. CLOSURE_FLOAT_PARAM(PrincipledClearcoatClosure, clearcoat),
  263. CLOSURE_FLOAT_PARAM(PrincipledClearcoatClosure, clearcoat_roughness),
  264. CLOSURE_STRING_KEYPARAM(PrincipledClearcoatClosure, label, "label"),
  265. CLOSURE_FINISH_PARAM(PrincipledClearcoatClosure)};
  266. return params;
  267. }
  268. CCLOSURE_PREPARE(closure_bsdf_principled_clearcoat_prepare, PrincipledClearcoatClosure)
  269. /* Registration */
  270. static void register_closure(OSL::ShadingSystem *ss,
  271. const char *name,
  272. int id,
  273. OSL::ClosureParam *params,
  274. OSL::PrepareClosureFunc prepare)
  275. {
  276. /* optimization: it's possible to not use a prepare function at all and
  277. * only initialize the actual class when accessing the closure component
  278. * data, but then we need to map the id to the class somehow */
  279. #if OSL_LIBRARY_VERSION_CODE >= 10900
  280. ss->register_closure(name, id, params, prepare, NULL);
  281. #else
  282. ss->register_closure(name, id, params, prepare, NULL, 16);
  283. #endif
  284. }
  285. void OSLShader::register_closures(OSLShadingSystem *ss_)
  286. {
  287. OSL::ShadingSystem *ss = (OSL::ShadingSystem *)ss_;
  288. int id = 0;
  289. register_closure(ss, "diffuse", id++, bsdf_diffuse_params(), bsdf_diffuse_prepare);
  290. register_closure(ss, "oren_nayar", id++, bsdf_oren_nayar_params(), bsdf_oren_nayar_prepare);
  291. register_closure(ss, "translucent", id++, bsdf_translucent_params(), bsdf_translucent_prepare);
  292. register_closure(ss, "reflection", id++, bsdf_reflection_params(), bsdf_reflection_prepare);
  293. register_closure(ss, "refraction", id++, bsdf_refraction_params(), bsdf_refraction_prepare);
  294. register_closure(ss,
  295. "transparent",
  296. id++,
  297. closure_bsdf_transparent_params(),
  298. closure_bsdf_transparent_prepare);
  299. register_closure(
  300. ss, "microfacet_ggx", id++, bsdf_microfacet_ggx_params(), bsdf_microfacet_ggx_prepare);
  301. register_closure(ss,
  302. "microfacet_ggx_aniso",
  303. id++,
  304. bsdf_microfacet_ggx_aniso_params(),
  305. bsdf_microfacet_ggx_aniso_prepare);
  306. register_closure(ss,
  307. "microfacet_ggx_refraction",
  308. id++,
  309. bsdf_microfacet_ggx_refraction_params(),
  310. bsdf_microfacet_ggx_refraction_prepare);
  311. register_closure(ss,
  312. "microfacet_multi_ggx",
  313. id++,
  314. closure_bsdf_microfacet_multi_ggx_params(),
  315. closure_bsdf_microfacet_multi_ggx_prepare);
  316. register_closure(ss,
  317. "microfacet_multi_ggx_glass",
  318. id++,
  319. closure_bsdf_microfacet_multi_ggx_glass_params(),
  320. closure_bsdf_microfacet_multi_ggx_glass_prepare);
  321. register_closure(ss,
  322. "microfacet_multi_ggx_aniso",
  323. id++,
  324. closure_bsdf_microfacet_multi_ggx_aniso_params(),
  325. closure_bsdf_microfacet_multi_ggx_aniso_prepare);
  326. register_closure(ss,
  327. "microfacet_ggx_fresnel",
  328. id++,
  329. closure_bsdf_microfacet_ggx_fresnel_params(),
  330. closure_bsdf_microfacet_ggx_fresnel_prepare);
  331. register_closure(ss,
  332. "microfacet_ggx_aniso_fresnel",
  333. id++,
  334. closure_bsdf_microfacet_ggx_aniso_fresnel_params(),
  335. closure_bsdf_microfacet_ggx_aniso_fresnel_prepare);
  336. register_closure(ss,
  337. "microfacet_multi_ggx_fresnel",
  338. id++,
  339. closure_bsdf_microfacet_multi_ggx_fresnel_params(),
  340. closure_bsdf_microfacet_multi_ggx_fresnel_prepare);
  341. register_closure(ss,
  342. "microfacet_multi_ggx_glass_fresnel",
  343. id++,
  344. closure_bsdf_microfacet_multi_ggx_glass_fresnel_params(),
  345. closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare);
  346. register_closure(ss,
  347. "microfacet_multi_ggx_aniso_fresnel",
  348. id++,
  349. closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params(),
  350. closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare);
  351. register_closure(ss,
  352. "microfacet_beckmann",
  353. id++,
  354. bsdf_microfacet_beckmann_params(),
  355. bsdf_microfacet_beckmann_prepare);
  356. register_closure(ss,
  357. "microfacet_beckmann_aniso",
  358. id++,
  359. bsdf_microfacet_beckmann_aniso_params(),
  360. bsdf_microfacet_beckmann_aniso_prepare);
  361. register_closure(ss,
  362. "microfacet_beckmann_refraction",
  363. id++,
  364. bsdf_microfacet_beckmann_refraction_params(),
  365. bsdf_microfacet_beckmann_refraction_prepare);
  366. register_closure(ss,
  367. "ashikhmin_shirley",
  368. id++,
  369. bsdf_ashikhmin_shirley_aniso_params(),
  370. bsdf_ashikhmin_shirley_aniso_prepare);
  371. register_closure(
  372. ss, "ashikhmin_velvet", id++, bsdf_ashikhmin_velvet_params(), bsdf_ashikhmin_velvet_prepare);
  373. register_closure(
  374. ss, "diffuse_toon", id++, bsdf_diffuse_toon_params(), bsdf_diffuse_toon_prepare);
  375. register_closure(ss, "glossy_toon", id++, bsdf_glossy_toon_params(), bsdf_glossy_toon_prepare);
  376. register_closure(ss,
  377. "principled_diffuse",
  378. id++,
  379. bsdf_principled_diffuse_params(),
  380. bsdf_principled_diffuse_prepare);
  381. register_closure(
  382. ss, "principled_sheen", id++, bsdf_principled_sheen_params(), bsdf_principled_sheen_prepare);
  383. register_closure(ss,
  384. "principled_clearcoat",
  385. id++,
  386. closure_bsdf_principled_clearcoat_params(),
  387. closure_bsdf_principled_clearcoat_prepare);
  388. register_closure(ss, "emission", id++, closure_emission_params(), closure_emission_prepare);
  389. register_closure(
  390. ss, "background", id++, closure_background_params(), closure_background_prepare);
  391. register_closure(ss, "holdout", id++, closure_holdout_params(), closure_holdout_prepare);
  392. register_closure(ss,
  393. "diffuse_ramp",
  394. id++,
  395. closure_bsdf_diffuse_ramp_params(),
  396. closure_bsdf_diffuse_ramp_prepare);
  397. register_closure(
  398. ss, "phong_ramp", id++, closure_bsdf_phong_ramp_params(), closure_bsdf_phong_ramp_prepare);
  399. register_closure(ss, "bssrdf", id++, closure_bssrdf_params(), closure_bssrdf_prepare);
  400. register_closure(
  401. ss, "hair_reflection", id++, bsdf_hair_reflection_params(), bsdf_hair_reflection_prepare);
  402. register_closure(ss,
  403. "hair_transmission",
  404. id++,
  405. bsdf_hair_transmission_params(),
  406. bsdf_hair_transmission_prepare);
  407. register_closure(ss,
  408. "principled_hair",
  409. id++,
  410. closure_bsdf_principled_hair_params(),
  411. closure_bsdf_principled_hair_prepare);
  412. register_closure(ss,
  413. "henyey_greenstein",
  414. id++,
  415. closure_henyey_greenstein_params(),
  416. closure_henyey_greenstein_prepare);
  417. register_closure(
  418. ss, "absorption", id++, closure_absorption_params(), closure_absorption_prepare);
  419. }
  420. /* BSDF Closure */
  421. bool CBSDFClosure::skip(const ShaderData *sd, int path_flag, int scattering)
  422. {
  423. /* caustic options */
  424. if ((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) {
  425. KernelGlobals *kg = sd->osl_globals;
  426. if ((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) ||
  427. (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) {
  428. return true;
  429. }
  430. }
  431. return false;
  432. }
  433. /* GGX closures with Fresnel */
  434. class MicrofacetFresnelClosure : public CBSDFClosure {
  435. public:
  436. MicrofacetBsdf params;
  437. float3 color;
  438. float3 cspec0;
  439. MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
  440. {
  441. /* Technically, the MultiGGX Glass closure may also transmit. However,
  442. * since this is set statically and only used for caustic flags, this
  443. * is probably as good as it gets. */
  444. if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
  445. return NULL;
  446. }
  447. MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
  448. sd, sizeof(MicrofacetBsdf), weight, &params);
  449. if (!bsdf) {
  450. return NULL;
  451. }
  452. MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
  453. if (!extra) {
  454. return NULL;
  455. }
  456. bsdf->extra = extra;
  457. bsdf->extra->color = color;
  458. bsdf->extra->cspec0 = cspec0;
  459. bsdf->extra->clearcoat = 0.0f;
  460. return bsdf;
  461. }
  462. };
  463. class MicrofacetGGXFresnelClosure : public MicrofacetFresnelClosure {
  464. public:
  465. void setup(ShaderData *sd, int path_flag, float3 weight)
  466. {
  467. MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
  468. if (!bsdf) {
  469. return;
  470. }
  471. bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
  472. bsdf->alpha_y = bsdf->alpha_x;
  473. sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd);
  474. }
  475. };
  476. ClosureParam *closure_bsdf_microfacet_ggx_fresnel_params()
  477. {
  478. static ClosureParam params[] = {
  479. CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.N),
  480. CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_x),
  481. CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.ior),
  482. CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, color),
  483. CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, cspec0),
  484. CLOSURE_STRING_KEYPARAM(MicrofacetGGXFresnelClosure, label, "label"),
  485. CLOSURE_FINISH_PARAM(MicrofacetGGXFresnelClosure)};
  486. return params;
  487. }
  488. CCLOSURE_PREPARE(closure_bsdf_microfacet_ggx_fresnel_prepare, MicrofacetGGXFresnelClosure);
  489. class MicrofacetGGXAnisoFresnelClosure : public MicrofacetFresnelClosure {
  490. public:
  491. void setup(ShaderData *sd, int path_flag, float3 weight)
  492. {
  493. MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
  494. if (!bsdf) {
  495. return;
  496. }
  497. sd->flag |= bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf, sd);
  498. }
  499. };
  500. ClosureParam *closure_bsdf_microfacet_ggx_aniso_fresnel_params()
  501. {
  502. static ClosureParam params[] = {
  503. CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.N),
  504. CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.T),
  505. CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_x),
  506. CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_y),
  507. CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.ior),
  508. CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, color),
  509. CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, cspec0),
  510. CLOSURE_STRING_KEYPARAM(MicrofacetGGXFresnelClosure, label, "label"),
  511. CLOSURE_FINISH_PARAM(MicrofacetGGXFresnelClosure)};
  512. return params;
  513. }
  514. CCLOSURE_PREPARE(closure_bsdf_microfacet_ggx_aniso_fresnel_prepare,
  515. MicrofacetGGXAnisoFresnelClosure);
  516. /* Multiscattering GGX closures */
  517. class MicrofacetMultiClosure : public CBSDFClosure {
  518. public:
  519. MicrofacetBsdf params;
  520. float3 color;
  521. MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
  522. {
  523. /* Technically, the MultiGGX closure may also transmit. However,
  524. * since this is set statically and only used for caustic flags, this
  525. * is probably as good as it gets. */
  526. if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
  527. return NULL;
  528. }
  529. MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
  530. sd, sizeof(MicrofacetBsdf), weight, &params);
  531. if (!bsdf) {
  532. return NULL;
  533. }
  534. MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
  535. if (!extra) {
  536. return NULL;
  537. }
  538. bsdf->extra = extra;
  539. bsdf->extra->color = color;
  540. bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
  541. bsdf->extra->clearcoat = 0.0f;
  542. return bsdf;
  543. }
  544. };
  545. class MicrofacetMultiGGXClosure : public MicrofacetMultiClosure {
  546. public:
  547. void setup(ShaderData *sd, int path_flag, float3 weight)
  548. {
  549. MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
  550. if (!bsdf) {
  551. return;
  552. }
  553. bsdf->ior = 0.0f;
  554. bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
  555. bsdf->alpha_y = bsdf->alpha_x;
  556. sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
  557. }
  558. };
  559. ClosureParam *closure_bsdf_microfacet_multi_ggx_params()
  560. {
  561. static ClosureParam params[] = {
  562. CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N),
  563. CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x),
  564. CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color),
  565. CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"),
  566. CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)};
  567. return params;
  568. }
  569. CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_prepare, MicrofacetMultiGGXClosure);
  570. class MicrofacetMultiGGXAnisoClosure : public MicrofacetMultiClosure {
  571. public:
  572. void setup(ShaderData *sd, int path_flag, float3 weight)
  573. {
  574. MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
  575. if (!bsdf) {
  576. return;
  577. }
  578. bsdf->ior = 0.0f;
  579. sd->flag |= bsdf_microfacet_multi_ggx_aniso_setup(bsdf);
  580. }
  581. };
  582. ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_params()
  583. {
  584. static ClosureParam params[] = {
  585. CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N),
  586. CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.T),
  587. CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x),
  588. CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_y),
  589. CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color),
  590. CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"),
  591. CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)};
  592. return params;
  593. }
  594. CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_aniso_prepare, MicrofacetMultiGGXAnisoClosure);
  595. class MicrofacetMultiGGXGlassClosure : public MicrofacetMultiClosure {
  596. public:
  597. MicrofacetMultiGGXGlassClosure() : MicrofacetMultiClosure()
  598. {
  599. }
  600. void setup(ShaderData *sd, int path_flag, float3 weight)
  601. {
  602. MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
  603. if (!bsdf) {
  604. return;
  605. }
  606. bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
  607. bsdf->alpha_y = bsdf->alpha_x;
  608. sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf);
  609. }
  610. };
  611. ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_params()
  612. {
  613. static ClosureParam params[] = {
  614. CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N),
  615. CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x),
  616. CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.ior),
  617. CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color),
  618. CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"),
  619. CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)};
  620. return params;
  621. }
  622. CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_glass_prepare, MicrofacetMultiGGXGlassClosure);
  623. /* Multiscattering GGX closures with Fresnel */
  624. class MicrofacetMultiFresnelClosure : public CBSDFClosure {
  625. public:
  626. MicrofacetBsdf params;
  627. float3 color;
  628. float3 cspec0;
  629. MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
  630. {
  631. /* Technically, the MultiGGX closure may also transmit. However,
  632. * since this is set statically and only used for caustic flags, this
  633. * is probably as good as it gets. */
  634. if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
  635. return NULL;
  636. }
  637. MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
  638. sd, sizeof(MicrofacetBsdf), weight, &params);
  639. if (!bsdf) {
  640. return NULL;
  641. }
  642. MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
  643. if (!extra) {
  644. return NULL;
  645. }
  646. bsdf->extra = extra;
  647. bsdf->extra->color = color;
  648. bsdf->extra->cspec0 = cspec0;
  649. bsdf->extra->clearcoat = 0.0f;
  650. return bsdf;
  651. }
  652. };
  653. class MicrofacetMultiGGXFresnelClosure : public MicrofacetMultiFresnelClosure {
  654. public:
  655. void setup(ShaderData *sd, int path_flag, float3 weight)
  656. {
  657. MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
  658. if (!bsdf) {
  659. return;
  660. }
  661. bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
  662. bsdf->alpha_y = bsdf->alpha_x;
  663. sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd);
  664. }
  665. };
  666. ClosureParam *closure_bsdf_microfacet_multi_ggx_fresnel_params()
  667. {
  668. static ClosureParam params[] = {
  669. CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N),
  670. CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x),
  671. CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior),
  672. CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color),
  673. CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0),
  674. CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"),
  675. CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)};
  676. return params;
  677. }
  678. CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_fresnel_prepare,
  679. MicrofacetMultiGGXFresnelClosure);
  680. class MicrofacetMultiGGXAnisoFresnelClosure : public MicrofacetMultiFresnelClosure {
  681. public:
  682. void setup(ShaderData *sd, int path_flag, float3 weight)
  683. {
  684. MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
  685. if (!bsdf) {
  686. return;
  687. }
  688. sd->flag |= bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf, sd);
  689. }
  690. };
  691. ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params()
  692. {
  693. static ClosureParam params[] = {
  694. CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N),
  695. CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.T),
  696. CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x),
  697. CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_y),
  698. CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior),
  699. CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color),
  700. CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0),
  701. CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"),
  702. CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)};
  703. return params;
  704. }
  705. CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare,
  706. MicrofacetMultiGGXAnisoFresnelClosure);
  707. class MicrofacetMultiGGXGlassFresnelClosure : public MicrofacetMultiFresnelClosure {
  708. public:
  709. MicrofacetMultiGGXGlassFresnelClosure() : MicrofacetMultiFresnelClosure()
  710. {
  711. }
  712. void setup(ShaderData *sd, int path_flag, float3 weight)
  713. {
  714. MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
  715. if (!bsdf) {
  716. return;
  717. }
  718. bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
  719. bsdf->alpha_y = bsdf->alpha_x;
  720. sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd);
  721. }
  722. };
  723. ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_fresnel_params()
  724. {
  725. static ClosureParam params[] = {
  726. CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N),
  727. CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x),
  728. CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior),
  729. CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color),
  730. CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0),
  731. CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"),
  732. CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)};
  733. return params;
  734. }
  735. CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare,
  736. MicrofacetMultiGGXGlassFresnelClosure);
  737. /* Transparent */
  738. class TransparentClosure : public CBSDFClosure {
  739. public:
  740. ShaderClosure params;
  741. float3 unused;
  742. void setup(ShaderData *sd, int path_flag, float3 weight)
  743. {
  744. bsdf_transparent_setup(sd, weight, path_flag);
  745. }
  746. };
  747. ClosureParam *closure_bsdf_transparent_params()
  748. {
  749. static ClosureParam params[] = {CLOSURE_STRING_KEYPARAM(TransparentClosure, label, "label"),
  750. CLOSURE_FINISH_PARAM(TransparentClosure)};
  751. return params;
  752. }
  753. CCLOSURE_PREPARE(closure_bsdf_transparent_prepare, TransparentClosure)
  754. /* Volume */
  755. class VolumeAbsorptionClosure : public CBSDFClosure {
  756. public:
  757. void setup(ShaderData *sd, int path_flag, float3 weight)
  758. {
  759. volume_extinction_setup(sd, weight);
  760. }
  761. };
  762. ClosureParam *closure_absorption_params()
  763. {
  764. static ClosureParam params[] = {CLOSURE_STRING_KEYPARAM(VolumeAbsorptionClosure, label, "label"),
  765. CLOSURE_FINISH_PARAM(VolumeAbsorptionClosure)};
  766. return params;
  767. }
  768. CCLOSURE_PREPARE(closure_absorption_prepare, VolumeAbsorptionClosure)
  769. class VolumeHenyeyGreensteinClosure : public CBSDFClosure {
  770. public:
  771. HenyeyGreensteinVolume params;
  772. void setup(ShaderData *sd, int path_flag, float3 weight)
  773. {
  774. volume_extinction_setup(sd, weight);
  775. HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume *)bsdf_alloc_osl(
  776. sd, sizeof(HenyeyGreensteinVolume), weight, &params);
  777. if (!volume) {
  778. return;
  779. }
  780. sd->flag |= volume_henyey_greenstein_setup(volume);
  781. }
  782. };
  783. ClosureParam *closure_henyey_greenstein_params()
  784. {
  785. static ClosureParam params[] = {
  786. CLOSURE_FLOAT_PARAM(VolumeHenyeyGreensteinClosure, params.g),
  787. CLOSURE_STRING_KEYPARAM(VolumeHenyeyGreensteinClosure, label, "label"),
  788. CLOSURE_FINISH_PARAM(VolumeHenyeyGreensteinClosure)};
  789. return params;
  790. }
  791. CCLOSURE_PREPARE(closure_henyey_greenstein_prepare, VolumeHenyeyGreensteinClosure)
  792. CCL_NAMESPACE_END