ClangFormat: apply to source, most of intern
[blender.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
26     kernel_path_subsurface_scatter(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   PROFILING_INIT(kg, PROFILING_SUBSURFACE);
36
37   float bssrdf_u, bssrdf_v;
38   path_state_rng_2D(kg, state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
39
40   const ShaderClosure *sc = shader_bssrdf_pick(sd, throughput, &bssrdf_u);
41
42   /* do bssrdf scatter step if we picked a bssrdf closure */
43   if (sc) {
44     /* We should never have two consecutive BSSRDF bounces,
45      * the second one should be converted to a diffuse BSDF to
46      * avoid this.
47      */
48     kernel_assert(!(state->flag & PATH_RAY_DIFFUSE_ANCESTOR));
49
50     uint lcg_state = lcg_state_init_addrspace(state, 0x68bc21eb);
51
52     LocalIntersection ss_isect;
53     int num_hits = subsurface_scatter_multi_intersect(
54         kg, &ss_isect, sd, state, sc, &lcg_state, bssrdf_u, bssrdf_v, false);
55 #  ifdef __VOLUME__
56     bool need_update_volume_stack = kernel_data.integrator.use_volumes &&
57                                     sd->object_flag & SD_OBJECT_INTERSECTS_VOLUME;
58 #  endif /* __VOLUME__ */
59
60     /* Closure memory will be overwritten, so read required variables now. */
61     Bssrdf *bssrdf = (Bssrdf *)sc;
62     ClosureType bssrdf_type = sc->type;
63     float bssrdf_roughness = bssrdf->roughness;
64
65     /* compute lighting with the BSDF closure */
66     for (int hit = 0; hit < num_hits; hit++) {
67       /* NOTE: We reuse the existing ShaderData, we assume the path
68        * integration loop stops when this function returns true.
69        */
70       subsurface_scatter_multi_setup(kg, &ss_isect, hit, sd, state, bssrdf_type, bssrdf_roughness);
71
72       kernel_path_surface_connect_light(kg, sd, emission_sd, *throughput, state, L);
73
74       ccl_addr_space PathState *hit_state = &ss_indirect->state[ss_indirect->num_rays];
75       ccl_addr_space Ray *hit_ray = &ss_indirect->rays[ss_indirect->num_rays];
76       ccl_addr_space float3 *hit_tp = &ss_indirect->throughputs[ss_indirect->num_rays];
77       PathRadianceState *hit_L_state = &ss_indirect->L_state[ss_indirect->num_rays];
78
79       *hit_state = *state;
80       *hit_ray = *ray;
81       *hit_tp = *throughput;
82       *hit_L_state = L->state;
83
84       hit_state->rng_offset += PRNG_BOUNCE_NUM;
85
86       if (kernel_path_surface_bounce(kg, sd, hit_tp, hit_state, hit_L_state, hit_ray)) {
87 #  ifdef __LAMP_MIS__
88         hit_state->ray_t = 0.0f;
89 #  endif /* __LAMP_MIS__ */
90
91 #  ifdef __VOLUME__
92         if (need_update_volume_stack) {
93           Ray volume_ray = *ray;
94           /* Setup ray from previous surface point to the new one. */
95           volume_ray.D = normalize_len(hit_ray->P - volume_ray.P, &volume_ray.t);
96
97           kernel_volume_stack_update_for_subsurface(
98               kg, emission_sd, &volume_ray, hit_state->volume_stack);
99         }
100 #  endif /* __VOLUME__ */
101         ss_indirect->num_rays++;
102       }
103     }
104     return true;
105   }
106   return false;
107 }
108
109 ccl_device_inline void kernel_path_subsurface_init_indirect(
110     ccl_addr_space SubsurfaceIndirectRays *ss_indirect)
111 {
112   ss_indirect->num_rays = 0;
113 }
114
115 ccl_device void kernel_path_subsurface_setup_indirect(
116     KernelGlobals *kg,
117     ccl_addr_space SubsurfaceIndirectRays *ss_indirect,
118     ccl_addr_space PathState *state,
119     ccl_addr_space Ray *ray,
120     PathRadiance *L,
121     ccl_addr_space float3 *throughput)
122 {
123   /* Setup state, ray and throughput for indirect SSS rays. */
124   ss_indirect->num_rays--;
125
126   path_radiance_sum_indirect(L);
127   path_radiance_reset_indirect(L);
128
129   *state = ss_indirect->state[ss_indirect->num_rays];
130   *ray = ss_indirect->rays[ss_indirect->num_rays];
131   L->state = ss_indirect->L_state[ss_indirect->num_rays];
132   *throughput = ss_indirect->throughputs[ss_indirect->num_rays];
133
134   state->rng_offset += ss_indirect->num_rays * PRNG_BOUNCE_NUM;
135 }
136
137 #endif /* __SUBSURFACE__ */
138
139 CCL_NAMESPACE_END