osl_services.cpp 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467
  1. /*
  2. * Copyright 2011-2013 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. /* TODO(sergey): There is a bit of headers dependency hell going on
  17. * here, so for now we just put here. In the future it might be better
  18. * to have dedicated file for such tweaks.
  19. */
  20. #if (defined(__GNUC__) && !defined(__clang__)) && defined(NDEBUG)
  21. # pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
  22. # pragma GCC diagnostic ignored "-Wuninitialized"
  23. #endif
  24. #include <string.h>
  25. #include "render/colorspace.h"
  26. #include "render/mesh.h"
  27. #include "render/object.h"
  28. #include "render/scene.h"
  29. #include "kernel/osl/osl_closures.h"
  30. #include "kernel/osl/osl_globals.h"
  31. #include "kernel/osl/osl_services.h"
  32. #include "kernel/osl/osl_shader.h"
  33. #include "util/util_foreach.h"
  34. #include "util/util_logging.h"
  35. #include "util/util_string.h"
  36. #include "kernel/kernel_compat_cpu.h"
  37. #include "kernel/split/kernel_split_data_types.h"
  38. #include "kernel/kernel_globals.h"
  39. #include "kernel/kernel_color.h"
  40. #include "kernel/kernel_random.h"
  41. #include "kernel/kernel_projection.h"
  42. #include "kernel/kernel_differential.h"
  43. #include "kernel/kernel_montecarlo.h"
  44. #include "kernel/kernel_camera.h"
  45. #include "kernel/kernels/cpu/kernel_cpu_image.h"
  46. #include "kernel/geom/geom.h"
  47. #include "kernel/bvh/bvh.h"
  48. #include "kernel/kernel_projection.h"
  49. #include "kernel/kernel_accumulate.h"
  50. #include "kernel/kernel_shader.h"
  51. CCL_NAMESPACE_BEGIN
  52. /* RenderServices implementation */
  53. static void copy_matrix(OSL::Matrix44 &m, const Transform &tfm)
  54. {
  55. ProjectionTransform t = projection_transpose(ProjectionTransform(tfm));
  56. memcpy((void *)&m, &t, sizeof(m));
  57. }
  58. static void copy_matrix(OSL::Matrix44 &m, const ProjectionTransform &tfm)
  59. {
  60. ProjectionTransform t = projection_transpose(tfm);
  61. memcpy((void *)&m, &t, sizeof(m));
  62. }
  63. /* static ustrings */
  64. ustring OSLRenderServices::u_distance("distance");
  65. ustring OSLRenderServices::u_index("index");
  66. ustring OSLRenderServices::u_world("world");
  67. ustring OSLRenderServices::u_camera("camera");
  68. ustring OSLRenderServices::u_screen("screen");
  69. ustring OSLRenderServices::u_raster("raster");
  70. ustring OSLRenderServices::u_ndc("NDC");
  71. ustring OSLRenderServices::u_object_location("object:location");
  72. ustring OSLRenderServices::u_object_index("object:index");
  73. ustring OSLRenderServices::u_geom_dupli_generated("geom:dupli_generated");
  74. ustring OSLRenderServices::u_geom_dupli_uv("geom:dupli_uv");
  75. ustring OSLRenderServices::u_material_index("material:index");
  76. ustring OSLRenderServices::u_object_random("object:random");
  77. ustring OSLRenderServices::u_particle_index("particle:index");
  78. ustring OSLRenderServices::u_particle_random("particle:random");
  79. ustring OSLRenderServices::u_particle_age("particle:age");
  80. ustring OSLRenderServices::u_particle_lifetime("particle:lifetime");
  81. ustring OSLRenderServices::u_particle_location("particle:location");
  82. ustring OSLRenderServices::u_particle_rotation("particle:rotation");
  83. ustring OSLRenderServices::u_particle_size("particle:size");
  84. ustring OSLRenderServices::u_particle_velocity("particle:velocity");
  85. ustring OSLRenderServices::u_particle_angular_velocity("particle:angular_velocity");
  86. ustring OSLRenderServices::u_geom_numpolyvertices("geom:numpolyvertices");
  87. ustring OSLRenderServices::u_geom_trianglevertices("geom:trianglevertices");
  88. ustring OSLRenderServices::u_geom_polyvertices("geom:polyvertices");
  89. ustring OSLRenderServices::u_geom_name("geom:name");
  90. ustring OSLRenderServices::u_geom_undisplaced("geom:undisplaced");
  91. ustring OSLRenderServices::u_is_smooth("geom:is_smooth");
  92. ustring OSLRenderServices::u_is_curve("geom:is_curve");
  93. ustring OSLRenderServices::u_curve_thickness("geom:curve_thickness");
  94. ustring OSLRenderServices::u_curve_tangent_normal("geom:curve_tangent_normal");
  95. ustring OSLRenderServices::u_curve_random("geom:curve_random");
  96. ustring OSLRenderServices::u_path_ray_length("path:ray_length");
  97. ustring OSLRenderServices::u_path_ray_depth("path:ray_depth");
  98. ustring OSLRenderServices::u_path_diffuse_depth("path:diffuse_depth");
  99. ustring OSLRenderServices::u_path_glossy_depth("path:glossy_depth");
  100. ustring OSLRenderServices::u_path_transparent_depth("path:transparent_depth");
  101. ustring OSLRenderServices::u_path_transmission_depth("path:transmission_depth");
  102. ustring OSLRenderServices::u_trace("trace");
  103. ustring OSLRenderServices::u_hit("hit");
  104. ustring OSLRenderServices::u_hitdist("hitdist");
  105. ustring OSLRenderServices::u_N("N");
  106. ustring OSLRenderServices::u_Ng("Ng");
  107. ustring OSLRenderServices::u_P("P");
  108. ustring OSLRenderServices::u_I("I");
  109. ustring OSLRenderServices::u_u("u");
  110. ustring OSLRenderServices::u_v("v");
  111. ustring OSLRenderServices::u_empty;
  112. OSLRenderServices::OSLRenderServices(OSL::TextureSystem *texture_system)
  113. : texture_system(texture_system)
  114. {
  115. }
  116. OSLRenderServices::~OSLRenderServices()
  117. {
  118. if (texture_system) {
  119. VLOG(2) << "OSL texture system stats:\n" << texture_system->getstats();
  120. }
  121. }
  122. bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
  123. OSL::Matrix44 &result,
  124. OSL::TransformationPtr xform,
  125. float time)
  126. {
  127. /* this is only used for shader and object space, we don't really have
  128. * a concept of shader space, so we just use object space for both. */
  129. if (xform) {
  130. const ShaderData *sd = (const ShaderData *)xform;
  131. KernelGlobals *kg = sd->osl_globals;
  132. int object = sd->object;
  133. if (object != OBJECT_NONE) {
  134. #ifdef __OBJECT_MOTION__
  135. Transform tfm;
  136. if (time == sd->time)
  137. tfm = sd->ob_tfm;
  138. else
  139. tfm = object_fetch_transform_motion_test(kg, object, time, NULL);
  140. #else
  141. Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
  142. #endif
  143. copy_matrix(result, tfm);
  144. return true;
  145. }
  146. else if (sd->type == PRIMITIVE_LAMP) {
  147. copy_matrix(result, sd->ob_tfm);
  148. return true;
  149. }
  150. }
  151. return false;
  152. }
  153. bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
  154. OSL::Matrix44 &result,
  155. OSL::TransformationPtr xform,
  156. float time)
  157. {
  158. /* this is only used for shader and object space, we don't really have
  159. * a concept of shader space, so we just use object space for both. */
  160. if (xform) {
  161. const ShaderData *sd = (const ShaderData *)xform;
  162. KernelGlobals *kg = sd->osl_globals;
  163. int object = sd->object;
  164. if (object != OBJECT_NONE) {
  165. #ifdef __OBJECT_MOTION__
  166. Transform itfm;
  167. if (time == sd->time)
  168. itfm = sd->ob_itfm;
  169. else
  170. object_fetch_transform_motion_test(kg, object, time, &itfm);
  171. #else
  172. Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
  173. #endif
  174. copy_matrix(result, itfm);
  175. return true;
  176. }
  177. else if (sd->type == PRIMITIVE_LAMP) {
  178. copy_matrix(result, sd->ob_itfm);
  179. return true;
  180. }
  181. }
  182. return false;
  183. }
  184. bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
  185. OSL::Matrix44 &result,
  186. ustring from,
  187. float time)
  188. {
  189. ShaderData *sd = (ShaderData *)(sg->renderstate);
  190. KernelGlobals *kg = sd->osl_globals;
  191. if (from == u_ndc) {
  192. copy_matrix(result, kernel_data.cam.ndctoworld);
  193. return true;
  194. }
  195. else if (from == u_raster) {
  196. copy_matrix(result, kernel_data.cam.rastertoworld);
  197. return true;
  198. }
  199. else if (from == u_screen) {
  200. copy_matrix(result, kernel_data.cam.screentoworld);
  201. return true;
  202. }
  203. else if (from == u_camera) {
  204. copy_matrix(result, kernel_data.cam.cameratoworld);
  205. return true;
  206. }
  207. else if (from == u_world) {
  208. result.makeIdentity();
  209. return true;
  210. }
  211. return false;
  212. }
  213. bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
  214. OSL::Matrix44 &result,
  215. ustring to,
  216. float time)
  217. {
  218. ShaderData *sd = (ShaderData *)(sg->renderstate);
  219. KernelGlobals *kg = sd->osl_globals;
  220. if (to == u_ndc) {
  221. copy_matrix(result, kernel_data.cam.worldtondc);
  222. return true;
  223. }
  224. else if (to == u_raster) {
  225. copy_matrix(result, kernel_data.cam.worldtoraster);
  226. return true;
  227. }
  228. else if (to == u_screen) {
  229. copy_matrix(result, kernel_data.cam.worldtoscreen);
  230. return true;
  231. }
  232. else if (to == u_camera) {
  233. copy_matrix(result, kernel_data.cam.worldtocamera);
  234. return true;
  235. }
  236. else if (to == u_world) {
  237. result.makeIdentity();
  238. return true;
  239. }
  240. return false;
  241. }
  242. bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg,
  243. OSL::Matrix44 &result,
  244. OSL::TransformationPtr xform)
  245. {
  246. /* this is only used for shader and object space, we don't really have
  247. * a concept of shader space, so we just use object space for both. */
  248. if (xform) {
  249. const ShaderData *sd = (const ShaderData *)xform;
  250. int object = sd->object;
  251. if (object != OBJECT_NONE) {
  252. #ifdef __OBJECT_MOTION__
  253. Transform tfm = sd->ob_tfm;
  254. #else
  255. KernelGlobals *kg = sd->osl_globals;
  256. Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
  257. #endif
  258. copy_matrix(result, tfm);
  259. return true;
  260. }
  261. else if (sd->type == PRIMITIVE_LAMP) {
  262. copy_matrix(result, sd->ob_tfm);
  263. return true;
  264. }
  265. }
  266. return false;
  267. }
  268. bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
  269. OSL::Matrix44 &result,
  270. OSL::TransformationPtr xform)
  271. {
  272. /* this is only used for shader and object space, we don't really have
  273. * a concept of shader space, so we just use object space for both. */
  274. if (xform) {
  275. const ShaderData *sd = (const ShaderData *)xform;
  276. int object = sd->object;
  277. if (object != OBJECT_NONE) {
  278. #ifdef __OBJECT_MOTION__
  279. Transform tfm = sd->ob_itfm;
  280. #else
  281. KernelGlobals *kg = sd->osl_globals;
  282. Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
  283. #endif
  284. copy_matrix(result, tfm);
  285. return true;
  286. }
  287. else if (sd->type == PRIMITIVE_LAMP) {
  288. copy_matrix(result, sd->ob_itfm);
  289. return true;
  290. }
  291. }
  292. return false;
  293. }
  294. bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result, ustring from)
  295. {
  296. ShaderData *sd = (ShaderData *)(sg->renderstate);
  297. KernelGlobals *kg = sd->osl_globals;
  298. if (from == u_ndc) {
  299. copy_matrix(result, kernel_data.cam.ndctoworld);
  300. return true;
  301. }
  302. else if (from == u_raster) {
  303. copy_matrix(result, kernel_data.cam.rastertoworld);
  304. return true;
  305. }
  306. else if (from == u_screen) {
  307. copy_matrix(result, kernel_data.cam.screentoworld);
  308. return true;
  309. }
  310. else if (from == u_camera) {
  311. copy_matrix(result, kernel_data.cam.cameratoworld);
  312. return true;
  313. }
  314. return false;
  315. }
  316. bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg,
  317. OSL::Matrix44 &result,
  318. ustring to)
  319. {
  320. ShaderData *sd = (ShaderData *)(sg->renderstate);
  321. KernelGlobals *kg = sd->osl_globals;
  322. if (to == u_ndc) {
  323. copy_matrix(result, kernel_data.cam.worldtondc);
  324. return true;
  325. }
  326. else if (to == u_raster) {
  327. copy_matrix(result, kernel_data.cam.worldtoraster);
  328. return true;
  329. }
  330. else if (to == u_screen) {
  331. copy_matrix(result, kernel_data.cam.worldtoscreen);
  332. return true;
  333. }
  334. else if (to == u_camera) {
  335. copy_matrix(result, kernel_data.cam.worldtocamera);
  336. return true;
  337. }
  338. return false;
  339. }
  340. bool OSLRenderServices::get_array_attribute(OSL::ShaderGlobals *sg,
  341. bool derivatives,
  342. ustring object,
  343. TypeDesc type,
  344. ustring name,
  345. int index,
  346. void *val)
  347. {
  348. return false;
  349. }
  350. static bool set_attribute_float2(float2 f[3], TypeDesc type, bool derivatives, void *val)
  351. {
  352. if (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
  353. type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor) {
  354. float *fval = (float *)val;
  355. fval[0] = f[0].x;
  356. fval[1] = f[0].y;
  357. fval[2] = 0.0f;
  358. if (derivatives) {
  359. fval[3] = f[1].x;
  360. fval[4] = f[1].y;
  361. fval[5] = 0.0f;
  362. fval[6] = f[2].x;
  363. fval[7] = f[2].y;
  364. fval[8] = 0.0f;
  365. }
  366. return true;
  367. }
  368. else if (type == TypeDesc::TypeFloat) {
  369. float *fval = (float *)val;
  370. fval[0] = average(f[0]);
  371. if (derivatives) {
  372. fval[1] = average(f[1]);
  373. fval[2] = average(f[2]);
  374. }
  375. return true;
  376. }
  377. return false;
  378. }
  379. static bool set_attribute_float3(float3 f[3], TypeDesc type, bool derivatives, void *val)
  380. {
  381. if (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
  382. type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor) {
  383. float *fval = (float *)val;
  384. fval[0] = f[0].x;
  385. fval[1] = f[0].y;
  386. fval[2] = f[0].z;
  387. if (derivatives) {
  388. fval[3] = f[1].x;
  389. fval[4] = f[1].y;
  390. fval[5] = f[1].z;
  391. fval[6] = f[2].x;
  392. fval[7] = f[2].y;
  393. fval[8] = f[2].z;
  394. }
  395. return true;
  396. }
  397. else if (type == TypeDesc::TypeFloat) {
  398. float *fval = (float *)val;
  399. fval[0] = average(f[0]);
  400. if (derivatives) {
  401. fval[1] = average(f[1]);
  402. fval[2] = average(f[2]);
  403. }
  404. return true;
  405. }
  406. return false;
  407. }
  408. static bool set_attribute_float3(float3 f, TypeDesc type, bool derivatives, void *val)
  409. {
  410. float3 fv[3];
  411. fv[0] = f;
  412. fv[1] = make_float3(0.0f, 0.0f, 0.0f);
  413. fv[2] = make_float3(0.0f, 0.0f, 0.0f);
  414. return set_attribute_float3(fv, type, derivatives, val);
  415. }
  416. static bool set_attribute_float(float f[3], TypeDesc type, bool derivatives, void *val)
  417. {
  418. if (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
  419. type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor) {
  420. float *fval = (float *)val;
  421. fval[0] = f[0];
  422. fval[1] = f[1];
  423. fval[2] = f[2];
  424. if (derivatives) {
  425. fval[3] = f[1];
  426. fval[4] = f[1];
  427. fval[5] = f[1];
  428. fval[6] = f[2];
  429. fval[7] = f[2];
  430. fval[8] = f[2];
  431. }
  432. return true;
  433. }
  434. else if (type == TypeDesc::TypeFloat) {
  435. float *fval = (float *)val;
  436. fval[0] = f[0];
  437. if (derivatives) {
  438. fval[1] = f[1];
  439. fval[2] = f[2];
  440. }
  441. return true;
  442. }
  443. return false;
  444. }
  445. static bool set_attribute_float(float f, TypeDesc type, bool derivatives, void *val)
  446. {
  447. float fv[3];
  448. fv[0] = f;
  449. fv[1] = 0.0f;
  450. fv[2] = 0.0f;
  451. return set_attribute_float(fv, type, derivatives, val);
  452. }
  453. static bool set_attribute_int(int i, TypeDesc type, bool derivatives, void *val)
  454. {
  455. if (type.basetype == TypeDesc::INT && type.aggregate == TypeDesc::SCALAR && type.arraylen == 0) {
  456. int *ival = (int *)val;
  457. ival[0] = i;
  458. if (derivatives) {
  459. ival[1] = 0;
  460. ival[2] = 0;
  461. }
  462. return true;
  463. }
  464. return false;
  465. }
  466. static bool set_attribute_string(ustring str, TypeDesc type, bool derivatives, void *val)
  467. {
  468. if (type.basetype == TypeDesc::STRING && type.aggregate == TypeDesc::SCALAR &&
  469. type.arraylen == 0) {
  470. ustring *sval = (ustring *)val;
  471. sval[0] = str;
  472. if (derivatives) {
  473. sval[1] = OSLRenderServices::u_empty;
  474. sval[2] = OSLRenderServices::u_empty;
  475. }
  476. return true;
  477. }
  478. return false;
  479. }
  480. static bool set_attribute_float3_3(float3 P[3], TypeDesc type, bool derivatives, void *val)
  481. {
  482. if (type.vecsemantics == TypeDesc::POINT && type.arraylen >= 3) {
  483. float *fval = (float *)val;
  484. fval[0] = P[0].x;
  485. fval[1] = P[0].y;
  486. fval[2] = P[0].z;
  487. fval[3] = P[1].x;
  488. fval[4] = P[1].y;
  489. fval[5] = P[1].z;
  490. fval[6] = P[2].x;
  491. fval[7] = P[2].y;
  492. fval[8] = P[2].z;
  493. if (type.arraylen > 3)
  494. memset(fval + 3 * 3, 0, sizeof(float) * 3 * (type.arraylen - 3));
  495. if (derivatives)
  496. memset(fval + type.arraylen * 3, 0, sizeof(float) * 2 * 3 * type.arraylen);
  497. return true;
  498. }
  499. return false;
  500. }
  501. static bool set_attribute_matrix(const Transform &tfm, TypeDesc type, void *val)
  502. {
  503. if (type == TypeDesc::TypeMatrix) {
  504. copy_matrix(*(OSL::Matrix44 *)val, tfm);
  505. return true;
  506. }
  507. return false;
  508. }
  509. static bool get_primitive_attribute(KernelGlobals *kg,
  510. const ShaderData *sd,
  511. const OSLGlobals::Attribute &attr,
  512. const TypeDesc &type,
  513. bool derivatives,
  514. void *val)
  515. {
  516. if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
  517. attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) {
  518. float3 fval[3];
  519. fval[0] = primitive_attribute_float3(
  520. kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
  521. return set_attribute_float3(fval, type, derivatives, val);
  522. }
  523. else if (attr.type == TypeFloat2) {
  524. float2 fval[3];
  525. fval[0] = primitive_attribute_float2(
  526. kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
  527. return set_attribute_float2(fval, type, derivatives, val);
  528. }
  529. else if (attr.type == TypeDesc::TypeFloat) {
  530. float fval[3];
  531. fval[0] = primitive_attribute_float(
  532. kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
  533. return set_attribute_float(fval, type, derivatives, val);
  534. }
  535. else {
  536. return false;
  537. }
  538. }
  539. static bool get_mesh_attribute(KernelGlobals *kg,
  540. const ShaderData *sd,
  541. const OSLGlobals::Attribute &attr,
  542. const TypeDesc &type,
  543. bool derivatives,
  544. void *val)
  545. {
  546. if (attr.type == TypeDesc::TypeMatrix) {
  547. Transform tfm = primitive_attribute_matrix(kg, sd, attr.desc);
  548. return set_attribute_matrix(tfm, type, val);
  549. }
  550. else {
  551. return false;
  552. }
  553. }
  554. static void get_object_attribute(const OSLGlobals::Attribute &attr, bool derivatives, void *val)
  555. {
  556. size_t datasize = attr.value.datasize();
  557. memcpy(val, attr.value.data(), datasize);
  558. if (derivatives)
  559. memset((char *)val + datasize, 0, datasize * 2);
  560. }
  561. bool OSLRenderServices::get_object_standard_attribute(
  562. KernelGlobals *kg, ShaderData *sd, ustring name, TypeDesc type, bool derivatives, void *val)
  563. {
  564. /* todo: turn this into hash table? */
  565. /* Object Attributes */
  566. if (name == u_object_location) {
  567. float3 f = object_location(kg, sd);
  568. return set_attribute_float3(f, type, derivatives, val);
  569. }
  570. else if (name == u_object_index) {
  571. float f = object_pass_id(kg, sd->object);
  572. return set_attribute_float(f, type, derivatives, val);
  573. }
  574. else if (name == u_geom_dupli_generated) {
  575. float3 f = object_dupli_generated(kg, sd->object);
  576. return set_attribute_float3(f, type, derivatives, val);
  577. }
  578. else if (name == u_geom_dupli_uv) {
  579. float3 f = object_dupli_uv(kg, sd->object);
  580. return set_attribute_float3(f, type, derivatives, val);
  581. }
  582. else if (name == u_material_index) {
  583. float f = shader_pass_id(kg, sd);
  584. return set_attribute_float(f, type, derivatives, val);
  585. }
  586. else if (name == u_object_random) {
  587. float f = object_random_number(kg, sd->object);
  588. return set_attribute_float(f, type, derivatives, val);
  589. }
  590. /* Particle Attributes */
  591. else if (name == u_particle_index) {
  592. int particle_id = object_particle_id(kg, sd->object);
  593. float f = particle_index(kg, particle_id);
  594. return set_attribute_float(f, type, derivatives, val);
  595. }
  596. else if (name == u_particle_random) {
  597. int particle_id = object_particle_id(kg, sd->object);
  598. float f = hash_int_01(particle_index(kg, particle_id));
  599. return set_attribute_float(f, type, derivatives, val);
  600. }
  601. else if (name == u_particle_age) {
  602. int particle_id = object_particle_id(kg, sd->object);
  603. float f = particle_age(kg, particle_id);
  604. return set_attribute_float(f, type, derivatives, val);
  605. }
  606. else if (name == u_particle_lifetime) {
  607. int particle_id = object_particle_id(kg, sd->object);
  608. float f = particle_lifetime(kg, particle_id);
  609. return set_attribute_float(f, type, derivatives, val);
  610. }
  611. else if (name == u_particle_location) {
  612. int particle_id = object_particle_id(kg, sd->object);
  613. float3 f = particle_location(kg, particle_id);
  614. return set_attribute_float3(f, type, derivatives, val);
  615. }
  616. #if 0 /* unsupported */
  617. else if (name == u_particle_rotation) {
  618. int particle_id = object_particle_id(kg, sd->object);
  619. float4 f = particle_rotation(kg, particle_id);
  620. return set_attribute_float4(f, type, derivatives, val);
  621. }
  622. #endif
  623. else if (name == u_particle_size) {
  624. int particle_id = object_particle_id(kg, sd->object);
  625. float f = particle_size(kg, particle_id);
  626. return set_attribute_float(f, type, derivatives, val);
  627. }
  628. else if (name == u_particle_velocity) {
  629. int particle_id = object_particle_id(kg, sd->object);
  630. float3 f = particle_velocity(kg, particle_id);
  631. return set_attribute_float3(f, type, derivatives, val);
  632. }
  633. else if (name == u_particle_angular_velocity) {
  634. int particle_id = object_particle_id(kg, sd->object);
  635. float3 f = particle_angular_velocity(kg, particle_id);
  636. return set_attribute_float3(f, type, derivatives, val);
  637. }
  638. /* Geometry Attributes */
  639. else if (name == u_geom_numpolyvertices) {
  640. return set_attribute_int(3, type, derivatives, val);
  641. }
  642. else if ((name == u_geom_trianglevertices || name == u_geom_polyvertices) &&
  643. sd->type & PRIMITIVE_ALL_TRIANGLE) {
  644. float3 P[3];
  645. if (sd->type & PRIMITIVE_TRIANGLE)
  646. triangle_vertices(kg, sd->prim, P);
  647. else
  648. motion_triangle_vertices(kg, sd->object, sd->prim, sd->time, P);
  649. if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
  650. object_position_transform(kg, sd, &P[0]);
  651. object_position_transform(kg, sd, &P[1]);
  652. object_position_transform(kg, sd, &P[2]);
  653. }
  654. return set_attribute_float3_3(P, type, derivatives, val);
  655. }
  656. else if (name == u_geom_name) {
  657. ustring object_name = kg->osl->object_names[sd->object];
  658. return set_attribute_string(object_name, type, derivatives, val);
  659. }
  660. else if (name == u_is_smooth) {
  661. float f = ((sd->shader & SHADER_SMOOTH_NORMAL) != 0);
  662. return set_attribute_float(f, type, derivatives, val);
  663. }
  664. /* Hair Attributes */
  665. else if (name == u_is_curve) {
  666. float f = (sd->type & PRIMITIVE_ALL_CURVE) != 0;
  667. return set_attribute_float(f, type, derivatives, val);
  668. }
  669. else if (name == u_curve_thickness) {
  670. float f = curve_thickness(kg, sd);
  671. return set_attribute_float(f, type, derivatives, val);
  672. }
  673. else if (name == u_curve_tangent_normal) {
  674. float3 f = curve_tangent_normal(kg, sd);
  675. return set_attribute_float3(f, type, derivatives, val);
  676. }
  677. else
  678. return false;
  679. }
  680. bool OSLRenderServices::get_background_attribute(
  681. KernelGlobals *kg, ShaderData *sd, ustring name, TypeDesc type, bool derivatives, void *val)
  682. {
  683. if (name == u_path_ray_length) {
  684. /* Ray Length */
  685. float f = sd->ray_length;
  686. return set_attribute_float(f, type, derivatives, val);
  687. }
  688. else if (name == u_path_ray_depth) {
  689. /* Ray Depth */
  690. PathState *state = sd->osl_path_state;
  691. int f = state->bounce;
  692. return set_attribute_int(f, type, derivatives, val);
  693. }
  694. else if (name == u_path_diffuse_depth) {
  695. /* Diffuse Ray Depth */
  696. PathState *state = sd->osl_path_state;
  697. int f = state->diffuse_bounce;
  698. return set_attribute_int(f, type, derivatives, val);
  699. }
  700. else if (name == u_path_glossy_depth) {
  701. /* Glossy Ray Depth */
  702. PathState *state = sd->osl_path_state;
  703. int f = state->glossy_bounce;
  704. return set_attribute_int(f, type, derivatives, val);
  705. }
  706. else if (name == u_path_transmission_depth) {
  707. /* Transmission Ray Depth */
  708. PathState *state = sd->osl_path_state;
  709. int f = state->transmission_bounce;
  710. return set_attribute_int(f, type, derivatives, val);
  711. }
  712. else if (name == u_path_transparent_depth) {
  713. /* Transparent Ray Depth */
  714. PathState *state = sd->osl_path_state;
  715. int f = state->transparent_bounce;
  716. return set_attribute_int(f, type, derivatives, val);
  717. }
  718. else if (name == u_path_transmission_depth) {
  719. /* Transmission Ray Depth */
  720. PathState *state = sd->osl_path_state;
  721. int f = state->transmission_bounce;
  722. return set_attribute_int(f, type, derivatives, val);
  723. }
  724. else if (name == u_ndc) {
  725. /* NDC coordinates with special exception for otho */
  726. OSLThreadData *tdata = kg->osl_tdata;
  727. OSL::ShaderGlobals *globals = &tdata->globals;
  728. float3 ndc[3];
  729. if ((globals->raytype & PATH_RAY_CAMERA) && sd->object == OBJECT_NONE &&
  730. kernel_data.cam.type == CAMERA_ORTHOGRAPHIC) {
  731. ndc[0] = camera_world_to_ndc(kg, sd, sd->ray_P);
  732. if (derivatives) {
  733. ndc[1] = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dx) - ndc[0];
  734. ndc[2] = camera_world_to_ndc(kg, sd, sd->ray_P + sd->ray_dP.dy) - ndc[0];
  735. }
  736. }
  737. else {
  738. ndc[0] = camera_world_to_ndc(kg, sd, sd->P);
  739. if (derivatives) {
  740. ndc[1] = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dx) - ndc[0];
  741. ndc[2] = camera_world_to_ndc(kg, sd, sd->P + sd->dP.dy) - ndc[0];
  742. }
  743. }
  744. return set_attribute_float3(ndc, type, derivatives, val);
  745. }
  746. else
  747. return false;
  748. }
  749. bool OSLRenderServices::get_attribute(OSL::ShaderGlobals *sg,
  750. bool derivatives,
  751. ustring object_name,
  752. TypeDesc type,
  753. ustring name,
  754. void *val)
  755. {
  756. if (sg == NULL || sg->renderstate == NULL)
  757. return false;
  758. ShaderData *sd = (ShaderData *)(sg->renderstate);
  759. return get_attribute(sd, derivatives, object_name, type, name, val);
  760. }
  761. bool OSLRenderServices::get_attribute(
  762. ShaderData *sd, bool derivatives, ustring object_name, TypeDesc type, ustring name, void *val)
  763. {
  764. KernelGlobals *kg = sd->osl_globals;
  765. int prim_type = 0;
  766. int object;
  767. /* lookup of attribute on another object */
  768. if (object_name != u_empty) {
  769. OSLGlobals::ObjectNameMap::iterator it = kg->osl->object_name_map.find(object_name);
  770. if (it == kg->osl->object_name_map.end())
  771. return false;
  772. object = it->second;
  773. }
  774. else {
  775. object = sd->object;
  776. prim_type = attribute_primitive_type(kg, sd);
  777. if (object == OBJECT_NONE)
  778. return get_background_attribute(kg, sd, name, type, derivatives, val);
  779. }
  780. /* find attribute on object */
  781. object = object * ATTR_PRIM_TYPES + prim_type;
  782. OSLGlobals::AttributeMap &attribute_map = kg->osl->attribute_map[object];
  783. OSLGlobals::AttributeMap::iterator it = attribute_map.find(name);
  784. if (it != attribute_map.end()) {
  785. const OSLGlobals::Attribute &attr = it->second;
  786. if (attr.desc.element != ATTR_ELEMENT_OBJECT) {
  787. /* triangle and vertex attributes */
  788. if (get_primitive_attribute(kg, sd, attr, type, derivatives, val))
  789. return true;
  790. else
  791. return get_mesh_attribute(kg, sd, attr, type, derivatives, val);
  792. }
  793. else {
  794. /* object attribute */
  795. get_object_attribute(attr, derivatives, val);
  796. return true;
  797. }
  798. }
  799. else {
  800. /* not found in attribute, check standard object info */
  801. bool is_std_object_attribute = get_object_standard_attribute(
  802. kg, sd, name, type, derivatives, val);
  803. if (is_std_object_attribute)
  804. return true;
  805. return get_background_attribute(kg, sd, name, type, derivatives, val);
  806. }
  807. return false;
  808. }
  809. bool OSLRenderServices::get_userdata(
  810. bool derivatives, ustring name, TypeDesc type, OSL::ShaderGlobals *sg, void *val)
  811. {
  812. return false; /* disabled by lockgeom */
  813. }
  814. TextureSystem::TextureHandle *OSLRenderServices::get_texture_handle(ustring filename)
  815. {
  816. OSLTextureHandleMap::iterator it = textures.find(filename);
  817. /* For non-OIIO textures, just return a pointer to our own OSLTextureHandle. */
  818. if (it != textures.end()) {
  819. if (it->second->type != OSLTextureHandle::OIIO) {
  820. return (TextureSystem::TextureHandle *)it->second.get();
  821. }
  822. }
  823. /* Get handle from OpenImageIO. */
  824. OSL::TextureSystem *ts = texture_system;
  825. TextureSystem::TextureHandle *handle = ts->get_texture_handle(filename);
  826. if (handle == NULL) {
  827. return NULL;
  828. }
  829. /* Insert new OSLTextureHandle if needed. */
  830. if (it == textures.end()) {
  831. textures.insert(filename, new OSLTextureHandle(OSLTextureHandle::OIIO));
  832. it = textures.find(filename);
  833. }
  834. /* Assign OIIO texture handle and return. */
  835. it->second->oiio_handle = handle;
  836. return (TextureSystem::TextureHandle *)it->second.get();
  837. }
  838. bool OSLRenderServices::good(TextureSystem::TextureHandle *texture_handle)
  839. {
  840. OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
  841. if (handle->oiio_handle) {
  842. OSL::TextureSystem *ts = texture_system;
  843. return ts->good(handle->oiio_handle);
  844. }
  845. else {
  846. return true;
  847. }
  848. }
  849. bool OSLRenderServices::texture(ustring filename,
  850. TextureHandle *texture_handle,
  851. TexturePerthread *texture_thread_info,
  852. TextureOpt &options,
  853. OSL::ShaderGlobals *sg,
  854. float s,
  855. float t,
  856. float dsdx,
  857. float dtdx,
  858. float dsdy,
  859. float dtdy,
  860. int nchannels,
  861. float *result,
  862. float *dresultds,
  863. float *dresultdt,
  864. ustring *errormessage)
  865. {
  866. OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
  867. OSLTextureHandle::Type texture_type = (handle) ? handle->type : OSLTextureHandle::OIIO;
  868. ShaderData *sd = (ShaderData *)(sg->renderstate);
  869. KernelGlobals *kernel_globals = sd->osl_globals;
  870. bool status = false;
  871. switch (texture_type) {
  872. case OSLTextureHandle::BEVEL: {
  873. /* Bevel shader hack. */
  874. if (nchannels >= 3) {
  875. PathState *state = sd->osl_path_state;
  876. int num_samples = (int)s;
  877. float radius = t;
  878. float3 N = svm_bevel(kernel_globals, sd, state, radius, num_samples);
  879. result[0] = N.x;
  880. result[1] = N.y;
  881. result[2] = N.z;
  882. status = true;
  883. }
  884. break;
  885. }
  886. case OSLTextureHandle::AO: {
  887. /* AO shader hack. */
  888. PathState *state = sd->osl_path_state;
  889. int num_samples = (int)s;
  890. float radius = t;
  891. float3 N = make_float3(dsdx, dtdx, dsdy);
  892. int flags = 0;
  893. if ((int)dtdy) {
  894. flags |= NODE_AO_INSIDE;
  895. }
  896. if ((int)options.sblur) {
  897. flags |= NODE_AO_ONLY_LOCAL;
  898. }
  899. if ((int)options.tblur) {
  900. flags |= NODE_AO_GLOBAL_RADIUS;
  901. }
  902. result[0] = svm_ao(kernel_globals, sd, N, state, radius, num_samples, flags);
  903. status = true;
  904. break;
  905. }
  906. case OSLTextureHandle::SVM: {
  907. /* Packed texture. */
  908. float4 rgba = kernel_tex_image_interp(kernel_globals, handle->svm_slot, s, 1.0f - t);
  909. result[0] = rgba[0];
  910. if (nchannels > 1)
  911. result[1] = rgba[1];
  912. if (nchannels > 2)
  913. result[2] = rgba[2];
  914. if (nchannels > 3)
  915. result[3] = rgba[3];
  916. status = true;
  917. break;
  918. }
  919. case OSLTextureHandle::IES: {
  920. /* IES light. */
  921. result[0] = kernel_ies_interp(kernel_globals, handle->svm_slot, s, t);
  922. status = true;
  923. break;
  924. }
  925. case OSLTextureHandle::OIIO: {
  926. /* OpenImageIO texture cache. */
  927. OSL::TextureSystem *ts = texture_system;
  928. if (handle && handle->oiio_handle) {
  929. if (texture_thread_info == NULL) {
  930. OSLThreadData *tdata = kernel_globals->osl_tdata;
  931. texture_thread_info = tdata->oiio_thread_info;
  932. }
  933. status = ts->texture(handle->oiio_handle,
  934. texture_thread_info,
  935. options,
  936. s,
  937. t,
  938. dsdx,
  939. dtdx,
  940. dsdy,
  941. dtdy,
  942. nchannels,
  943. result,
  944. dresultds,
  945. dresultdt);
  946. }
  947. else {
  948. status = ts->texture(filename,
  949. options,
  950. s,
  951. t,
  952. dsdx,
  953. dtdx,
  954. dsdy,
  955. dtdy,
  956. nchannels,
  957. result,
  958. dresultds,
  959. dresultdt);
  960. }
  961. if (!status) {
  962. /* This might be slow, but prevents error messages leak and
  963. * other nasty stuff happening. */
  964. ts->geterror();
  965. }
  966. else if (handle && handle->processor) {
  967. ColorSpaceManager::to_scene_linear(handle->processor, result, nchannels);
  968. }
  969. break;
  970. }
  971. }
  972. if (!status) {
  973. if (nchannels == 3 || nchannels == 4) {
  974. result[0] = 1.0f;
  975. result[1] = 0.0f;
  976. result[2] = 1.0f;
  977. if (nchannels == 4)
  978. result[3] = 1.0f;
  979. }
  980. }
  981. return status;
  982. }
  983. bool OSLRenderServices::texture3d(ustring filename,
  984. TextureHandle *texture_handle,
  985. TexturePerthread *texture_thread_info,
  986. TextureOpt &options,
  987. OSL::ShaderGlobals *sg,
  988. const OSL::Vec3 &P,
  989. const OSL::Vec3 &dPdx,
  990. const OSL::Vec3 &dPdy,
  991. const OSL::Vec3 &dPdz,
  992. int nchannels,
  993. float *result,
  994. float *dresultds,
  995. float *dresultdt,
  996. float *dresultdr,
  997. ustring *errormessage)
  998. {
  999. OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
  1000. OSLTextureHandle::Type texture_type = (handle) ? handle->type : OSLTextureHandle::OIIO;
  1001. bool status = false;
  1002. switch (texture_type) {
  1003. case OSLTextureHandle::SVM: {
  1004. /* Packed texture. */
  1005. ShaderData *sd = (ShaderData *)(sg->renderstate);
  1006. KernelGlobals *kernel_globals = sd->osl_globals;
  1007. int slot = handle->svm_slot;
  1008. float4 rgba = kernel_tex_image_interp_3d(
  1009. kernel_globals, slot, P.x, P.y, P.z, INTERPOLATION_NONE);
  1010. result[0] = rgba[0];
  1011. if (nchannels > 1)
  1012. result[1] = rgba[1];
  1013. if (nchannels > 2)
  1014. result[2] = rgba[2];
  1015. if (nchannels > 3)
  1016. result[3] = rgba[3];
  1017. status = true;
  1018. break;
  1019. }
  1020. case OSLTextureHandle::OIIO: {
  1021. /* OpenImageIO texture cache. */
  1022. OSL::TextureSystem *ts = texture_system;
  1023. if (handle && handle->oiio_handle) {
  1024. if (texture_thread_info == NULL) {
  1025. ShaderData *sd = (ShaderData *)(sg->renderstate);
  1026. KernelGlobals *kernel_globals = sd->osl_globals;
  1027. OSLThreadData *tdata = kernel_globals->osl_tdata;
  1028. texture_thread_info = tdata->oiio_thread_info;
  1029. }
  1030. status = ts->texture3d(handle->oiio_handle,
  1031. texture_thread_info,
  1032. options,
  1033. P,
  1034. dPdx,
  1035. dPdy,
  1036. dPdz,
  1037. nchannels,
  1038. result,
  1039. dresultds,
  1040. dresultdt,
  1041. dresultdr);
  1042. }
  1043. else {
  1044. status = ts->texture3d(filename,
  1045. options,
  1046. P,
  1047. dPdx,
  1048. dPdy,
  1049. dPdz,
  1050. nchannels,
  1051. result,
  1052. dresultds,
  1053. dresultdt,
  1054. dresultdr);
  1055. }
  1056. if (!status) {
  1057. /* This might be slow, but prevents error messages leak and
  1058. * other nasty stuff happening. */
  1059. ts->geterror();
  1060. }
  1061. else if (handle && handle->processor) {
  1062. ColorSpaceManager::to_scene_linear(handle->processor, result, nchannels);
  1063. }
  1064. break;
  1065. }
  1066. case OSLTextureHandle::IES:
  1067. case OSLTextureHandle::AO:
  1068. case OSLTextureHandle::BEVEL: {
  1069. status = false;
  1070. break;
  1071. }
  1072. }
  1073. if (!status) {
  1074. if (nchannels == 3 || nchannels == 4) {
  1075. result[0] = 1.0f;
  1076. result[1] = 0.0f;
  1077. result[2] = 1.0f;
  1078. if (nchannels == 4)
  1079. result[3] = 1.0f;
  1080. }
  1081. }
  1082. return status;
  1083. }
  1084. bool OSLRenderServices::environment(ustring filename,
  1085. TextureHandle *texture_handle,
  1086. TexturePerthread *thread_info,
  1087. TextureOpt &options,
  1088. OSL::ShaderGlobals *sg,
  1089. const OSL::Vec3 &R,
  1090. const OSL::Vec3 &dRdx,
  1091. const OSL::Vec3 &dRdy,
  1092. int nchannels,
  1093. float *result,
  1094. float *dresultds,
  1095. float *dresultdt,
  1096. ustring *errormessage)
  1097. {
  1098. OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
  1099. OSL::TextureSystem *ts = texture_system;
  1100. bool status = false;
  1101. if (handle && handle->oiio_handle) {
  1102. if (thread_info == NULL) {
  1103. ShaderData *sd = (ShaderData *)(sg->renderstate);
  1104. KernelGlobals *kernel_globals = sd->osl_globals;
  1105. OSLThreadData *tdata = kernel_globals->osl_tdata;
  1106. thread_info = tdata->oiio_thread_info;
  1107. }
  1108. status = ts->environment(handle->oiio_handle,
  1109. thread_info,
  1110. options,
  1111. R,
  1112. dRdx,
  1113. dRdy,
  1114. nchannels,
  1115. result,
  1116. dresultds,
  1117. dresultdt);
  1118. }
  1119. else {
  1120. status = ts->environment(
  1121. filename, options, R, dRdx, dRdy, nchannels, result, dresultds, dresultdt);
  1122. }
  1123. if (!status) {
  1124. if (nchannels == 3 || nchannels == 4) {
  1125. result[0] = 1.0f;
  1126. result[1] = 0.0f;
  1127. result[2] = 1.0f;
  1128. if (nchannels == 4)
  1129. result[3] = 1.0f;
  1130. }
  1131. }
  1132. else if (handle && handle->processor) {
  1133. ColorSpaceManager::to_scene_linear(handle->processor, result, nchannels);
  1134. }
  1135. return status;
  1136. }
  1137. bool OSLRenderServices::get_texture_info(OSL::ShaderGlobals *sg,
  1138. ustring filename,
  1139. TextureHandle *texture_handle,
  1140. int subimage,
  1141. ustring dataname,
  1142. TypeDesc datatype,
  1143. void *data)
  1144. {
  1145. OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
  1146. /* No texture info for other texture types. */
  1147. if (handle && handle->type != OSLTextureHandle::OIIO) {
  1148. return false;
  1149. }
  1150. /* Get texture info from OpenImageIO. */
  1151. OSL::TextureSystem *ts = texture_system;
  1152. return ts->get_texture_info(filename, subimage, dataname, datatype, data);
  1153. }
  1154. int OSLRenderServices::pointcloud_search(OSL::ShaderGlobals *sg,
  1155. ustring filename,
  1156. const OSL::Vec3 &center,
  1157. float radius,
  1158. int max_points,
  1159. bool sort,
  1160. size_t *out_indices,
  1161. float *out_distances,
  1162. int derivs_offset)
  1163. {
  1164. return 0;
  1165. }
  1166. int OSLRenderServices::pointcloud_get(OSL::ShaderGlobals *sg,
  1167. ustring filename,
  1168. size_t *indices,
  1169. int count,
  1170. ustring attr_name,
  1171. TypeDesc attr_type,
  1172. void *out_data)
  1173. {
  1174. return 0;
  1175. }
  1176. bool OSLRenderServices::pointcloud_write(OSL::ShaderGlobals *sg,
  1177. ustring filename,
  1178. const OSL::Vec3 &pos,
  1179. int nattribs,
  1180. const ustring *names,
  1181. const TypeDesc *types,
  1182. const void **data)
  1183. {
  1184. return false;
  1185. }
  1186. bool OSLRenderServices::trace(TraceOpt &options,
  1187. OSL::ShaderGlobals *sg,
  1188. const OSL::Vec3 &P,
  1189. const OSL::Vec3 &dPdx,
  1190. const OSL::Vec3 &dPdy,
  1191. const OSL::Vec3 &R,
  1192. const OSL::Vec3 &dRdx,
  1193. const OSL::Vec3 &dRdy)
  1194. {
  1195. /* todo: options.shader support, maybe options.traceset */
  1196. ShaderData *sd = (ShaderData *)(sg->renderstate);
  1197. /* setup ray */
  1198. Ray ray;
  1199. ray.P = TO_FLOAT3(P);
  1200. ray.D = TO_FLOAT3(R);
  1201. ray.t = (options.maxdist == 1.0e30f) ? FLT_MAX : options.maxdist - options.mindist;
  1202. ray.time = sd->time;
  1203. if (options.mindist == 0.0f) {
  1204. /* avoid self-intersections */
  1205. if (ray.P == sd->P) {
  1206. bool transmit = (dot(sd->Ng, ray.D) < 0.0f);
  1207. ray.P = ray_offset(sd->P, (transmit) ? -sd->Ng : sd->Ng);
  1208. }
  1209. }
  1210. else {
  1211. /* offset for minimum distance */
  1212. ray.P += options.mindist * ray.D;
  1213. }
  1214. /* ray differentials */
  1215. ray.dP.dx = TO_FLOAT3(dPdx);
  1216. ray.dP.dy = TO_FLOAT3(dPdy);
  1217. ray.dD.dx = TO_FLOAT3(dRdx);
  1218. ray.dD.dy = TO_FLOAT3(dRdy);
  1219. /* allocate trace data */
  1220. OSLTraceData *tracedata = (OSLTraceData *)sg->tracedata;
  1221. tracedata->ray = ray;
  1222. tracedata->setup = false;
  1223. tracedata->init = true;
  1224. tracedata->sd.osl_globals = sd->osl_globals;
  1225. KernelGlobals *kg = sd->osl_globals;
  1226. /* Can't raytrace from shaders like displacement, before BVH exists. */
  1227. if (kernel_data.bvh.bvh_layout == BVH_LAYOUT_NONE) {
  1228. return false;
  1229. }
  1230. /* Raytrace, leaving out shadow opaque to avoid early exit. */
  1231. uint visibility = PATH_RAY_ALL_VISIBILITY - PATH_RAY_SHADOW_OPAQUE;
  1232. return scene_intersect(kg, ray, visibility, &tracedata->isect);
  1233. }
  1234. bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg,
  1235. ustring source,
  1236. ustring name,
  1237. TypeDesc type,
  1238. void *val,
  1239. bool derivatives)
  1240. {
  1241. OSLTraceData *tracedata = (OSLTraceData *)sg->tracedata;
  1242. if (source == u_trace && tracedata->init) {
  1243. if (name == u_hit) {
  1244. return set_attribute_int((tracedata->isect.prim != PRIM_NONE), type, derivatives, val);
  1245. }
  1246. else if (tracedata->isect.prim != PRIM_NONE) {
  1247. if (name == u_hitdist) {
  1248. float f[3] = {tracedata->isect.t, 0.0f, 0.0f};
  1249. return set_attribute_float(f, type, derivatives, val);
  1250. }
  1251. else {
  1252. ShaderData *sd = &tracedata->sd;
  1253. KernelGlobals *kg = sd->osl_globals;
  1254. if (!tracedata->setup) {
  1255. /* lazy shader data setup */
  1256. shader_setup_from_ray(kg, sd, &tracedata->isect, &tracedata->ray);
  1257. tracedata->setup = true;
  1258. }
  1259. if (name == u_N) {
  1260. return set_attribute_float3(sd->N, type, derivatives, val);
  1261. }
  1262. else if (name == u_Ng) {
  1263. return set_attribute_float3(sd->Ng, type, derivatives, val);
  1264. }
  1265. else if (name == u_P) {
  1266. float3 f[3] = {sd->P, sd->dP.dx, sd->dP.dy};
  1267. return set_attribute_float3(f, type, derivatives, val);
  1268. }
  1269. else if (name == u_I) {
  1270. float3 f[3] = {sd->I, sd->dI.dx, sd->dI.dy};
  1271. return set_attribute_float3(f, type, derivatives, val);
  1272. }
  1273. else if (name == u_u) {
  1274. float f[3] = {sd->u, sd->du.dx, sd->du.dy};
  1275. return set_attribute_float(f, type, derivatives, val);
  1276. }
  1277. else if (name == u_v) {
  1278. float f[3] = {sd->v, sd->dv.dx, sd->dv.dy};
  1279. return set_attribute_float(f, type, derivatives, val);
  1280. }
  1281. return get_attribute(sd, derivatives, u_empty, type, name, val);
  1282. }
  1283. }
  1284. }
  1285. return false;
  1286. }
  1287. CCL_NAMESPACE_END