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