4c1548af6e10a3729f76260d4fc0484e51bad461
[blender.git] / intern / cycles / kernel / kernel_shadow.h
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16
17 CCL_NAMESPACE_BEGIN
18
19 ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ray, float3 *shadow)
20 {
21         *shadow = make_float3(1.0f, 1.0f, 1.0f);
22
23         if(ray->t == 0.0f)
24                 return false;
25         
26         Intersection isect;
27 #ifdef __HAIR__
28         bool result = scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, &isect, NULL, 0.0f, 0.0f);
29 #else
30         bool result = scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, &isect);
31 #endif
32
33 #ifdef __TRANSPARENT_SHADOWS__
34         if(result && kernel_data.integrator.transparent_shadows) {
35                 /* transparent shadows work in such a way to try to minimize overhead
36                  * in cases where we don't need them. after a regular shadow ray is
37                  * cast we check if the hit primitive was potentially transparent, and
38                  * only in that case start marching. this gives on extra ray cast for
39                  * the cases were we do want transparency.
40                  *
41                  * also note that for this to work correct, multi close sampling must
42                  * be used, since we don't pass a random number to shader_eval_surface */
43                 if(shader_transparent_shadow(kg, &isect)) {
44                         float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
45                         float3 Pend = ray->P + ray->D*ray->t;
46                         int bounce = state->transparent_bounce;
47
48                         for(;;) {
49                                 if(bounce >= kernel_data.integrator.transparent_max_bounce) {
50                                         return true;
51                                 }
52                                 else if(bounce >= kernel_data.integrator.transparent_min_bounce) {
53                                         /* todo: get random number somewhere for probabilistic terminate */
54 #if 0
55                                         float probability = average(throughput);
56                                         float terminate = 0.0f;
57
58                                         if(terminate >= probability)
59                                                 return true;
60
61                                         throughput /= probability;
62 #endif
63                                 }
64
65 #ifdef __HAIR__
66                                 if(!scene_intersect(kg, ray, PATH_RAY_SHADOW_TRANSPARENT, &isect, NULL, 0.0f, 0.0f)) {
67 #else
68                                 if(!scene_intersect(kg, ray, PATH_RAY_SHADOW_TRANSPARENT, &isect)) {
69 #endif
70                                         *shadow *= throughput;
71                                         return false;
72                                 }
73
74                                 if(!shader_transparent_shadow(kg, &isect))
75                                         return true;
76
77                                 ShaderData sd;
78                                 shader_setup_from_ray(kg, &sd, &isect, ray, state->bounce+1);
79                                 shader_eval_surface(kg, &sd, 0.0f, PATH_RAY_SHADOW, SHADER_CONTEXT_SHADOW);
80
81                                 throughput *= shader_bsdf_transparency(kg, &sd);
82
83                                 ray->P = ray_offset(sd.P, -sd.Ng);
84                                 if(ray->t != FLT_MAX)
85                                         ray->D = normalize_len(Pend - ray->P, &ray->t);
86
87                                 bounce++;
88                         }
89                 }
90         }
91 #endif
92
93         return result;
94 }
95
96 CCL_NAMESPACE_END
97