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