Merge branch 'master' into blender2.8
[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                                        uint rng_hash,
23                                        int sample,
24                                        ccl_addr_space Ray *ray)
25 {
26         state->flag = PATH_RAY_CAMERA|PATH_RAY_MIS_SKIP|PATH_RAY_TRANSPARENT_BACKGROUND;
27
28         state->rng_hash = rng_hash;
29         state->rng_offset = PRNG_BASE_NUM;
30         state->sample = sample;
31         state->num_samples = kernel_data.integrator.aa_samples;
32         state->branch_factor = 1.0f;
33
34         state->bounce = 0;
35         state->diffuse_bounce = 0;
36         state->glossy_bounce = 0;
37         state->transmission_bounce = 0;
38         state->transparent_bounce = 0;
39
40 #ifdef __DENOISING_FEATURES__
41         if(kernel_data.film.pass_denoising_data) {
42                 state->flag |= PATH_RAY_STORE_SHADOW_INFO;
43                 state->denoising_feature_weight = 1.0f;
44         }
45         else {
46                 state->denoising_feature_weight = 0.0f;
47         }
48 #endif  /* __DENOISING_FEATURES__ */
49
50         state->min_ray_pdf = FLT_MAX;
51         state->ray_pdf = 0.0f;
52 #ifdef __LAMP_MIS__
53         state->ray_t = 0.0f;
54 #endif
55
56 #ifdef __VOLUME__
57         state->volume_bounce = 0;
58         state->volume_bounds_bounce = 0;
59
60         if(kernel_data.integrator.use_volumes) {
61                 /* Initialize volume stack with volume we are inside of. */
62                 kernel_volume_stack_init(kg, stack_sd, state, ray, state->volume_stack);
63         }
64         else {
65                 state->volume_stack[0].shader = SHADER_NONE;
66         }
67 #endif
68 }
69
70 ccl_device_inline void path_state_next(KernelGlobals *kg, ccl_addr_space PathState *state, int label)
71 {
72         /* ray through transparent keeps same flags from previous ray and is
73          * not counted as a regular bounce, transparent has separate max */
74         if(label & LABEL_TRANSPARENT) {
75                 state->flag |= PATH_RAY_TRANSPARENT;
76                 state->transparent_bounce++;
77                 if(state->transparent_bounce >= kernel_data.integrator.transparent_max_bounce) {
78                         state->flag |= PATH_RAY_TERMINATE_IMMEDIATE;
79                 }
80
81                 if(!kernel_data.integrator.transparent_shadows)
82                         state->flag |= PATH_RAY_MIS_SKIP;
83
84                 /* random number generator next bounce */
85                 state->rng_offset += PRNG_BOUNCE_NUM;
86
87                 return;
88         }
89
90         state->bounce++;
91         if(state->bounce >= kernel_data.integrator.max_bounce) {
92                 state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
93         }
94
95         state->flag &= ~(PATH_RAY_ALL_VISIBILITY|PATH_RAY_MIS_SKIP);
96
97 #ifdef __VOLUME__
98         if(label & LABEL_VOLUME_SCATTER) {
99                 /* volume scatter */
100                 state->flag |= PATH_RAY_VOLUME_SCATTER;
101                 state->flag &= ~PATH_RAY_TRANSPARENT_BACKGROUND;
102
103                 state->volume_bounce++;
104                 if(state->volume_bounce >= kernel_data.integrator.max_volume_bounce) {
105                         state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
106                 }
107         }
108         else
109 #endif
110         {
111                 /* surface reflection/transmission */
112                 if(label & LABEL_REFLECT) {
113                         state->flag |= PATH_RAY_REFLECT;
114                         state->flag &= ~PATH_RAY_TRANSPARENT_BACKGROUND;
115
116                         if(label & LABEL_DIFFUSE) {
117                                 state->diffuse_bounce++;
118                                 if(state->diffuse_bounce >= kernel_data.integrator.max_diffuse_bounce) {
119                                         state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
120                                 }
121                         }
122                         else {
123                                 state->glossy_bounce++;
124                                 if(state->glossy_bounce >= kernel_data.integrator.max_glossy_bounce) {
125                                         state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
126                                 }
127                         }
128                 }
129                 else {
130                         kernel_assert(label & LABEL_TRANSMIT);
131
132                         state->flag |= PATH_RAY_TRANSMIT;
133
134                         if(!(label & LABEL_TRANSMIT_TRANSPARENT)) {
135                                 state->flag &= ~PATH_RAY_TRANSPARENT_BACKGROUND;
136                         }
137
138                         state->transmission_bounce++;
139                         if(state->transmission_bounce >= kernel_data.integrator.max_transmission_bounce) {
140                                 state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
141                         }
142                 }
143
144                 /* diffuse/glossy/singular */
145                 if(label & LABEL_DIFFUSE) {
146                         state->flag |= PATH_RAY_DIFFUSE|PATH_RAY_DIFFUSE_ANCESTOR;
147                 }
148                 else if(label & LABEL_GLOSSY) {
149                         state->flag |= PATH_RAY_GLOSSY;
150                 }
151                 else {
152                         kernel_assert(label & LABEL_SINGULAR);
153                         state->flag |= PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP;
154                 }
155         }
156
157         /* random number generator next bounce */
158         state->rng_offset += PRNG_BOUNCE_NUM;
159
160 #ifdef __DENOISING_FEATURES__
161         if((state->denoising_feature_weight == 0.0f) && !(state->flag & PATH_RAY_SHADOW_CATCHER)) {
162                 state->flag &= ~PATH_RAY_STORE_SHADOW_INFO;
163         }
164 #endif
165 }
166
167 #ifdef __VOLUME__
168 ccl_device_inline bool path_state_volume_next(KernelGlobals *kg, ccl_addr_space PathState *state)
169 {
170         /* For volume bounding meshes we pass through without counting transparent
171          * bounces, only sanity check in case self intersection gets us stuck. */
172         state->volume_bounds_bounce++;
173         if(state->volume_bounds_bounce > VOLUME_BOUNDS_MAX) {
174                 return false;
175         }
176
177         /* Random number generator next bounce. */
178         if(state->volume_bounds_bounce > 1) {
179                 state->rng_offset += PRNG_BOUNCE_NUM;
180         }
181
182         return true;
183 }
184 #endif
185
186 ccl_device_inline uint path_state_ray_visibility(KernelGlobals *kg, ccl_addr_space PathState *state)
187 {
188         uint flag = state->flag & PATH_RAY_ALL_VISIBILITY;
189
190         /* for visibility, diffuse/glossy are for reflection only */
191         if(flag & PATH_RAY_TRANSMIT)
192                 flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY);
193         /* todo: this is not supported as its own ray visibility yet */
194         if(state->flag & PATH_RAY_VOLUME_SCATTER)
195                 flag |= PATH_RAY_DIFFUSE;
196
197         return flag;
198 }
199
200 ccl_device_inline float path_state_continuation_probability(KernelGlobals *kg,
201                                                             ccl_addr_space PathState *state,
202                                                             const float3 throughput)
203 {
204         if(state->flag & PATH_RAY_TERMINATE_IMMEDIATE) {
205                 /* Ray is to be terminated immediately. */
206                 return 0.0f;
207         }
208         else if(state->flag & PATH_RAY_TRANSPARENT) {
209                 /* Do at least one bounce without RR. */
210                 if(state->transparent_bounce <= 1) {
211                         return 1.0f;
212                 }
213 #ifdef __SHADOW_TRICKS__
214                 /* Exception for shadow catcher not working correctly with RR. */
215                 else if((state->flag & PATH_RAY_SHADOW_CATCHER) && (state->transparent_bounce <= 8)) {
216                         return 1.0f;
217                 }
218 #endif
219         }
220         else {
221                 /* Do at least one bounce without RR. */
222                 if(state->bounce <= 1) {
223                         return 1.0f;
224                 }
225 #ifdef __SHADOW_TRICKS__
226                 /* Exception for shadow catcher not working correctly with RR. */
227                 else if((state->flag & PATH_RAY_SHADOW_CATCHER) && (state->bounce <= 3)) {
228                         return 1.0f;
229                 }
230 #endif
231         }
232
233         /* Probabilistic termination: use sqrt() to roughly match typical view
234          * transform and do path termination a bit later on average. */
235         return min(sqrtf(max3(fabs(throughput)) * state->branch_factor), 1.0f);
236 }
237
238 /* TODO(DingTo): Find more meaningful name for this */
239 ccl_device_inline void path_state_modify_bounce(ccl_addr_space PathState *state, bool increase)
240 {
241         /* Modify bounce temporarily for shader eval */
242         if(increase)
243                 state->bounce += 1;
244         else
245                 state->bounce -= 1;
246 }
247
248 ccl_device_inline bool path_state_ao_bounce(KernelGlobals *kg, ccl_addr_space PathState *state)
249 {
250     if(state->bounce <= kernel_data.integrator.ao_bounces) {
251         return false;
252     }
253
254     int bounce = state->bounce - state->transmission_bounce - (state->glossy_bounce > 0);
255     return (bounce > kernel_data.integrator.ao_bounces);
256 }
257
258 ccl_device_inline void path_state_branch(ccl_addr_space PathState *state,
259                                          int branch,
260                                          int num_branches)
261 {
262         if(num_branches > 1) {
263                 /* Path is splitting into a branch, adjust so that each branch
264                  * still gets a unique sample from the same sequence. */
265                 state->sample = state->sample*num_branches + branch;
266                 state->num_samples = state->num_samples*num_branches;
267                 state->branch_factor *= num_branches;
268         }
269 }
270
271 CCL_NAMESPACE_END