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