2 * Copyright 2011, Blender Foundation.
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.
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.
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.
20 * ShaderData, used in four steps:
22 * Setup from incoming ray, sampled position and background.
23 * Execute for surface, volume or displacement.
24 * Evaluate one or more closures.
32 #include "osl_shader.h"
37 #include "svm/emissive.h"
38 #include "svm/volume.h"
39 #include "svm/svm_bsdf.h"
46 /* ShaderData setup from incoming ray */
48 __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
49 const Intersection *isect, const Ray *ray)
51 /* fetch triangle data */
52 int prim = kernel_tex_fetch(__prim_index, isect->prim);
53 float4 Ns = kernel_tex_fetch(__tri_normal, prim);
54 float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
55 int shader = __float_as_int(Ns.w);
58 sd->P = bvh_triangle_refine(kg, isect, ray);
66 sd->object = isect->object;
75 if(sd->shader & SHADER_SMOOTH_NORMAL)
76 sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
78 sd->flag = kernel_tex_fetch(__shader_flag, sd->shader & SHADER_MASK);
82 triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
86 if(sd->object != ~0) {
87 /* instance transform */
88 object_normal_transform(kg, sd->object, &sd->N);
89 object_normal_transform(kg, sd->object, &sd->Ng);
91 object_dir_transform(kg, sd->object, &sd->dPdu);
92 object_dir_transform(kg, sd->object, &sd->dPdv);
96 /* non-instanced object index */
97 sd->object = kernel_tex_fetch(__prim_object, isect->prim);
101 /* backfacing test */
102 bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
105 sd->flag |= SD_BACKFACING;
109 sd->dPdu = -sd->dPdu;
110 sd->dPdv = -sd->dPdv;
114 #ifdef __RAY_DIFFERENTIALS__
116 differential_transfer(&sd->dP, ray->dP, ray->D, ray->dD, sd->Ng, isect->t);
117 differential_incoming(&sd->dI, ray->dD);
118 differential_dudv(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng);
122 /* ShaderData setup from position sampled on mesh */
124 __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
125 const float3 P, const float3 Ng, const float3 I,
126 int shader, int object, int prim, float u, float v)
136 #ifdef __INSTANCING__
145 /* detect instancing, for non-instanced the object index is -object-1 */
146 #ifdef __INSTANCING__
147 bool instanced = false;
154 sd->object = -sd->object-1;
155 #ifdef __INSTANCING__
160 if(sd->shader & SHADER_SMOOTH_NORMAL) {
161 sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
163 #ifdef __INSTANCING__
165 object_normal_transform(kg, sd->object, &sd->N);
169 sd->flag = kernel_tex_fetch(__shader_flag, sd->shader & SHADER_MASK);
174 sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
175 sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
178 triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
180 #ifdef __INSTANCING__
182 object_dir_transform(kg, sd->object, &sd->dPdu);
183 object_dir_transform(kg, sd->object, &sd->dPdv);
189 /* backfacing test */
191 bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
194 sd->flag |= SD_BACKFACING;
198 sd->dPdu = -sd->dPdu;
199 sd->dPdv = -sd->dPdv;
204 #ifdef __RAY_DIFFERENTIALS__
205 /* no ray differentials here yet */
206 sd->dP.dx = make_float3(0.0f, 0.0f, 0.0f);
207 sd->dP.dy = make_float3(0.0f, 0.0f, 0.0f);
208 sd->dI.dx = make_float3(0.0f, 0.0f, 0.0f);
209 sd->dI.dy = make_float3(0.0f, 0.0f, 0.0f);
217 /* ShaderData setup for displacement */
219 __device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
220 int object, int prim, float u, float v)
222 float3 P, Ng, I = make_float3(0.0f, 0.0f, 0.0f);
225 P = triangle_point_MT(kg, prim, u, v);
226 Ng = triangle_normal_MT(kg, prim, &shader);
228 /* force smooth shading for displacement */
229 sd->shader |= SHADER_SMOOTH_NORMAL;
231 /* watch out: no instance transform currently */
233 shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v);
236 /* ShaderData setup from ray into background */
238 __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray)
245 sd->shader = kernel_data.background.shader;
246 sd->flag = kernel_tex_fetch(__shader_flag, sd->shader & SHADER_MASK);
248 #ifdef __INSTANCING__
259 sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
260 sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
263 #ifdef __RAY_DIFFERENTIALS__
266 differential_incoming(&sd->dI, sd->dP);
276 #ifdef __MULTI_CLOSURE__
278 __device_inline float3 _shader_bsdf_multi_eval(const ShaderData *sd, const float3 omega_in, float *pdf,
279 int skip_bsdf, float3 sum_eval, float sum_pdf, float sum_sample_weight)
281 for(int i = 0; i< sd->num_closure; i++) {
285 const ShaderClosure *sc = &sd->closure[i];
287 if(CLOSURE_IS_BSDF(sc->type)) {
288 float bsdf_pdf = 0.0f;
290 float3 eval = OSLShader::bsdf_eval(sd, sc, omega_in, bsdf_pdf);
292 float3 eval = svm_bsdf_eval(sd, sc, omega_in, &bsdf_pdf);
295 if(bsdf_pdf != 0.0f) {
296 sum_eval += eval*sc->weight;
297 sum_pdf += bsdf_pdf*sc->sample_weight;
300 sum_sample_weight += sc->sample_weight;
304 *pdf = sum_pdf/sum_sample_weight;
310 __device float3 shader_bsdf_eval(KernelGlobals *kg, const ShaderData *sd,
311 const float3 omega_in, float *pdf)
313 #ifdef __MULTI_CLOSURE__
314 return _shader_bsdf_multi_eval(sd, omega_in, pdf, -1, make_float3(0.0f, 0.0f, 0.0f), 0.0f, 0.0f);
316 const ShaderClosure *sc = &sd->closure;
318 return svm_bsdf_eval(sd, sc, omega_in, pdf)*sc->weight;
322 __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
323 float randu, float randv, float3 *eval,
324 float3 *omega_in, differential3 *domega_in, float *pdf)
326 #ifdef __MULTI_CLOSURE__
329 if(sd->num_closure > 1) {
330 /* pick a BSDF closure based on sample weights */
333 for(sampled = 0; sampled < sd->num_closure; sampled++) {
334 const ShaderClosure *sc = &sd->closure[sampled];
336 if(CLOSURE_IS_BSDF(sc->type))
337 sum += sc->sample_weight;
340 float r = sd->randb_closure*sum;
343 for(sampled = 0; sampled < sd->num_closure; sampled++) {
344 const ShaderClosure *sc = &sd->closure[sampled];
346 if(CLOSURE_IS_BSDF(sc->type)) {
347 sum += sd->closure[sampled].sample_weight;
354 if(sampled == sd->num_closure) {
360 const ShaderClosure *sc = &sd->closure[sampled];
365 label = OSLShader::bsdf_sample(sd, sc, randu, randv, *eval, *omega_in, *domega_in, *pdf);
367 label = svm_bsdf_sample(sd, sc, randu, randv, eval, omega_in, domega_in, pdf);
372 if(sd->num_closure > 1 && *pdf != 0.0f) {
373 float sweight = sc->sample_weight;
374 *eval = _shader_bsdf_multi_eval(sd, *omega_in, pdf, sampled, *eval, *pdf*sweight, sweight);
379 /* sample the single closure that we picked */
381 int label = svm_bsdf_sample(sd, &sd->closure, randu, randv, eval, omega_in, domega_in, pdf);
382 *eval *= sd->closure.weight;
387 __device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughness)
390 #ifdef __MULTI_CLOSURE__
391 for(int i = 0; i< sd->num_closure; i++) {
392 ShaderClosure *sc = &sd->closure[i];
394 if(CLOSURE_IS_BSDF(sc->type))
395 svm_bsdf_blur(sc, roughness);
398 svm_bsdf_blur(&sd->closure, roughness);
403 __device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd)
405 #ifdef __MULTI_CLOSURE__
406 float3 eval = make_float3(0.0f, 0.0f, 0.0f);
408 for(int i = 0; i< sd->num_closure; i++) {
409 ShaderClosure *sc = &sd->closure[i];
411 if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) // todo: make this work for osl
417 if(sd->closure.type == CLOSURE_BSDF_TRANSPARENT_ID)
418 return sd->closure.weight;
420 return make_float3(0.0f, 0.0f, 0.0f);
427 __device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
430 #ifdef __MULTI_CLOSURE__
431 eval = make_float3(0.0f, 0.0f, 0.0f);
433 for(int i = 0; i < sd->num_closure; i++) {
434 ShaderClosure *sc = &sd->closure[i];
436 if(CLOSURE_IS_EMISSION(sc->type)) {
438 eval += OSLShader::emissive_eval(sd)*sc->weight;
440 eval += svm_emissive_eval(sd, sc)*sc->weight;
445 eval = svm_emissive_eval(sd, &sd->closure)*sd->closure.weight;
453 __device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
455 #ifdef __MULTI_CLOSURE__
456 float3 weight = make_float3(0.0f, 0.0f, 0.0f);
458 for(int i = 0; i < sd->num_closure; i++) {
459 ShaderClosure *sc = &sd->closure[i];
461 if(CLOSURE_IS_HOLDOUT(sc->type))
462 weight += sc->weight;
467 if(sd->closure.type == CLOSURE_HOLDOUT_ID)
468 return make_float3(1.0f, 1.0f, 1.0f);
470 return make_float3(0.0f, 0.0f, 0.0f);
474 /* Surface Evaluation */
476 __device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
477 float randb, int path_flag)
480 OSLShader::eval_surface(kg, sd, randb, path_flag);
484 svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, randb, path_flag);
486 bsdf_diffuse_setup(sd, &sd->closure);
487 sd->closure.weight = make_float3(0.8f, 0.8f, 0.8f);
493 /* Background Evaluation */
495 __device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag)
498 return OSLShader::eval_background(kg, sd, path_flag);
502 svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, 0.0f, path_flag);
504 #ifdef __MULTI_CLOSURE__
505 float3 eval = make_float3(0.0f, 0.0f, 0.0f);
507 for(int i = 0; i< sd->num_closure; i++) {
508 const ShaderClosure *sc = &sd->closure[i];
510 if(CLOSURE_IS_BACKGROUND(sc->type))
516 if(sd->closure.type == CLOSURE_BACKGROUND_ID)
517 return sd->closure.weight;
519 return make_float3(0.0f, 0.0f, 0.0f);
523 return make_float3(0.8f, 0.8f, 0.8f);
531 __device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd,
532 float3 omega_in, float3 omega_out)
534 #ifdef __MULTI_CLOSURE__
535 float3 eval = make_float3(0.0f, 0.0f, 0.0f);
537 for(int i = 0; i< sd->num_closure; i++) {
538 const ShaderClosure *sc = &sd->closure[i];
540 if(CLOSURE_IS_VOLUME(sc->type)) {
542 eval += OSLShader::volume_eval_phase(sd, omega_in, omega_out);
544 eval += volume_eval_phase(sd, sc, omega_in, omega_out);
551 return volume_eval_phase(sd, &sd->closure, omega_in, omega_out);
555 /* Volume Evaluation */
557 __device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
558 float randb, int path_flag)
562 OSLShader::eval_volume(kg, sd, randb, path_flag);
564 svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, randb, path_flag);
569 /* Displacement Evaluation */
571 __device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd)
573 /* this will modify sd->P */
576 OSLShader::eval_displacement(kg, sd);
578 svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0.0f, 0);
583 /* Transparent Shadows */
585 #ifdef __TRANSPARENT_SHADOWS__
586 __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
588 int prim = kernel_tex_fetch(__prim_index, isect->prim);
589 float4 Ns = kernel_tex_fetch(__tri_normal, prim);
590 int shader = __float_as_int(Ns.w);
591 int flag = kernel_tex_fetch(__shader_flag, shader & SHADER_MASK);
593 return (flag & SD_HAS_SURFACE_TRANSPARENT) != 0;
597 /* Free ShaderData */
599 __device void shader_release(KernelGlobals *kg, ShaderData *sd)
602 OSLShader::release(kg, sd);