Blender  V2.93
kernel_path_subsurface.h
Go to the documentation of this file.
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 
18 
19 #ifdef __SUBSURFACE__
20 # ifndef __KERNEL_CUDA__
22 # else
24 # endif
25  bool
26  kernel_path_subsurface_scatter(KernelGlobals *kg,
27  ShaderData *sd,
28  ShaderData *emission_sd,
29  PathRadiance *L,
31  ccl_addr_space Ray *ray,
32  ccl_addr_space float3 *throughput,
34 {
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  */
49 
50  uint lcg_state = lcg_state_init_addrspace(state, 0x68bc21eb);
51 
52  LocalIntersection ss_isect;
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(
111 {
112  ss_indirect->num_rays = 0;
113 }
114 
115 ccl_device void kernel_path_subsurface_setup_indirect(
116  KernelGlobals *kg,
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 
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 
unsigned int uint
Definition: BLI_sys_types.h:83
ccl_device_inline void path_radiance_sum_indirect(PathRadiance *L)
ccl_device_inline void path_radiance_reset_indirect(PathRadiance *L)
#define kernel_data
#define kernel_assert(cond)
#define ccl_addr_space
#define ccl_device
#define ccl_device_inline
#define CCL_NAMESPACE_END
ccl_device bool kernel_path_surface_bounce(KernelGlobals *kg, ShaderData *sd, ccl_addr_space float3 *throughput, ccl_addr_space PathState *state, PathRadianceState *L_state, ccl_addr_space Ray *ray)
CCL_NAMESPACE_BEGIN ccl_device_inline void kernel_path_surface_connect_light(KernelGlobals *kg, ShaderData *sd, ShaderData *emission_sd, float3 throughput, ccl_addr_space PathState *state, PathRadiance *L)
#define PROFILING_INIT(kg, event)
ccl_device_inline void path_state_rng_2D(KernelGlobals *kg, const ccl_addr_space PathState *state, int dimension, float *fx, float *fy)
ccl_device_inline uint lcg_state_init_addrspace(ccl_addr_space PathState *state, uint scramble)
ccl_device_inline const ShaderClosure * shader_bssrdf_pick(ShaderData *sd, ccl_addr_space float3 *throughput, float *randu)
ccl_device_inline int subsurface_scatter_multi_intersect(KernelGlobals *kg, LocalIntersection *ss_isect, ShaderData *sd, ccl_addr_space PathState *state, const ShaderClosure *sc, uint *lcg_state, float bssrdf_u, float bssrdf_v, bool all)
ccl_device_noinline void subsurface_scatter_multi_setup(KernelGlobals *kg, LocalIntersection *ss_isect, int hit, ShaderData *sd, ccl_addr_space PathState *state, ClosureType type, float roughness)
@ PRNG_BOUNCE_NUM
Definition: kernel_types.h:248
@ PRNG_BSDF_U
Definition: kernel_types.h:240
@ PATH_RAY_DIFFUSE_ANCESTOR
Definition: kernel_types.h:302
ShaderData
@ SD_OBJECT_INTERSECTS_VOLUME
Definition: kernel_types.h:914
ShaderClosure
Definition: kernel_types.h:831
static ulong state[N]
#define L
closure color bssrdf(string method, normal N, vector radius, color albedo) BUILTIN
Definition: bssrdf.h:22
float t
Definition: kernel_types.h:649
float3 P
Definition: kernel_types.h:647
float3 D
Definition: kernel_types.h:648
ClosureType
Definition: svm_types.h:527
ccl_device_inline float2 normalize_len(const float2 &a, float *t)
@ PROFILING_SUBSURFACE