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