b0461013239f4a8f3a38837c6c0ca815027d42a0
[blender.git] / intern / cycles / kernel / osl / osl_shader.cpp
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
17 #include "kernel_compat_cpu.h"
18 #include "kernel_montecarlo.h"
19 #include "kernel_types.h"
20 #include "kernel_globals.h"
21 #include "kernel_object.h"
22
23 #include "closure/bsdf_diffuse.h"
24 #include "closure/bssrdf.h"
25
26 #include "osl_bssrdf.h"
27 #include "osl_closures.h"
28 #include "osl_globals.h"
29 #include "osl_services.h"
30 #include "osl_shader.h"
31
32 #include "util_foreach.h"
33
34 #include "attribute.h"
35
36 #include <OSL/oslexec.h>
37
38 CCL_NAMESPACE_BEGIN
39
40 /* Threads */
41
42 void OSLShader::thread_init(KernelGlobals *kg, KernelGlobals *kernel_globals, OSLGlobals *osl_globals)
43 {
44         /* no osl used? */
45         if(!osl_globals->use) {
46                 kg->osl = NULL;
47                 return;
48         }
49
50         /* per thread kernel data init*/
51         kg->osl = osl_globals;
52         kg->osl->services->thread_init(kernel_globals, osl_globals->ts);
53
54         OSL::ShadingSystem *ss = kg->osl->ss;
55         OSLThreadData *tdata = new OSLThreadData();
56
57         memset(&tdata->globals, 0, sizeof(OSL::ShaderGlobals));
58         tdata->globals.tracedata = &tdata->tracedata;
59         tdata->globals.flipHandedness = false;
60         tdata->osl_thread_info = ss->create_thread_info();
61
62         for(int i = 0; i < SHADER_CONTEXT_NUM; i++)
63                 tdata->context[i] = ss->get_context(tdata->osl_thread_info);
64
65         tdata->oiio_thread_info = osl_globals->ts->get_perthread_info();
66
67         kg->osl_ss = (OSLShadingSystem*)ss;
68         kg->osl_tdata = tdata;
69 }
70
71 void OSLShader::thread_free(KernelGlobals *kg)
72 {
73         if(!kg->osl)
74                 return;
75
76         OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
77         OSLThreadData *tdata = kg->osl_tdata;
78
79         for(int i = 0; i < SHADER_CONTEXT_NUM; i++)
80                 ss->release_context(tdata->context[i]);
81
82         ss->destroy_thread_info(tdata->osl_thread_info);
83
84         delete tdata;
85
86         kg->osl = NULL;
87         kg->osl_ss = NULL;
88         kg->osl_tdata = NULL;
89 }
90
91 /* Globals */
92
93 static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
94                                         int path_flag, OSLThreadData *tdata)
95 {
96         OSL::ShaderGlobals *globals = &tdata->globals;
97
98         /* copy from shader data to shader globals */
99         globals->P = TO_VEC3(sd->P);
100         globals->dPdx = TO_VEC3(sd->dP.dx);
101         globals->dPdy = TO_VEC3(sd->dP.dy);
102         globals->I = TO_VEC3(sd->I);
103         globals->dIdx = TO_VEC3(sd->dI.dx);
104         globals->dIdy = TO_VEC3(sd->dI.dy);
105         globals->N = TO_VEC3(sd->N);
106         globals->Ng = TO_VEC3(sd->Ng);
107         globals->u = sd->u;
108         globals->dudx = sd->du.dx;
109         globals->dudy = sd->du.dy;
110         globals->v = sd->v;
111         globals->dvdx = sd->dv.dx;
112         globals->dvdy = sd->dv.dy;
113         globals->dPdu = TO_VEC3(sd->dPdu);
114         globals->dPdv = TO_VEC3(sd->dPdv);
115         globals->surfacearea = (sd->object == ~0) ? 1.0f : object_surface_area(kg, sd->object);
116         globals->time = sd->time;
117
118         /* booleans */
119         globals->raytype = path_flag;
120         globals->backfacing = (sd->flag & SD_BACKFACING);
121
122         /* shader data to be used in services callbacks */
123         globals->renderstate = sd; 
124
125         /* hacky, we leave it to services to fetch actual object matrix */
126         globals->shader2common = sd;
127         globals->object2common = sd;
128
129         /* must be set to NULL before execute */
130         globals->Ci = NULL;
131
132         /* clear trace data */
133         tdata->tracedata.init = false;
134
135         /* used by renderservices */
136         sd->osl_globals = kg;
137 }
138
139 /* Surface */
140
141 static void flatten_surface_closure_tree(ShaderData *sd, int path_flag,
142                                          const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f))
143 {
144         /* OSL gives us a closure tree, we flatten it into arrays per
145          * closure type, for evaluation, sampling, etc later on. */
146
147         if (closure->type == OSL::ClosureColor::COMPONENT) {
148                 OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
149                 CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
150
151                 if (prim) {
152                         ShaderClosure sc;
153
154 #ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
155                         weight = weight*TO_FLOAT3(comp->w);
156 #endif
157                         sc.weight = weight;
158
159                         prim->setup();
160
161                         switch (prim->category) {
162                                 case CClosurePrimitive::BSDF: {
163                                         CBSDFClosure *bsdf = (CBSDFClosure *)prim;
164                                         int scattering = bsdf->scattering();
165
166                                         /* no caustics option */
167                                         if(scattering == LABEL_GLOSSY && (path_flag & PATH_RAY_DIFFUSE)) {
168                                                 KernelGlobals *kg = sd->osl_globals;
169                                                 if(kernel_data.integrator.no_caustics)
170                                                         return;
171                                         }
172
173                                         /* sample weight */
174                                         float sample_weight = fabsf(average(weight));
175
176                                         sc.sample_weight = sample_weight;
177
178                                         sc.type = bsdf->sc.type;
179                                         sc.N = bsdf->sc.N;
180                                         sc.T = bsdf->sc.T;
181                                         sc.data0 = bsdf->sc.data0;
182                                         sc.data1 = bsdf->sc.data1;
183                                         sc.prim = bsdf->sc.prim;
184
185 #ifdef __HAIR__
186                                         sc.offset = bsdf->sc.offset;
187 #endif
188
189                                         /* add */
190                                         if(sc.sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE) {
191                                                 sd->closure[sd->num_closure++] = sc;
192                                                 sd->flag |= bsdf->shaderdata_flag();
193                                         }
194                                         break;
195                                 }
196                                 case CClosurePrimitive::Emissive: {
197                                         /* sample weight */
198                                         float sample_weight = fabsf(average(weight));
199
200                                         sc.sample_weight = sample_weight;
201                                         sc.type = CLOSURE_EMISSION_ID;
202                                         sc.data0 = 0.0f;
203                                         sc.data1 = 0.0f;
204                                         sc.prim = NULL;
205
206                                         /* flag */
207                                         if(sd->num_closure < MAX_CLOSURE) {
208                                                 sd->closure[sd->num_closure++] = sc;
209                                                 sd->flag |= SD_EMISSION;
210                                         }
211                                         break;
212                                 }
213                                 case CClosurePrimitive::AmbientOcclusion: {
214                                         /* sample weight */
215                                         float sample_weight = fabsf(average(weight));
216
217                                         sc.sample_weight = sample_weight;
218                                         sc.type = CLOSURE_AMBIENT_OCCLUSION_ID;
219                                         sc.data0 = 0.0f;
220                                         sc.data1 = 0.0f;
221                                         sc.prim = NULL;
222
223                                         if(sd->num_closure < MAX_CLOSURE) {
224                                                 sd->closure[sd->num_closure++] = sc;
225                                                 sd->flag |= SD_AO;
226                                         }
227                                         break;
228                                 }
229                                 case CClosurePrimitive::Holdout: {
230                                         sc.sample_weight = 0.0f;
231                                         sc.type = CLOSURE_HOLDOUT_ID;
232                                         sc.data0 = 0.0f;
233                                         sc.data1 = 0.0f;
234                                         sc.prim = NULL;
235
236                                         if(sd->num_closure < MAX_CLOSURE) {
237                                                 sd->closure[sd->num_closure++] = sc;
238                                                 sd->flag |= SD_HOLDOUT;
239                                         }
240                                         break;
241                                 }
242                                 case CClosurePrimitive::BSSRDF: {
243                                         CBSSRDFClosure *bssrdf = (CBSSRDFClosure *)prim;
244                                         float sample_weight = fabsf(average(weight));
245
246                                         if(sample_weight > 1e-5f && sd->num_closure+2 < MAX_CLOSURE) {
247                                                 sc.sample_weight = sample_weight;
248
249                                                 sc.type = bssrdf->sc.type;
250                                                 sc.N = bssrdf->sc.N;
251                                                 sc.data1 = bssrdf->sc.data1;
252                                                 sc.T.x = bssrdf->sc.T.x;
253                                                 sc.prim = NULL;
254
255                                                 /* disable in case of diffuse ancestor, can't see it well then and
256                                                  * adds considerably noise due to probabilities of continuing path
257                                                  * getting lower and lower */
258                                                 if(path_flag & PATH_RAY_DIFFUSE_ANCESTOR)
259                                                         bssrdf->radius = make_float3(0.0f, 0.0f, 0.0f);
260
261                                                 /* create one closure for each color channel */
262                                                 if(fabsf(weight.x) > 0.0f) {
263                                                         sc.weight = make_float3(weight.x, 0.0f, 0.0f);
264                                                         sc.data0 = bssrdf->radius.x;
265                                                         sd->flag |= bssrdf_setup(&sc, sc.type);
266                                                         sd->closure[sd->num_closure++] = sc;
267                                                 }
268
269                                                 if(fabsf(weight.y) > 0.0f) {
270                                                         sc.weight = make_float3(0.0f, weight.y, 0.0f);
271                                                         sc.data0 = bssrdf->radius.y;
272                                                         sd->flag |= bssrdf_setup(&sc, sc.type);
273                                                         sd->closure[sd->num_closure++] = sc;
274                                                 }
275
276                                                 if(fabsf(weight.z) > 0.0f) {
277                                                         sc.weight = make_float3(0.0f, 0.0f, weight.z);
278                                                         sc.data0 = bssrdf->radius.z;
279                                                         sd->flag |= bssrdf_setup(&sc, sc.type);
280                                                         sd->closure[sd->num_closure++] = sc;
281                                                 }
282                                         }
283                                         break;
284                                 }
285                                 case CClosurePrimitive::Background:
286                                 case CClosurePrimitive::Volume:
287                                         break; /* not relevant */
288                         }
289                 }
290         }
291         else if (closure->type == OSL::ClosureColor::MUL) {
292                 OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
293                 flatten_surface_closure_tree(sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight);
294         }
295         else if (closure->type == OSL::ClosureColor::ADD) {
296                 OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
297                 flatten_surface_closure_tree(sd, path_flag, add->closureA, weight);
298                 flatten_surface_closure_tree(sd, path_flag, add->closureB, weight);
299         }
300 }
301
302 void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx)
303 {
304         /* setup shader globals from shader data */
305         OSLThreadData *tdata = kg->osl_tdata;
306         shaderdata_to_shaderglobals(kg, sd, path_flag, tdata);
307
308         /* execute shader for this point */
309         OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
310         OSL::ShaderGlobals *globals = &tdata->globals;
311         OSL::ShadingContext *octx = tdata->context[(int)ctx];
312         int shader = sd->shader & SHADER_MASK;
313
314         if (kg->osl->surface_state[shader])
315                 ss->execute(*octx, *(kg->osl->surface_state[shader]), *globals);
316
317         /* flatten closure tree */
318         sd->num_closure = 0;
319         sd->randb_closure = randb;
320
321         if (globals->Ci)
322                 flatten_surface_closure_tree(sd, path_flag, globals->Ci);
323 }
324
325 /* Background */
326
327 static float3 flatten_background_closure_tree(const OSL::ClosureColor *closure)
328 {
329         /* OSL gives us a closure tree, if we are shading for background there
330          * is only one supported closure type at the moment, which has no evaluation
331          * functions, so we just sum the weights */
332
333         if (closure->type == OSL::ClosureColor::COMPONENT) {
334                 OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
335                 CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
336
337                 if (prim && prim->category == CClosurePrimitive::Background)
338 #ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
339                         return TO_FLOAT3(comp->w);
340 #else
341                         return make_float3(1.0f, 1.0f, 1.0f);
342 #endif
343         }
344         else if (closure->type == OSL::ClosureColor::MUL) {
345                 OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
346
347                 return TO_FLOAT3(mul->weight) * flatten_background_closure_tree(mul->closure);
348         }
349         else if (closure->type == OSL::ClosureColor::ADD) {
350                 OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
351
352                 return flatten_background_closure_tree(add->closureA) +
353                        flatten_background_closure_tree(add->closureB);
354         }
355
356         return make_float3(0.0f, 0.0f, 0.0f);
357 }
358
359 float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx)
360 {
361         /* setup shader globals from shader data */
362         OSLThreadData *tdata = kg->osl_tdata;
363         shaderdata_to_shaderglobals(kg, sd, path_flag, tdata);
364
365         /* execute shader for this point */
366         OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
367         OSL::ShaderGlobals *globals = &tdata->globals;
368         OSL::ShadingContext *octx = tdata->context[(int)ctx];
369
370         if (kg->osl->background_state)
371                 ss->execute(*octx, *(kg->osl->background_state), *globals);
372
373         /* return background color immediately */
374         if (globals->Ci)
375                 return flatten_background_closure_tree(globals->Ci);
376
377         return make_float3(0.0f, 0.0f, 0.0f);
378 }
379
380 /* Volume */
381
382 static void flatten_volume_closure_tree(ShaderData *sd,
383                                         const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f))
384 {
385         /* OSL gives us a closure tree, we flatten it into arrays per
386          * closure type, for evaluation, sampling, etc later on. */
387
388         if (closure->type == OSL::ClosureColor::COMPONENT) {
389                 OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
390                 CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
391
392                 if (prim) {
393                         ShaderClosure sc;
394
395 #ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
396                         weight = weight*TO_FLOAT3(comp->w);
397 #endif
398                         sc.weight = weight;
399
400                         prim->setup();
401
402                         switch (prim->category) {
403                                 case CClosurePrimitive::Volume: {
404                                         /* sample weight */
405                                         float sample_weight = fabsf(average(weight));
406
407                                         sc.sample_weight = sample_weight;
408                                         sc.type = CLOSURE_VOLUME_ID;
409                                         sc.data0 = 0.0f;
410                                         sc.data1 = 0.0f;
411                                         sc.prim = NULL;
412
413                                         /* add */
414                                         if(sc.sample_weight > 1e-5f && sd->num_closure < MAX_CLOSURE)
415                                                 sd->closure[sd->num_closure++] = sc;
416                                         break;
417                                 }
418                                 case CClosurePrimitive::Holdout:
419                                         break; /* not implemented */
420                                 case CClosurePrimitive::Background:
421                                 case CClosurePrimitive::BSDF:
422                                 case CClosurePrimitive::Emissive:
423                                 case CClosurePrimitive::BSSRDF:
424                                 case CClosurePrimitive::AmbientOcclusion:
425                                         break; /* not relevant */
426                         }
427                 }
428         }
429         else if (closure->type == OSL::ClosureColor::MUL) {
430                 OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
431                 flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight);
432         }
433         else if (closure->type == OSL::ClosureColor::ADD) {
434                 OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
435                 flatten_volume_closure_tree(sd, add->closureA, weight);
436                 flatten_volume_closure_tree(sd, add->closureB, weight);
437         }
438 }
439
440 void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag, ShaderContext ctx)
441 {
442         /* setup shader globals from shader data */
443         OSLThreadData *tdata = kg->osl_tdata;
444         shaderdata_to_shaderglobals(kg, sd, path_flag, tdata);
445
446         /* execute shader */
447         OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
448         OSL::ShaderGlobals *globals = &tdata->globals;
449         OSL::ShadingContext *octx = tdata->context[(int)ctx];
450         int shader = sd->shader & SHADER_MASK;
451
452         if (kg->osl->volume_state[shader])
453                 ss->execute(*octx, *(kg->osl->volume_state[shader]), *globals);
454
455         if (globals->Ci)
456                 flatten_volume_closure_tree(sd, globals->Ci);
457 }
458
459 /* Displacement */
460
461 void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx)
462 {
463         /* setup shader globals from shader data */
464         OSLThreadData *tdata = kg->osl_tdata;
465         shaderdata_to_shaderglobals(kg, sd, 0, tdata);
466
467         /* execute shader */
468         OSL::ShadingSystem *ss = (OSL::ShadingSystem*)kg->osl_ss;
469         OSL::ShaderGlobals *globals = &tdata->globals;
470         OSL::ShadingContext *octx = tdata->context[(int)ctx];
471         int shader = sd->shader & SHADER_MASK;
472
473         if (kg->osl->displacement_state[shader])
474                 ss->execute(*octx, *(kg->osl->displacement_state[shader]), *globals);
475
476         /* get back position */
477         sd->P = TO_FLOAT3(globals->P);
478 }
479
480 /* BSDF Closure */
481
482 int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3& eval, float3& omega_in, differential3& domega_in, float& pdf)
483 {
484         CBSDFClosure *sample_bsdf = (CBSDFClosure *)sc->prim;
485
486         pdf = 0.0f;
487
488         return sample_bsdf->sample(sd->Ng,
489                                    sd->I, sd->dI.dx, sd->dI.dy,
490                                    randu, randv,
491                                    omega_in, domega_in.dx, domega_in.dy,
492                                    pdf, eval);
493 }
494
495 float3 OSLShader::bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, const float3& omega_in, float& pdf)
496 {
497         CBSDFClosure *bsdf = (CBSDFClosure *)sc->prim;
498         float3 bsdf_eval;
499
500         if (dot(sd->Ng, omega_in) >= 0.0f)
501                 bsdf_eval = bsdf->eval_reflect(sd->I, omega_in, pdf);
502         else
503                 bsdf_eval = bsdf->eval_transmit(sd->I, omega_in, pdf);
504         
505         return bsdf_eval;
506 }
507
508 void OSLShader::bsdf_blur(ShaderClosure *sc, float roughness)
509 {
510         CBSDFClosure *bsdf = (CBSDFClosure *)sc->prim;
511         bsdf->blur(roughness);
512 }
513
514 /* Attributes */
515
516 int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id, AttributeElement *elem)
517 {
518         /* for OSL, a hash map is used to lookup the attribute by name. */
519         int object = sd->object*ATTR_PRIM_TYPES;
520 #ifdef __HAIR__
521         if(sd->segment != ~0) object += ATTR_PRIM_CURVE;
522 #endif
523
524         OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object];
525         ustring stdname(std::string("geom:") + std::string(Attribute::standard_name((AttributeStandard)id)));
526         OSLGlobals::AttributeMap::const_iterator it = attr_map.find(stdname);
527
528         if (it != attr_map.end()) {
529                 const OSLGlobals::Attribute &osl_attr = it->second;
530                 *elem = osl_attr.elem;
531                 /* return result */
532                 return (osl_attr.elem == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : osl_attr.offset;
533         }
534         else
535                 return (int)ATTR_STD_NOT_FOUND;
536 }
537
538 CCL_NAMESPACE_END
539