2 * Copyright 2011-2013 Blender Foundation
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
19 typedef struct PathState {
25 int transmission_bounce;
26 int transparent_bounce;
29 ccl_device_inline void path_state_init(PathState *state)
31 state->flag = PATH_RAY_CAMERA|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP;
33 state->diffuse_bounce = 0;
34 state->glossy_bounce = 0;
35 state->transmission_bounce = 0;
36 state->transparent_bounce = 0;
39 ccl_device_inline void path_state_next(KernelGlobals *kg, PathState *state, int label)
41 /* ray through transparent keeps same flags from previous ray and is
42 * not counted as a regular bounce, transparent has separate max */
43 if(label & LABEL_TRANSPARENT) {
44 state->flag |= PATH_RAY_TRANSPARENT;
45 state->transparent_bounce++;
47 if(!kernel_data.integrator.transparent_shadows)
48 state->flag |= PATH_RAY_MIS_SKIP;
55 /* reflection/transmission */
56 if(label & LABEL_REFLECT) {
57 state->flag |= PATH_RAY_REFLECT;
58 state->flag &= ~(PATH_RAY_TRANSMIT|PATH_RAY_CAMERA|PATH_RAY_TRANSPARENT);
60 if(label & LABEL_DIFFUSE)
61 state->diffuse_bounce++;
63 state->glossy_bounce++;
66 kernel_assert(label & LABEL_TRANSMIT);
68 state->flag |= PATH_RAY_TRANSMIT;
69 state->flag &= ~(PATH_RAY_REFLECT|PATH_RAY_CAMERA|PATH_RAY_TRANSPARENT);
71 state->transmission_bounce++;
74 /* diffuse/glossy/singular */
75 if(label & LABEL_DIFFUSE) {
76 state->flag |= PATH_RAY_DIFFUSE|PATH_RAY_DIFFUSE_ANCESTOR;
77 state->flag &= ~(PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP);
79 else if(label & LABEL_GLOSSY) {
80 state->flag |= PATH_RAY_GLOSSY|PATH_RAY_GLOSSY_ANCESTOR;
81 state->flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP);
84 kernel_assert(label & LABEL_SINGULAR);
86 state->flag |= PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP;
87 state->flag &= ~PATH_RAY_DIFFUSE;
91 ccl_device_inline uint path_state_ray_visibility(KernelGlobals *kg, PathState *state)
93 uint flag = state->flag & PATH_RAY_ALL_VISIBILITY;
95 /* for visibility, diffuse/glossy are for reflection only */
96 if(flag & PATH_RAY_TRANSMIT)
97 flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY);
98 /* for camera visibility, use render layer flags */
99 if(flag & PATH_RAY_CAMERA)
100 flag |= kernel_data.integrator.layer_flag;
105 ccl_device_inline float path_state_terminate_probability(KernelGlobals *kg, PathState *state, const float3 throughput)
107 if(state->flag & PATH_RAY_TRANSPARENT) {
108 /* transparent rays treated separately */
109 if(state->transparent_bounce >= kernel_data.integrator.transparent_max_bounce)
111 else if(state->transparent_bounce <= kernel_data.integrator.transparent_min_bounce)
116 if((state->bounce >= kernel_data.integrator.max_bounce) ||
117 (state->diffuse_bounce >= kernel_data.integrator.max_diffuse_bounce) ||
118 (state->glossy_bounce >= kernel_data.integrator.max_glossy_bounce) ||
119 (state->transmission_bounce >= kernel_data.integrator.max_transmission_bounce))
123 else if(state->bounce <= kernel_data.integrator.min_bounce) {
128 /* probalistic termination */
129 return average(throughput); /* todo: try using max here */