Code refactor: tweaks in SSS code to prepare for coming changes.
[blender-staging.git] / intern / cycles / kernel / kernel_path_subsurface.h
1 /*
2  * Copyright 2017 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 #ifdef __SUBSURFACE__
20 #  ifndef __KERNEL_CUDA__
21 ccl_device
22 #  else
23 ccl_device_inline
24 #  endif
25 bool kernel_path_subsurface_scatter(
26         KernelGlobals *kg,
27         ShaderData *sd,
28         ShaderData *emission_sd,
29         PathRadiance *L,
30         ccl_addr_space PathState *state,
31         ccl_addr_space Ray *ray,
32         ccl_addr_space float3 *throughput,
33         ccl_addr_space SubsurfaceIndirectRays *ss_indirect)
34 {
35         float bssrdf_u, bssrdf_v;
36         path_state_rng_2D(kg, state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
37
38         const ShaderClosure *sc = shader_bssrdf_pick(sd, throughput, &bssrdf_u);
39
40         /* do bssrdf scatter step if we picked a bssrdf closure */
41         if(sc) {
42                 /* We should never have two consecutive BSSRDF bounces,
43                  * the second one should be converted to a diffuse BSDF to
44                  * avoid this.
45                  */
46                 kernel_assert(!(state->flag & PATH_RAY_DIFFUSE_ANCESTOR));
47
48                 uint lcg_state = lcg_state_init_addrspace(state, 0x68bc21eb);
49
50                 LocalIntersection ss_isect;
51                 int num_hits = subsurface_scatter_multi_intersect(kg,
52                                                                   &ss_isect,
53                                                                   sd,
54                                                                   sc,
55                                                                   &lcg_state,
56                                                                   bssrdf_u, bssrdf_v,
57                                                                   false);
58 #  ifdef __VOLUME__
59                 bool need_update_volume_stack =
60                         kernel_data.integrator.use_volumes &&
61                         sd->object_flag & SD_OBJECT_INTERSECTS_VOLUME;
62 #  endif  /* __VOLUME__ */
63
64                 /* compute lighting with the BSDF closure */
65                 for(int hit = 0; hit < num_hits; hit++) {
66                         /* NOTE: We reuse the existing ShaderData, we assume the path
67                          * integration loop stops when this function returns true.
68                          */
69                         subsurface_scatter_multi_setup(kg,
70                                                        &ss_isect,
71                                                        hit,
72                                                        sd,
73                                                        state,
74                                                        sc);
75
76                         kernel_path_surface_connect_light(kg, sd, emission_sd, *throughput, state, L);
77
78                         ccl_addr_space PathState *hit_state = &ss_indirect->state[ss_indirect->num_rays];
79                         ccl_addr_space Ray *hit_ray = &ss_indirect->rays[ss_indirect->num_rays];
80                         ccl_addr_space float3 *hit_tp = &ss_indirect->throughputs[ss_indirect->num_rays];
81                         PathRadianceState *hit_L_state = &ss_indirect->L_state[ss_indirect->num_rays];
82
83                         *hit_state = *state;
84                         *hit_ray = *ray;
85                         *hit_tp = *throughput;
86                         *hit_L_state = L->state;
87
88                         hit_state->rng_offset += PRNG_BOUNCE_NUM;
89
90                         if(kernel_path_surface_bounce(kg,
91                                                       sd,
92                                                       hit_tp,
93                                                       hit_state,
94                                                       hit_L_state,
95                                                       hit_ray))
96                         {
97 #  ifdef __LAMP_MIS__
98                                 hit_state->ray_t = 0.0f;
99 #  endif  /* __LAMP_MIS__ */
100
101 #  ifdef __VOLUME__
102                                 if(need_update_volume_stack) {
103                                         Ray volume_ray = *ray;
104                                         /* Setup ray from previous surface point to the new one. */
105                                         volume_ray.D = normalize_len(hit_ray->P - volume_ray.P,
106                                                                      &volume_ray.t);
107
108                                         kernel_volume_stack_update_for_subsurface(
109                                             kg,
110                                             emission_sd,
111                                             &volume_ray,
112                                             hit_state->volume_stack);
113                                 }
114 #  endif  /* __VOLUME__ */
115                                 ss_indirect->num_rays++;
116                         }
117                 }
118                 return true;
119         }
120         return false;
121 }
122
123 ccl_device_inline void kernel_path_subsurface_init_indirect(
124         ccl_addr_space SubsurfaceIndirectRays *ss_indirect)
125 {
126         ss_indirect->num_rays = 0;
127 }
128
129 ccl_device void kernel_path_subsurface_setup_indirect(
130         KernelGlobals *kg,
131         ccl_addr_space SubsurfaceIndirectRays *ss_indirect,
132         ccl_addr_space PathState *state,
133         ccl_addr_space Ray *ray,
134         PathRadiance *L,
135         ccl_addr_space float3 *throughput)
136 {
137         /* Setup state, ray and throughput for indirect SSS rays. */
138         ss_indirect->num_rays--;
139
140         path_radiance_sum_indirect(L);
141         path_radiance_reset_indirect(L);
142
143         *state = ss_indirect->state[ss_indirect->num_rays];
144         *ray = ss_indirect->rays[ss_indirect->num_rays];
145         L->state = ss_indirect->L_state[ss_indirect->num_rays];
146         *throughput = ss_indirect->throughputs[ss_indirect->num_rays];
147
148         state->rng_offset += ss_indirect->num_rays * PRNG_BOUNCE_NUM;
149 }
150
151 #endif  /* __SUBSURFACE__ */
152
153 CCL_NAMESPACE_END
154