Cycles: better path termination for transparency.
[blender.git] / intern / cycles / kernel / closure / bsdf_transparent.h
index 81bc7690b507ec714c5a98ae1177955eb6db3575..79ee9dc4537c2ea996ad77dcf0b8df26b57aff3b 100644 (file)
 
 CCL_NAMESPACE_BEGIN
 
-__device int bsdf_transparent_setup(ShaderClosure *sc)
+ccl_device void bsdf_transparent_setup(ShaderData *sd, const float3 weight, int path_flag)
 {
-       sc->type = CLOSURE_BSDF_TRANSPARENT_ID;
-       return SD_BSDF;
-}
+       if(sd->flag & SD_TRANSPARENT) {
+               sd->closure_transparent_extinction += weight;
 
-__device void bsdf_transparent_blur(ShaderClosure *sc, float roughness)
-{
+               for(int i = 0; i < sd->num_closure; i++) {
+                       ShaderClosure *sc = &sd->closure[i];
+
+                       if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) {
+                               sc->weight += weight;
+                               sc->sample_weight += fabsf(average(weight));
+                               break;
+                       }
+               }
+       }
+       else {
+               sd->flag |= SD_BSDF|SD_TRANSPARENT;
+               sd->closure_transparent_extinction = weight;
+
+               if(path_flag & PATH_RAY_TERMINATE) {
+                       /* In this case the number of closures is set to zero to disable
+                        * all others, but we still want to get transparency so increase
+                        * the number just for this. */
+                       sd->num_closure_left = 1;
+               }
+
+               ShaderClosure *bsdf = bsdf_alloc(sd, sizeof(ShaderClosure), weight);
+
+               if(bsdf) {
+                       bsdf->N = sd->N;
+                       bsdf->type = CLOSURE_BSDF_TRANSPARENT_ID;
+               }
+       }
 }
 
-__device float3 bsdf_transparent_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_transparent_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
 {
        return make_float3(0.0f, 0.0f, 0.0f);
 }
 
-__device float3 bsdf_transparent_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+ccl_device float3 bsdf_transparent_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
 {
        return make_float3(0.0f, 0.0f, 0.0f);
 }
 
-__device int bsdf_transparent_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+ccl_device int bsdf_transparent_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
 {
        // only one direction is possible
        *omega_in = -I;