Fix Cycles shadow catcher objects influencing each other.
[blender.git] / intern / cycles / kernel / kernel_path_state.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 void path_state_init(KernelGlobals *kg,
20                                        ShaderData *stack_sd,
21                                        ccl_addr_space PathState *state,
22                                        RNG *rng,
23                                        int sample,
24                                        ccl_addr_space Ray *ray)
25 {
26         state->flag = PATH_RAY_CAMERA|PATH_RAY_MIS_SKIP;
27
28         state->rng_offset = PRNG_BASE_NUM;
29         state->sample = sample;
30         state->num_samples = kernel_data.integrator.aa_samples;
31
32         state->bounce = 0;
33         state->diffuse_bounce = 0;
34         state->glossy_bounce = 0;
35         state->transmission_bounce = 0;
36         state->transparent_bounce = 0;
37
38 #ifdef __DENOISING_FEATURES__
39         if(kernel_data.film.pass_denoising_data) {
40                 state->flag |= PATH_RAY_STORE_SHADOW_INFO;
41                 state->denoising_feature_weight = 1.0f;
42         }
43         else {
44                 state->denoising_feature_weight = 0.0f;
45         }
46 #endif  /* __DENOISING_FEATURES__ */
47
48         state->min_ray_pdf = FLT_MAX;
49         state->ray_pdf = 0.0f;
50 #ifdef __LAMP_MIS__
51         state->ray_t = 0.0f;
52 #endif
53
54 #ifdef __VOLUME__
55         state->volume_bounce = 0;
56
57         if(kernel_data.integrator.use_volumes) {
58                 /* Initialize volume stack with volume we are inside of. */
59                 kernel_volume_stack_init(kg, stack_sd, state, ray, state->volume_stack);
60                 /* Seed RNG for cases where we can't use stratified samples .*/
61                 state->rng_congruential = lcg_init(*rng + sample*0x51633e2d);
62         }
63         else {
64                 state->volume_stack[0].shader = SHADER_NONE;
65         }
66 #endif
67 }
68
69 ccl_device_inline void path_state_next(KernelGlobals *kg, ccl_addr_space PathState *state, int label)
70 {
71         /* ray through transparent keeps same flags from previous ray and is
72          * not counted as a regular bounce, transparent has separate max */
73         if(label & LABEL_TRANSPARENT) {
74                 state->flag |= PATH_RAY_TRANSPARENT;
75                 state->transparent_bounce++;
76
77                 /* don't increase random number generator offset here, to avoid some
78                  * unwanted patterns, see path_state_rng_1D_for_decision */
79
80                 if(!kernel_data.integrator.transparent_shadows)
81                         state->flag |= PATH_RAY_MIS_SKIP;
82
83                 return;
84         }
85
86         state->bounce++;
87
88 #ifdef __VOLUME__
89         if(label & LABEL_VOLUME_SCATTER) {
90                 /* volume scatter */
91                 state->flag |= PATH_RAY_VOLUME_SCATTER;
92                 state->flag &= ~(PATH_RAY_REFLECT|PATH_RAY_TRANSMIT|PATH_RAY_CAMERA|PATH_RAY_TRANSPARENT|PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP);
93
94                 state->volume_bounce++;
95         }
96         else
97 #endif
98         {
99                 /* surface reflection/transmission */
100                 if(label & LABEL_REFLECT) {
101                         state->flag |= PATH_RAY_REFLECT;
102                         state->flag &= ~(PATH_RAY_TRANSMIT|PATH_RAY_VOLUME_SCATTER|PATH_RAY_CAMERA|PATH_RAY_TRANSPARENT);
103
104                         if(label & LABEL_DIFFUSE)
105                                 state->diffuse_bounce++;
106                         else
107                                 state->glossy_bounce++;
108                 }
109                 else {
110                         kernel_assert(label & LABEL_TRANSMIT);
111
112                         state->flag |= PATH_RAY_TRANSMIT;
113                         state->flag &= ~(PATH_RAY_REFLECT|PATH_RAY_VOLUME_SCATTER|PATH_RAY_CAMERA|PATH_RAY_TRANSPARENT);
114
115                         state->transmission_bounce++;
116                 }
117
118                 /* diffuse/glossy/singular */
119                 if(label & LABEL_DIFFUSE) {
120                         state->flag |= PATH_RAY_DIFFUSE|PATH_RAY_DIFFUSE_ANCESTOR;
121                         state->flag &= ~(PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP);
122                 }
123                 else if(label & LABEL_GLOSSY) {
124                         state->flag |= PATH_RAY_GLOSSY;
125                         state->flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP);
126                 }
127                 else {
128                         kernel_assert(label & LABEL_SINGULAR);
129
130                         state->flag |= PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP;
131                         state->flag &= ~PATH_RAY_DIFFUSE;
132                 }
133         }
134
135         /* random number generator next bounce */
136         state->rng_offset += PRNG_BOUNCE_NUM;
137
138 #ifdef __DENOISING_FEATURES__
139         if((state->denoising_feature_weight == 0.0f) && !(state->flag & PATH_RAY_SHADOW_CATCHER)) {
140                 state->flag &= ~PATH_RAY_STORE_SHADOW_INFO;
141         }
142 #endif
143 }
144
145 ccl_device_inline uint path_state_ray_visibility(KernelGlobals *kg, PathState *state)
146 {
147         uint flag = state->flag & PATH_RAY_ALL_VISIBILITY;
148
149         /* for visibility, diffuse/glossy are for reflection only */
150         if(flag & PATH_RAY_TRANSMIT)
151                 flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY);
152         /* todo: this is not supported as its own ray visibility yet */
153         if(state->flag & PATH_RAY_VOLUME_SCATTER)
154                 flag |= PATH_RAY_DIFFUSE;
155
156         return flag;
157 }
158
159 ccl_device_inline float path_state_terminate_probability(KernelGlobals *kg, ccl_addr_space PathState *state, const float3 throughput)
160 {
161         if(state->flag & PATH_RAY_TRANSPARENT) {
162                 /* Transparent rays are treated separately with own max bounces. */
163                 if(state->transparent_bounce >= kernel_data.integrator.transparent_max_bounce) {
164                         return 0.0f;
165                 }
166                 /* Do at least one bounce without RR. */
167                 else if(state->transparent_bounce <= 1) {
168                         return 1.0f;
169                 }
170 #ifdef __SHADOW_TRICKS__
171                 /* Exception for shadow catcher not working correctly with RR. */
172                 else if ((state->flag & PATH_RAY_SHADOW_CATCHER) && (state->transparent_bounce <= 8)) {
173                         return 1.0f;
174                 }
175 #endif
176         }
177         else {
178                 /* Test max bounces for various ray types. */
179                 if((state->bounce >= kernel_data.integrator.max_bounce) ||
180                    (state->diffuse_bounce >= kernel_data.integrator.max_diffuse_bounce) ||
181                    (state->glossy_bounce >= kernel_data.integrator.max_glossy_bounce) ||
182 #ifdef __VOLUME__
183                    (state->volume_bounce >= kernel_data.integrator.max_volume_bounce) ||
184 #endif
185                    (state->transmission_bounce >= kernel_data.integrator.max_transmission_bounce))
186                 {
187                         return 0.0f;
188                 }
189                 /* Do at least one bounce without RR. */
190                 else if(state->bounce <= 1) {
191                         return 1.0f;
192                 }
193 #ifdef __SHADOW_TRICKS__
194                 /* Exception for shadow catcher not working correctly with RR. */
195                 else if ((state->flag & PATH_RAY_SHADOW_CATCHER) && (state->bounce <= 3)) {
196                         return 1.0f;
197                 }
198 #endif
199         }
200
201         /* Probalistic termination: use sqrt() to roughly match typical view
202          * transform and do path termination a bit later on average. */
203         return sqrtf(max3(fabs(throughput)));
204 }
205
206 /* TODO(DingTo): Find more meaningful name for this */
207 ccl_device_inline void path_state_modify_bounce(ccl_addr_space PathState *state, bool increase)
208 {
209         /* Modify bounce temporarily for shader eval */
210         if(increase)
211                 state->bounce += 1;
212         else
213                 state->bounce -= 1;
214 }
215
216 CCL_NAMESPACE_END
217