Cycles: remove min bounces, modify RR to terminate less.
[blender-staging.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 #ifdef __SHADOW_TRICKS__
69         state->catcher_object = OBJECT_NONE;
70 #endif
71 }
72
73 ccl_device_inline void path_state_next(KernelGlobals *kg, ccl_addr_space PathState *state, int label)
74 {
75         /* ray through transparent keeps same flags from previous ray and is
76          * not counted as a regular bounce, transparent has separate max */
77         if(label & LABEL_TRANSPARENT) {
78                 state->flag |= PATH_RAY_TRANSPARENT;
79                 state->transparent_bounce++;
80
81                 /* don't increase random number generator offset here, to avoid some
82                  * unwanted patterns, see path_state_rng_1D_for_decision */
83
84                 if(!kernel_data.integrator.transparent_shadows)
85                         state->flag |= PATH_RAY_MIS_SKIP;
86
87                 return;
88         }
89
90         state->bounce++;
91
92 #ifdef __VOLUME__
93         if(label & LABEL_VOLUME_SCATTER) {
94                 /* volume scatter */
95                 state->flag |= PATH_RAY_VOLUME_SCATTER;
96                 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);
97
98                 state->volume_bounce++;
99         }
100         else
101 #endif
102         {
103                 /* surface reflection/transmission */
104                 if(label & LABEL_REFLECT) {
105                         state->flag |= PATH_RAY_REFLECT;
106                         state->flag &= ~(PATH_RAY_TRANSMIT|PATH_RAY_VOLUME_SCATTER|PATH_RAY_CAMERA|PATH_RAY_TRANSPARENT);
107
108                         if(label & LABEL_DIFFUSE)
109                                 state->diffuse_bounce++;
110                         else
111                                 state->glossy_bounce++;
112                 }
113                 else {
114                         kernel_assert(label & LABEL_TRANSMIT);
115
116                         state->flag |= PATH_RAY_TRANSMIT;
117                         state->flag &= ~(PATH_RAY_REFLECT|PATH_RAY_VOLUME_SCATTER|PATH_RAY_CAMERA|PATH_RAY_TRANSPARENT);
118
119                         state->transmission_bounce++;
120                 }
121
122                 /* diffuse/glossy/singular */
123                 if(label & LABEL_DIFFUSE) {
124                         state->flag |= PATH_RAY_DIFFUSE|PATH_RAY_DIFFUSE_ANCESTOR;
125                         state->flag &= ~(PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP);
126                 }
127                 else if(label & LABEL_GLOSSY) {
128                         state->flag |= PATH_RAY_GLOSSY;
129                         state->flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP);
130                 }
131                 else {
132                         kernel_assert(label & LABEL_SINGULAR);
133
134                         state->flag |= PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP;
135                         state->flag &= ~PATH_RAY_DIFFUSE;
136                 }
137         }
138
139         /* random number generator next bounce */
140         state->rng_offset += PRNG_BOUNCE_NUM;
141
142 #ifdef __DENOISING_FEATURES__
143         if((state->denoising_feature_weight == 0.0f) && !(state->flag & PATH_RAY_SHADOW_CATCHER)) {
144                 state->flag &= ~PATH_RAY_STORE_SHADOW_INFO;
145         }
146 #endif
147 }
148
149 ccl_device_inline uint path_state_ray_visibility(KernelGlobals *kg, PathState *state)
150 {
151         uint flag = state->flag & PATH_RAY_ALL_VISIBILITY;
152
153         /* for visibility, diffuse/glossy are for reflection only */
154         if(flag & PATH_RAY_TRANSMIT)
155                 flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY);
156         /* todo: this is not supported as its own ray visibility yet */
157         if(state->flag & PATH_RAY_VOLUME_SCATTER)
158                 flag |= PATH_RAY_DIFFUSE;
159
160         return flag;
161 }
162
163 ccl_device_inline float path_state_terminate_probability(KernelGlobals *kg, ccl_addr_space PathState *state, const float3 throughput)
164 {
165         if(state->flag & PATH_RAY_TRANSPARENT) {
166                 /* Transparent rays are treated separately with own max bounces. */
167                 if(state->transparent_bounce >= kernel_data.integrator.transparent_max_bounce) {
168                         return 0.0f;
169                 }
170                 /* Do at least one bounce without RR. */
171                 else if(state->transparent_bounce <= 1) {
172                         return 1.0f;
173                 }
174 #ifdef __SHADOW_TRICKS__
175                 /* Exception for shadow catcher not working correctly with RR. */
176                 else if ((state->flag & PATH_RAY_SHADOW_CATCHER) && (state->transparent_bounce <= 8)) {
177                         return 1.0f;
178                 }
179 #endif
180         }
181         else {
182                 /* Test max bounces for various ray types. */
183                 if((state->bounce >= kernel_data.integrator.max_bounce) ||
184                    (state->diffuse_bounce >= kernel_data.integrator.max_diffuse_bounce) ||
185                    (state->glossy_bounce >= kernel_data.integrator.max_glossy_bounce) ||
186 #ifdef __VOLUME__
187                    (state->volume_bounce >= kernel_data.integrator.max_volume_bounce) ||
188 #endif
189                    (state->transmission_bounce >= kernel_data.integrator.max_transmission_bounce))
190                 {
191                         return 0.0f;
192                 }
193                 /* Do at least one bounce without RR. */
194                 else if(state->bounce <= 1) {
195                         return 1.0f;
196                 }
197 #ifdef __SHADOW_TRICKS__
198                 /* Exception for shadow catcher not working correctly with RR. */
199                 else if ((state->flag & PATH_RAY_SHADOW_CATCHER) && (state->bounce <= 3)) {
200                         return 1.0f;
201                 }
202 #endif
203         }
204
205         /* Probalistic termination: use sqrt() to roughly match typical view
206          * transform and do path termination a bit later on average. */
207         return sqrtf(max3(fabs(throughput)));
208 }
209
210 /* TODO(DingTo): Find more meaningful name for this */
211 ccl_device_inline void path_state_modify_bounce(ccl_addr_space PathState *state, bool increase)
212 {
213         /* Modify bounce temporarily for shader eval */
214         if(increase)
215                 state->bounce += 1;
216         else
217                 state->bounce -= 1;
218 }
219
220 CCL_NAMESPACE_END
221