Blender  V3.3
subsurface.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 #pragma once
5 
7 
8 #include "kernel/bvh/bvh.h"
9 
10 #include "kernel/closure/alloc.h"
13 #include "kernel/closure/bssrdf.h"
14 #include "kernel/closure/volume.h"
15 
21 
23 
24 #ifdef __SUBSURFACE__
25 
26 ccl_device int subsurface_bounce(KernelGlobals kg,
29  ccl_private const ShaderClosure *sc)
30 {
31  /* We should never have two consecutive BSSRDF bounces, the second one should
32  * be converted to a diffuse BSDF to avoid this. */
34 
35  /* Setup path state for intersect_subsurface kernel. */
36  ccl_private const Bssrdf *bssrdf = (ccl_private const Bssrdf *)sc;
37 
38  /* Setup ray into surface. */
39  INTEGRATOR_STATE_WRITE(state, ray, P) = sd->P;
41  INTEGRATOR_STATE_WRITE(state, ray, tmin) = 0.0f;
42  INTEGRATOR_STATE_WRITE(state, ray, tmax) = FLT_MAX;
45 
46  /* Pass along object info, reusing isect to save memory. */
47  INTEGRATOR_STATE_WRITE(state, subsurface, Ng) = sd->Ng;
48 
49  uint32_t path_flag = (INTEGRATOR_STATE(state, path, flag) & ~PATH_RAY_CAMERA) |
52 
53  /* Compute weight, optionally including Fresnel from entry point. */
54  float3 weight = shader_bssrdf_sample_weight(sd, sc);
55 # ifdef __PRINCIPLED__
56  if (bssrdf->roughness != FLT_MAX) {
58  }
59 # endif
60 
61  if (sd->flag & SD_BACKFACING) {
62  path_flag |= PATH_RAY_SUBSURFACE_BACKFACING;
63  }
64 
65  INTEGRATOR_STATE_WRITE(state, path, throughput) *= weight;
66  INTEGRATOR_STATE_WRITE(state, path, flag) = path_flag;
67 
68  /* Advance random number offset for bounce. */
69  INTEGRATOR_STATE_WRITE(state, path, rng_offset) += PRNG_BOUNCE_NUM;
70 
71  if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
72  if (INTEGRATOR_STATE(state, path, bounce) == 0) {
73  INTEGRATOR_STATE_WRITE(state, path, pass_diffuse_weight) = one_float3();
74  INTEGRATOR_STATE_WRITE(state, path, pass_glossy_weight) = zero_float3();
75  }
76  }
77 
78  /* Pass BSSRDF parameters. */
79  INTEGRATOR_STATE_WRITE(state, subsurface, albedo) = bssrdf->albedo;
80  INTEGRATOR_STATE_WRITE(state, subsurface, radius) = bssrdf->radius;
81  INTEGRATOR_STATE_WRITE(state, subsurface, anisotropy) = bssrdf->anisotropy;
82 
84 }
85 
86 ccl_device void subsurface_shader_data_setup(KernelGlobals kg,
89  const uint32_t path_flag)
90 {
91  /* Get bump mapped normal from shader evaluation at exit point. */
92  float3 N = sd->N;
93  if (sd->flag & SD_HAS_BSSRDF_BUMP) {
94  N = shader_bssrdf_normal(sd);
95  }
96 
97  /* Setup diffuse BSDF at the exit point. This replaces shader_eval_surface. */
98  sd->flag &= ~SD_CLOSURE_FLAGS;
99  sd->num_closure = 0;
100  sd->num_closure_left = kernel_data.max_closures;
101 
102  const float3 weight = one_float3();
103 
104 # ifdef __PRINCIPLED__
105  if (path_flag & PATH_RAY_SUBSURFACE_USE_FRESNEL) {
107  sd, sizeof(PrincipledDiffuseBsdf), weight);
108 
109  if (bsdf) {
110  bsdf->N = N;
111  bsdf->roughness = FLT_MAX;
113  }
114  }
115  else
116 # endif /* __PRINCIPLED__ */
117  {
119  sd, sizeof(DiffuseBsdf), weight);
120 
121  if (bsdf) {
122  bsdf->N = N;
123  sd->flag |= bsdf_diffuse_setup(bsdf);
124  }
125  }
126 }
127 
128 ccl_device_inline bool subsurface_scatter(KernelGlobals kg, IntegratorState state)
129 {
130  RNGState rng_state;
131  path_state_rng_load(state, &rng_state);
132 
135 
137  if (!subsurface_random_walk(kg, state, rng_state, ray, ss_isect)) {
138  return false;
139  }
140  }
141  else {
142  if (!subsurface_disk(kg, state, rng_state, ray, ss_isect)) {
143  return false;
144  }
145  }
146 
147 # ifdef __VOLUME__
148  /* Update volume stack if needed. */
149  if (kernel_data.integrator.use_volumes) {
150  const int object = ss_isect.hits[0].object;
151  const int object_flag = kernel_data_fetch(object_flag, object);
152 
153  if (object_flag & SD_OBJECT_INTERSECTS_VOLUME) {
154  float3 P = INTEGRATOR_STATE(state, ray, P);
155 
157  }
158  }
159 # endif /* __VOLUME__ */
160 
161  /* Pretend ray is coming from the outside towards the exit point. This ensures
162  * correct front/back facing normals.
163  * TODO: find a more elegant solution? */
164  ray.P += ray.D * ray.tmax * 2.0f;
165  ray.D = -ray.D;
166 
167  integrator_state_write_isect(kg, state, &ss_isect.hits[0]);
169 
170  /* Advance random number offset for bounce. */
171  INTEGRATOR_STATE_WRITE(state, path, rng_offset) += PRNG_BOUNCE_NUM;
172 
173  const int shader = intersection_get_shader(kg, &ss_isect.hits[0]);
174  const int shader_flags = kernel_data_fetch(shaders, shader).flags;
175  const int object_flags = intersection_get_object_flags(kg, &ss_isect.hits[0]);
176  const bool use_caustics = kernel_data.integrator.use_caustics &&
177  (object_flags & SD_OBJECT_CAUSTICS);
178  const bool use_raytrace_kernel = (shader_flags & SD_HAS_RAYTRACE);
179 
180  if (use_caustics) {
182  state,
185  shader);
186  }
187  else if (use_raytrace_kernel) {
189  state,
192  shader);
193  }
194  else {
196  state,
199  shader);
200  }
201 
202  return true;
203 }
204 
205 #endif /* __SUBSURFACE__ */
206 
ccl_device_inline ccl_private ShaderClosure * bsdf_alloc(ccl_private ShaderData *sd, int size, float3 weight)
Definition: alloc.h:50
ccl_device int bsdf_diffuse_setup(ccl_private DiffuseBsdf *bsdf)
Definition: bsdf_diffuse.h:23
ccl_device int bsdf_principled_diffuse_setup(ccl_private PrincipledDiffuseBsdf *bsdf)
@ PRINCIPLED_DIFFUSE_LAMBERT_EXIT
#define kernel_assert(cond)
Definition: cpu/compat.h:34
#define ccl_optional_struct_init
Definition: cuda/compat.h:53
#define ccl_device
Definition: cuda/compat.h:32
#define ccl_private
Definition: cuda/compat.h:48
#define ccl_device_inline
Definition: cuda/compat.h:34
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
ccl_device_forceinline int intersection_get_object_flags(KernelGlobals kg, ccl_private const Intersection *ccl_restrict isect)
ccl_device_forceinline int intersection_get_shader(KernelGlobals kg, ccl_private const Intersection *ccl_restrict isect)
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define kernel_data_fetch(name, index)
ccl_device_forceinline float differential_make_compact(const differential3 D)
Definition: differential.h:117
ccl_device_forceinline float differential_zero_compact()
Definition: differential.h:112
CCL_NAMESPACE_BEGIN ccl_device void integrator_volume_stack_update_for_subsurface(KernelGlobals kg, IntegratorState state, const float3 from_P, const float3 to_P)
const int state
ccl_device_inline float3 shader_bssrdf_sample_weight(ccl_private const ShaderData *ccl_restrict sd, ccl_private const ShaderClosure *ccl_restrict bssrdf_sc)
@ CLOSURE_BSSRDF_BURLEY_ID
@ SD_CLOSURE_FLAGS
Definition: kernel/types.h:758
@ SD_BACKFACING
Definition: kernel/types.h:738
@ SD_HAS_BSSRDF_BUMP
Definition: kernel/types.h:774
@ SD_HAS_RAYTRACE
Definition: kernel/types.h:792
@ PRNG_BOUNCE_NUM
Definition: kernel/types.h:172
@ PATH_RAY_SUBSURFACE_USE_FRESNEL
Definition: kernel/types.h:260
@ PATH_RAY_SUBSURFACE_BACKFACING
Definition: kernel/types.h:261
@ PATH_RAY_SUBSURFACE_DISK
Definition: kernel/types.h:259
@ PATH_RAY_CAMERA
Definition: kernel/types.h:194
@ PATH_RAY_DIFFUSE_ANCESTOR
Definition: kernel/types.h:229
@ PATH_RAY_SUBSURFACE_RANDOM_WALK
Definition: kernel/types.h:258
@ KERNEL_FEATURE_LIGHT_PASSES
ShaderData
Definition: kernel/types.h:925
@ SD_OBJECT_CAUSTICS
Definition: kernel/types.h:829
@ SD_OBJECT_INTERSECTS_VOLUME
Definition: kernel/types.h:814
@ LABEL_SUBSURFACE_SCATTER
Definition: kernel/types.h:325
ShaderClosure
Definition: kernel/types.h:726
@ DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE
@ DEVICE_KERNEL_INTEGRATOR_INTERSECT_SUBSURFACE
@ DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE
@ DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_MNEE
ccl_device_inline float3 one_float3()
Definition: math_float3.h:89
ccl_device_inline float3 zero_float3()
Definition: math_float3.h:80
static float P(float k)
Definition: math_interp.c:25
#define N
ccl_device_inline void path_state_rng_load(ConstIntegratorState state, ccl_private RNGState *rng_state)
Definition: path_state.h:283
IntegratorStateCPU *ccl_restrict IntegratorState
Definition: state.h:147
#define INTEGRATOR_STATE_WRITE(state, nested_struct, member)
Definition: state.h:155
#define INTEGRATOR_STATE(state, nested_struct, member)
Definition: state.h:154
ccl_device_forceinline void integrator_path_next_sorted(KernelGlobals kg, IntegratorState state, const DeviceKernel current_kernel, const DeviceKernel next_kernel, const uint32_t key)
Definition: state_flow.h:168
ccl_device_forceinline void integrator_state_write_isect(KernelGlobals kg, IntegratorState state, ccl_private const Intersection *ccl_restrict isect)
Definition: state_util.h:68
CCL_NAMESPACE_BEGIN ccl_device_forceinline void integrator_state_write_ray(KernelGlobals kg, IntegratorState state, ccl_private const Ray *ccl_restrict ray)
Definition: state_util.h:14
closure color bssrdf(string method, normal N, vector radius, color albedo) BUILTIN
unsigned int uint32_t
Definition: stdint.h:80
Definition: bssrdf.h:8
ccl_device_inline bool subsurface_disk(KernelGlobals kg, IntegratorState state, RNGState rng_state, ccl_private Ray &ray, ccl_private LocalIntersection &ss_isect)
ccl_device_inline bool subsurface_random_walk(KernelGlobals kg, IntegratorState state, RNGState rng_state, ccl_private Ray &ray, ccl_private LocalIntersection &ss_isect)
BLI_INLINE float D(const float *data, const int res[3], int x, int y, int z)
Definition: voxel.c:13