Cycles: Remove few function arguments needed only for the split kernel
[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, ccl_addr_space PathState *state, ccl_addr_space RNG *rng, int sample, ccl_addr_space Ray *ray)
20 {
21         state->flag = PATH_RAY_CAMERA|PATH_RAY_MIS_SKIP;
22
23         state->rng_offset = PRNG_BASE_NUM;
24         state->sample = sample;
25         state->num_samples = kernel_data.integrator.aa_samples;
26
27         state->bounce = 0;
28         state->diffuse_bounce = 0;
29         state->glossy_bounce = 0;
30         state->transmission_bounce = 0;
31         state->transparent_bounce = 0;
32
33         state->min_ray_pdf = FLT_MAX;
34         state->ray_pdf = 0.0f;
35 #ifdef __LAMP_MIS__
36         state->ray_t = 0.0f;
37 #endif
38
39 #ifdef __VOLUME__
40         state->volume_bounce = 0;
41
42         if(kernel_data.integrator.use_volumes) {
43                 /* initialize volume stack with volume we are inside of */
44                 kernel_volume_stack_init(kg, ray, state->volume_stack);
45                 /* seed RNG for cases where we can't use stratified samples */
46                 state->rng_congruential = lcg_init(*rng + sample*0x51633e2d);
47         }
48         else {
49                 state->volume_stack[0].shader = SHADER_NONE;
50         }
51 #endif
52 }
53
54 ccl_device_inline void path_state_next(KernelGlobals *kg, ccl_addr_space PathState *state, int label)
55 {
56         /* ray through transparent keeps same flags from previous ray and is
57          * not counted as a regular bounce, transparent has separate max */
58         if(label & LABEL_TRANSPARENT) {
59                 state->flag |= PATH_RAY_TRANSPARENT;
60                 state->transparent_bounce++;
61
62                 /* don't increase random number generator offset here, to avoid some
63                  * unwanted patterns, see path_state_rng_1D_for_decision */
64
65                 if(!kernel_data.integrator.transparent_shadows)
66                         state->flag |= PATH_RAY_MIS_SKIP;
67
68                 return;
69         }
70
71         state->bounce++;
72
73 #ifdef __VOLUME__
74         if(label & LABEL_VOLUME_SCATTER) {
75                 /* volume scatter */
76                 state->flag |= PATH_RAY_VOLUME_SCATTER;
77                 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);
78
79                 state->volume_bounce++;
80         }
81         else
82 #endif
83         {
84                 /* surface reflection/transmission */
85                 if(label & LABEL_REFLECT) {
86                         state->flag |= PATH_RAY_REFLECT;
87                         state->flag &= ~(PATH_RAY_TRANSMIT|PATH_RAY_VOLUME_SCATTER|PATH_RAY_CAMERA|PATH_RAY_TRANSPARENT);
88
89                         if(label & LABEL_DIFFUSE)
90                                 state->diffuse_bounce++;
91                         else
92                                 state->glossy_bounce++;
93                 }
94                 else {
95                         kernel_assert(label & LABEL_TRANSMIT);
96
97                         state->flag |= PATH_RAY_TRANSMIT;
98                         state->flag &= ~(PATH_RAY_REFLECT|PATH_RAY_VOLUME_SCATTER|PATH_RAY_CAMERA|PATH_RAY_TRANSPARENT);
99
100                         state->transmission_bounce++;
101                 }
102
103                 /* diffuse/glossy/singular */
104                 if(label & LABEL_DIFFUSE) {
105                         state->flag |= PATH_RAY_DIFFUSE|PATH_RAY_DIFFUSE_ANCESTOR;
106                         state->flag &= ~(PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP);
107                 }
108                 else if(label & LABEL_GLOSSY) {
109                         state->flag |= PATH_RAY_GLOSSY;
110                         state->flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP);
111                 }
112                 else {
113                         kernel_assert(label & LABEL_SINGULAR);
114
115                         state->flag |= PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP;
116                         state->flag &= ~PATH_RAY_DIFFUSE;
117                 }
118         }
119
120         /* random number generator next bounce */
121         state->rng_offset += PRNG_BOUNCE_NUM;
122 }
123
124 ccl_device_inline uint path_state_ray_visibility(KernelGlobals *kg, PathState *state)
125 {
126         uint flag = state->flag & PATH_RAY_ALL_VISIBILITY;
127
128         /* for visibility, diffuse/glossy are for reflection only */
129         if(flag & PATH_RAY_TRANSMIT)
130                 flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY);
131         /* todo: this is not supported as its own ray visibility yet */
132         if(state->flag & PATH_RAY_VOLUME_SCATTER)
133                 flag |= PATH_RAY_DIFFUSE;
134         /* for camera visibility, use render layer flags */
135         if(flag & PATH_RAY_CAMERA)
136                 flag |= kernel_data.integrator.layer_flag;
137
138         return flag;
139 }
140
141 ccl_device_inline float path_state_terminate_probability(KernelGlobals *kg, ccl_addr_space PathState *state, const float3 throughput)
142 {
143         if(state->flag & PATH_RAY_TRANSPARENT) {
144                 /* transparent rays treated separately */
145                 if(state->transparent_bounce >= kernel_data.integrator.transparent_max_bounce)
146                         return 0.0f;
147                 else if(state->transparent_bounce <= kernel_data.integrator.transparent_min_bounce)
148                         return 1.0f;
149         }
150         else {
151                 /* other rays */
152                 if((state->bounce >= kernel_data.integrator.max_bounce) ||
153                    (state->diffuse_bounce >= kernel_data.integrator.max_diffuse_bounce) ||
154                    (state->glossy_bounce >= kernel_data.integrator.max_glossy_bounce) ||
155 #ifdef __VOLUME__
156                    (state->volume_bounce >= kernel_data.integrator.max_volume_bounce) ||
157 #endif
158                    (state->transmission_bounce >= kernel_data.integrator.max_transmission_bounce))
159                 {
160                         return 0.0f;
161                 }
162                 else if(state->bounce <= kernel_data.integrator.min_bounce) {
163                         return 1.0f;
164                 }
165         }
166
167         /* probalistic termination */
168         return average(throughput); /* todo: try using max here */
169 }
170
171 /* TODO(DingTo): Find more meaningful name for this */
172 ccl_device_inline void path_state_modify_bounce(ccl_addr_space PathState *state, bool increase)
173 {
174         /* Modify bounce temporarily for shader eval */
175         if(increase)
176                 state->bounce += 1;
177         else
178                 state->bounce -= 1;
179 }
180
181 CCL_NAMESPACE_END
182