Fix for Cycles OSL: The RenderServices pointer in ShadingSystem is no longer accessib...
[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_services.h"
25 #include "osl_shader.h"
26
27 #include "util_foreach.h"
28
29 #include <OSL/oslexec.h>
30
31 CCL_NAMESPACE_BEGIN
32
33 tls_ptr(OSLGlobals::ThreadData, OSLGlobals::thread_data);
34
35 /* Threads */
36
37 void OSLShader::thread_init(KernelGlobals *kg)
38 {
39         OSL::ShadingSystem *ss = kg->osl.ss;
40
41         OSLGlobals::ThreadData *tdata = new OSLGlobals::ThreadData();
42
43         memset(&tdata->globals, 0, sizeof(OSL::ShaderGlobals));
44         tdata->thread_info = ss->create_thread_info();
45
46         tls_set(kg->osl.thread_data, tdata);
47
48         kg->osl.services->thread_init(kg);
49 }
50
51 void OSLShader::thread_free(KernelGlobals *kg)
52 {
53         OSL::ShadingSystem *ss = kg->osl.ss;
54
55         OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
56
57         ss->destroy_thread_info(tdata->thread_info);
58
59         delete tdata;
60 }
61
62 /* Globals */
63
64 #define TO_VEC3(v) (*(OSL::Vec3 *)&(v))
65 #define TO_COLOR3(v) (*(OSL::Color3 *)&(v))
66 #define TO_FLOAT3(v) make_float3(v[0], v[1], v[2])
67
68 static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
69                                         int path_flag, OSL::ShaderGlobals *globals)
70 {
71         /* copy from shader data to shader globals */
72         globals->P = TO_VEC3(sd->P);
73         globals->dPdx = TO_VEC3(sd->dP.dx);
74         globals->dPdy = TO_VEC3(sd->dP.dy);
75         globals->I = TO_VEC3(sd->I);
76         globals->dIdx = TO_VEC3(sd->dI.dx);
77         globals->dIdy = TO_VEC3(sd->dI.dy);
78         globals->N = TO_VEC3(sd->N);
79         globals->Ng = TO_VEC3(sd->Ng);
80         globals->u = sd->u;
81         globals->dudx = sd->du.dx;
82         globals->dudy = sd->du.dy;
83         globals->v = sd->v;
84         globals->dvdx = sd->dv.dx;
85         globals->dvdy = sd->dv.dy;
86         globals->dPdu = TO_VEC3(sd->dPdu);
87         globals->dPdv = TO_VEC3(sd->dPdv);
88         globals->surfacearea = (sd->object == ~0) ? 1.0f : object_surface_area(kg, sd->object);
89
90         /* booleans */
91         globals->raytype = path_flag; /* todo: add our own ray types */
92         globals->backfacing = (sd->flag & SD_BACKFACING);
93
94         /* don't know yet if we need this */
95         globals->flipHandedness = false;
96         
97         /* shader data to be used in services callbacks */
98         globals->renderstate = sd; 
99
100         /* hacky, we leave it to services to fetch actual object matrix */
101         globals->shader2common = sd;
102         globals->object2common = sd;
103
104         /* must be set to NULL before execute */
105         globals->Ci = NULL;
106 }
107
108 /* Surface */
109
110 static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
111                                          const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f))
112 {
113         /* OSL gives us a closure tree, we flatten it into arrays per
114          * closure type, for evaluation, sampling, etc later on. */
115
116         if (closure->type == OSL::ClosureColor::COMPONENT) {
117                 OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
118                 OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive *)comp->data();
119
120                 if (prim) {
121                         ShaderClosure sc;
122                         sc.prim = prim;
123                         sc.weight = weight;
124
125                         switch (prim->category()) {
126                                 case OSL::ClosurePrimitive::BSDF: {
127                                         if (sd->num_closure == MAX_CLOSURE)
128                                                 return;
129
130                                         OSL::BSDFClosure *bsdf = (OSL::BSDFClosure *)prim;
131                                         ustring scattering = bsdf->scattering();
132
133                                         /* no caustics option */
134                                         if (no_glossy && scattering == OSL::Labels::GLOSSY)
135                                                 return;
136
137                                         /* sample weight */
138                                         float albedo = bsdf->albedo(TO_VEC3(sd->I));
139                                         float sample_weight = fabsf(average(weight)) * albedo;
140
141                                         sc.sample_weight = sample_weight;
142                                         sc.type = CLOSURE_BSDF_ID;
143
144                                         /* scattering flags */
145                                         if (scattering == OSL::Labels::DIFFUSE)
146                                                 sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL;
147                                         else if (scattering == OSL::Labels::GLOSSY)
148                                                 sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_GLOSSY;
149                                         else
150                                                 sd->flag |= SD_BSDF;
151
152                                         /* add */
153                                         sd->closure[sd->num_closure++] = sc;
154                                         break;
155                                 }
156                                 case OSL::ClosurePrimitive::Emissive: {
157                                         if (sd->num_closure == MAX_CLOSURE)
158                                                 return;
159
160                                         /* sample weight */
161                                         float sample_weight = fabsf(average(weight));
162
163                                         sc.sample_weight = sample_weight;
164                                         sc.type = CLOSURE_EMISSION_ID;
165
166                                         /* flag */
167                                         sd->flag |= SD_EMISSION;
168
169                                         sd->closure[sd->num_closure++] = sc;
170                                         break;
171                                 }
172                                 case OSL::ClosurePrimitive::Holdout:
173                                         if (sd->num_closure == MAX_CLOSURE)
174                                                 return;
175
176                                         sc.sample_weight = 0.0f;
177                                         sc.type = CLOSURE_HOLDOUT_ID;
178                                         sd->flag |= SD_HOLDOUT;
179                                         sd->closure[sd->num_closure++] = sc;
180                                         break;
181                                 case OSL::ClosurePrimitive::BSSRDF:
182                                 case OSL::ClosurePrimitive::Debug:
183                                         break; /* not implemented */
184                                 case OSL::ClosurePrimitive::Background:
185                                 case OSL::ClosurePrimitive::Volume:
186                                         break; /* not relevant */
187                         }
188                 }
189         }
190         else if (closure->type == OSL::ClosureColor::MUL) {
191                 OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
192                 flatten_surface_closure_tree(sd, no_glossy, mul->closure, TO_FLOAT3(mul->weight) * weight);
193         }
194         else if (closure->type == OSL::ClosureColor::ADD) {
195                 OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
196                 flatten_surface_closure_tree(sd, no_glossy, add->closureA, weight);
197                 flatten_surface_closure_tree(sd, no_glossy, add->closureB, weight);
198         }
199 }
200
201 void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag)
202 {
203         /* gather pointers */
204         OSL::ShadingSystem *ss = kg->osl.ss;
205         OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
206         OSL::ShaderGlobals *globals = &tdata->globals;
207         OSL::ShadingContext *ctx = ss->get_context(tdata->thread_info);
208
209         /* setup shader globals from shader data */
210         sd->osl_ctx = ctx;
211         shaderdata_to_shaderglobals(kg, sd, path_flag, globals);
212
213         /* execute shader for this point */
214         int shader = sd->shader & SHADER_MASK;
215
216         if (kg->osl.surface_state[shader])
217                 ss->execute(*ctx, *(kg->osl.surface_state[shader]), *globals);
218
219         /* flatten closure tree */
220         sd->num_closure = 0;
221         sd->randb_closure = randb;
222
223         if (globals->Ci) {
224                 bool no_glossy = (path_flag & PATH_RAY_DIFFUSE) && kernel_data.integrator.no_caustics;
225                 flatten_surface_closure_tree(sd, no_glossy, globals->Ci);
226         }
227 }
228
229 /* Background */
230
231 static float3 flatten_background_closure_tree(const OSL::ClosureColor *closure)
232 {
233         /* OSL gives us a closure tree, if we are shading for background there
234          * is only one supported closure type at the moment, which has no evaluation
235          * functions, so we just sum the weights */
236
237         if (closure->type == OSL::ClosureColor::COMPONENT) {
238                 OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
239                 OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive *)comp->data();
240
241                 if (prim && prim->category() == OSL::ClosurePrimitive::Background)
242                         return make_float3(1.0f, 1.0f, 1.0f);
243         }
244         else if (closure->type == OSL::ClosureColor::MUL) {
245                 OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
246
247                 return TO_FLOAT3(mul->weight) * flatten_background_closure_tree(mul->closure);
248         }
249         else if (closure->type == OSL::ClosureColor::ADD) {
250                 OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
251
252                 return flatten_background_closure_tree(add->closureA) +
253                        flatten_background_closure_tree(add->closureB);
254         }
255
256         return make_float3(0.0f, 0.0f, 0.0f);
257 }
258
259 float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag)
260 {
261         /* gather pointers */
262         OSL::ShadingSystem *ss = kg->osl.ss;
263         OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
264         OSL::ShaderGlobals *globals = &tdata->globals;
265         OSL::ShadingContext *ctx = ss->get_context(tdata->thread_info);
266
267         /* setup shader globals from shader data */
268         sd->osl_ctx = ctx;
269         shaderdata_to_shaderglobals(kg, sd, path_flag, globals);
270
271         /* execute shader for this point */
272         if (kg->osl.background_state)
273                 ss->execute(*ctx, *(kg->osl.background_state), *globals);
274
275         /* return background color immediately */
276         if (globals->Ci)
277                 return flatten_background_closure_tree(globals->Ci);
278
279         return make_float3(0.0f, 0.0f, 0.0f);
280 }
281
282 /* Volume */
283
284 static void flatten_volume_closure_tree(ShaderData *sd,
285                                         const OSL::ClosureColor *closure, float3 weight = make_float3(1.0f, 1.0f, 1.0f))
286 {
287         /* OSL gives us a closure tree, we flatten it into arrays per
288          * closure type, for evaluation, sampling, etc later on. */
289
290         if (closure->type == OSL::ClosureColor::COMPONENT) {
291                 OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
292                 OSL::ClosurePrimitive *prim = (OSL::ClosurePrimitive *)comp->data();
293
294                 if (prim) {
295                         ShaderClosure sc;
296                         sc.prim = prim;
297                         sc.weight = weight;
298
299                         switch (prim->category()) {
300                                 case OSL::ClosurePrimitive::Volume: {
301                                         if (sd->num_closure == MAX_CLOSURE)
302                                                 return;
303
304                                         /* sample weight */
305                                         float sample_weight = fabsf(average(weight));
306
307                                         sc.sample_weight = sample_weight;
308                                         sc.type = CLOSURE_VOLUME_ID;
309
310                                         /* add */
311                                         sd->closure[sd->num_closure++] = sc;
312                                         break;
313                                 }
314                                 case OSL::ClosurePrimitive::Holdout:
315                                 case OSL::ClosurePrimitive::Debug:
316                                         break; /* not implemented */
317                                 case OSL::ClosurePrimitive::Background:
318                                 case OSL::ClosurePrimitive::BSDF:
319                                 case OSL::ClosurePrimitive::Emissive:
320                                 case OSL::ClosurePrimitive::BSSRDF:
321                                         break; /* not relevant */
322                         }
323                 }
324         }
325         else if (closure->type == OSL::ClosureColor::MUL) {
326                 OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
327                 flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight);
328         }
329         else if (closure->type == OSL::ClosureColor::ADD) {
330                 OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
331                 flatten_volume_closure_tree(sd, add->closureA, weight);
332                 flatten_volume_closure_tree(sd, add->closureB, weight);
333         }
334 }
335
336 void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag)
337 {
338         /* gather pointers */
339         OSL::ShadingSystem *ss = kg->osl.ss;
340         OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
341         OSL::ShaderGlobals *globals = &tdata->globals;
342         OSL::ShadingContext *ctx = ss->get_context(tdata->thread_info);
343
344         /* setup shader globals from shader data */
345         sd->osl_ctx = ctx;
346         shaderdata_to_shaderglobals(kg, sd, path_flag, globals);
347
348         /* execute shader */
349         int shader = sd->shader & SHADER_MASK;
350
351         if (kg->osl.volume_state[shader])
352                 ss->execute(*ctx, *(kg->osl.volume_state[shader]), *globals);
353
354         if (globals->Ci)
355                 flatten_volume_closure_tree(sd, globals->Ci);
356 }
357
358 /* Displacement */
359
360 void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd)
361 {
362         /* gather pointers */
363         OSL::ShadingSystem *ss = kg->osl.ss;
364         OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
365         OSL::ShaderGlobals *globals = &tdata->globals;
366         OSL::ShadingContext *ctx = ss->get_context(tdata->thread_info);
367
368         /* setup shader globals from shader data */
369         sd->osl_ctx = ctx;
370         shaderdata_to_shaderglobals(kg, sd, 0, globals);
371
372         /* execute shader */
373         int shader = sd->shader & SHADER_MASK;
374
375         if (kg->osl.displacement_state[shader])
376                 ss->execute(*ctx, *(kg->osl.displacement_state[shader]), *globals);
377
378         /* get back position */
379         sd->P = TO_FLOAT3(globals->P);
380 }
381
382 void OSLShader::release(KernelGlobals *kg, const ShaderData *sd)
383 {
384         OSL::ShadingSystem *ss = kg->osl.ss;
385         OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
386         OSL::ShadingContext *ctx = ss->get_context(tdata->thread_info);
387
388         ss->release_context(ctx);
389 }
390
391 /* BSDF Closure */
392
393 int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3& eval, float3& omega_in, differential3& domega_in, float& pdf)
394 {
395         OSL::BSDFClosure *sample_bsdf = (OSL::BSDFClosure *)sc->prim;
396         int label = LABEL_NONE;
397
398         pdf = 0.0f;
399
400         /* sample BSDF closure */
401         ustring ulabel;
402
403         ulabel = sample_bsdf->sample(TO_VEC3(sd->Ng),
404                                      TO_VEC3(sd->I), TO_VEC3(sd->dI.dx), TO_VEC3(sd->dI.dy),
405                                      randu, randv,
406                                      TO_VEC3(omega_in), TO_VEC3(domega_in.dx), TO_VEC3(domega_in.dy),
407                                      pdf, TO_COLOR3(eval));
408
409         /* convert OSL label */
410         if (ulabel == OSL::Labels::REFLECT)
411                 label = LABEL_REFLECT;
412         else if (ulabel == OSL::Labels::TRANSMIT)
413                 label = LABEL_TRANSMIT;
414         else
415                 return LABEL_NONE;  /* sampling failed */
416
417         /* convert scattering to our bitflag label */
418         ustring uscattering = sample_bsdf->scattering();
419
420         if (uscattering == OSL::Labels::DIFFUSE)
421                 label |= LABEL_DIFFUSE;
422         else if (uscattering == OSL::Labels::GLOSSY)
423                 label |= LABEL_GLOSSY;
424         else if (uscattering == OSL::Labels::SINGULAR)
425                 label |= LABEL_SINGULAR;
426         else
427                 label |= LABEL_TRANSPARENT;
428
429         return label;
430 }
431
432 float3 OSLShader::bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, const float3& omega_in, float& pdf)
433 {
434         OSL::BSDFClosure *bsdf = (OSL::BSDFClosure *)sc->prim;
435         OSL::Color3 bsdf_eval;
436
437         if (dot(sd->Ng, omega_in) >= 0.0f)
438                 bsdf_eval = bsdf->eval_reflect(TO_VEC3(sd->I), TO_VEC3(omega_in), pdf);
439         else
440                 bsdf_eval = bsdf->eval_transmit(TO_VEC3(sd->I), TO_VEC3(omega_in), pdf);
441         
442         return TO_FLOAT3(bsdf_eval);
443 }
444
445 /* Emissive Closure */
446
447 float3 OSLShader::emissive_eval(const ShaderData *sd, const ShaderClosure *sc)
448 {
449         OSL::EmissiveClosure *emissive = (OSL::EmissiveClosure *)sc->prim;
450         OSL::Color3 emissive_eval = emissive->eval(TO_VEC3(sd->Ng), TO_VEC3(sd->I));
451
452         return TO_FLOAT3(emissive_eval);
453 }
454
455 /* Volume Closure */
456
457 float3 OSLShader::volume_eval_phase(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
458 {
459         OSL::VolumeClosure *volume = (OSL::VolumeClosure *)sc->prim;
460         OSL::Color3 volume_eval = volume->eval_phase(TO_VEC3(omega_in), TO_VEC3(omega_out));
461         return TO_FLOAT3(volume_eval) * sc->weight;
462 }
463
464 CCL_NAMESPACE_END
465