Blender  V2.93
kernel_path_surface.h
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2013 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 #if defined(__BRANCHED_PATH__) || defined(__SUBSURFACE__) || defined(__SHADOW_TRICKS__) || \
20  defined(__BAKING__)
21 /* branched path tracing: connect path directly to position on one or more lights and add it to L
22  */
23 ccl_device_noinline_cpu void kernel_branched_path_surface_connect_light(
24  KernelGlobals *kg,
25  ShaderData *sd,
26  ShaderData *emission_sd,
28  float3 throughput,
29  float num_samples_adjust,
30  PathRadiance *L,
31  int sample_all_lights)
32 {
33 # ifdef __EMISSION__
34  /* sample illumination from lights to find path contribution */
36 
37  int num_lights = 0;
38  if (kernel_data.integrator.use_direct_light) {
39  if (sample_all_lights) {
40  num_lights = kernel_data.integrator.num_all_lights;
41  if (kernel_data.integrator.pdf_triangles != 0.0f) {
42  num_lights += 1;
43  }
44  }
45  else {
46  num_lights = 1;
47  }
48  }
49 
50  for (int i = 0; i < num_lights; i++) {
51  /* sample one light at random */
52  int num_samples = 1;
53  int num_all_lights = 1;
54  uint lamp_rng_hash = state->rng_hash;
55  bool double_pdf = false;
56  bool is_mesh_light = false;
57  bool is_lamp = false;
58 
59  if (sample_all_lights) {
60  /* lamp sampling */
61  is_lamp = i < kernel_data.integrator.num_all_lights;
62  if (is_lamp) {
64  continue;
65  }
66  num_samples = ceil_to_int(num_samples_adjust * light_select_num_samples(kg, i));
67  num_all_lights = kernel_data.integrator.num_all_lights;
68  lamp_rng_hash = cmj_hash(state->rng_hash, i);
69  double_pdf = kernel_data.integrator.pdf_triangles != 0.0f;
70  }
71  /* mesh light sampling */
72  else {
73  num_samples = ceil_to_int(num_samples_adjust * kernel_data.integrator.mesh_light_samples);
74  double_pdf = kernel_data.integrator.num_all_lights != 0;
75  is_mesh_light = true;
76  }
77  }
78 
79  float num_samples_inv = num_samples_adjust / (num_samples * num_all_lights);
80 
81  for (int j = 0; j < num_samples; j++) {
82  Ray light_ray ccl_optional_struct_init;
83  light_ray.t = 0.0f; /* reset ray */
84 # ifdef __OBJECT_MOTION__
85  light_ray.time = sd->time;
86 # endif
87  bool has_emission = false;
88 
89  if (kernel_data.integrator.use_direct_light && (sd->flag & SD_BSDF_HAS_EVAL)) {
90  float light_u, light_v;
92  kg, lamp_rng_hash, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
93  float terminate = path_branched_rng_light_termination(
94  kg, lamp_rng_hash, state, j, num_samples);
95 
96  /* only sample triangle lights */
97  if (is_mesh_light && double_pdf) {
98  light_u = 0.5f * light_u;
99  }
100 
102  const int lamp = is_lamp ? i : -1;
103  if (light_sample(kg, lamp, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
104  /* The sampling probability returned by lamp_light_sample assumes that all lights were
105  * sampled. However, this code only samples lamps, so if the scene also had mesh lights,
106  * the real probability is twice as high. */
107  if (double_pdf) {
108  ls.pdf *= 2.0f;
109  }
110 
111  has_emission = direct_emission(
112  kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate);
113  }
114  }
115 
116  /* trace shadow ray */
117  float3 shadow;
118 
119  const bool blocked = shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow);
120 
121  if (has_emission) {
122  if (!blocked) {
123  /* accumulate */
125  L,
126  state,
127  throughput * num_samples_inv,
128  &L_light,
129  shadow,
130  num_samples_inv,
131  is_lamp);
132  }
133  else {
134  path_radiance_accum_total_light(L, state, throughput * num_samples_inv, &L_light);
135  }
136  }
137  }
138  }
139 # endif
140 }
141 
142 /* branched path tracing: bounce off or through surface to with new direction stored in ray */
143 ccl_device bool kernel_branched_path_surface_bounce(KernelGlobals *kg,
144  ShaderData *sd,
145  const ShaderClosure *sc,
146  int sample,
147  int num_samples,
148  ccl_addr_space float3 *throughput,
150  PathRadianceState *L_state,
151  ccl_addr_space Ray *ray,
152  float sum_sample_weight)
153 {
154  /* sample BSDF */
155  float bsdf_pdf;
157  float3 bsdf_omega_in ccl_optional_struct_init;
159  float bsdf_u, bsdf_v;
161  kg, state->rng_hash, state, sample, num_samples, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
162  int label;
163 
165  kg, sd, sc, bsdf_u, bsdf_v, &bsdf_eval, &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
166 
167  if (bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval))
168  return false;
169 
170  /* modify throughput */
171  path_radiance_bsdf_bounce(kg, L_state, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label);
172 
173 # ifdef __DENOISING_FEATURES__
174  state->denoising_feature_weight *= sc->sample_weight / (sum_sample_weight * num_samples);
175 # endif
176 
177  /* modify path state */
179 
180  /* setup ray */
181  ray->P = ray_offset(sd->P, (label & LABEL_TRANSMIT) ? -sd->Ng : sd->Ng);
182  ray->D = normalize(bsdf_omega_in);
183  ray->t = FLT_MAX;
184 # ifdef __RAY_DIFFERENTIALS__
185  ray->dP = sd->dP;
186  ray->dD = bsdf_domega_in;
187 # endif
188 # ifdef __OBJECT_MOTION__
189  ray->time = sd->time;
190 # endif
191 
192 # ifdef __VOLUME__
193  /* enter/exit volume */
194  if (label & LABEL_TRANSMIT)
195  kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
196 # endif
197 
198  /* branch RNG state */
199  path_state_branch(state, sample, num_samples);
200 
201  /* set MIS state */
202  state->min_ray_pdf = fminf(bsdf_pdf, FLT_MAX);
203  state->ray_pdf = bsdf_pdf;
204 # ifdef __LAMP_MIS__
205  state->ray_t = 0.0f;
206 # endif
207 
208  return true;
209 }
210 
211 #endif
212 
213 /* path tracing: connect path directly to position on a light and add it to L */
215  ShaderData *sd,
216  ShaderData *emission_sd,
217  float3 throughput,
219  PathRadiance *L)
220 {
222 
223 #ifdef __EMISSION__
224 # ifdef __SHADOW_TRICKS__
225  int all = (state->flag & PATH_RAY_SHADOW_CATCHER);
226  kernel_branched_path_surface_connect_light(kg, sd, emission_sd, state, throughput, 1.0f, L, all);
227 # else
228  /* sample illumination from lights to find path contribution */
229  Ray light_ray ccl_optional_struct_init;
231  bool is_lamp = false;
232  bool has_emission = false;
233 
234  light_ray.t = 0.0f;
235 # ifdef __OBJECT_MOTION__
236  light_ray.time = sd->time;
237 # endif
238 
239  if (kernel_data.integrator.use_direct_light && (sd->flag & SD_BSDF_HAS_EVAL)) {
240  float light_u, light_v;
241  path_state_rng_2D(kg, state, PRNG_LIGHT_U, &light_u, &light_v);
242 
244  if (light_sample(kg, -1, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) {
245  float terminate = path_state_rng_light_termination(kg, state);
246  has_emission = direct_emission(
247  kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate);
248  }
249  }
250 
251  /* trace shadow ray */
252  float3 shadow;
253 
254  const bool blocked = shadow_blocked(kg, sd, emission_sd, state, &light_ray, &shadow);
255 
256  if (has_emission) {
257  if (!blocked) {
258  /* accumulate */
259  path_radiance_accum_light(kg, L, state, throughput, &L_light, shadow, 1.0f, is_lamp);
260  }
261  else {
262  path_radiance_accum_total_light(L, state, throughput, &L_light);
263  }
264  }
265 # endif
266 #endif
267 }
268 
269 /* path tracing: bounce off or through surface to with new direction stored in ray */
271  ShaderData *sd,
272  ccl_addr_space float3 *throughput,
274  PathRadianceState *L_state,
275  ccl_addr_space Ray *ray)
276 {
278 
279  /* no BSDF? we can stop here */
280  if (sd->flag & SD_BSDF) {
281  /* sample BSDF */
282  float bsdf_pdf;
284  float3 bsdf_omega_in ccl_optional_struct_init;
286  float bsdf_u, bsdf_v;
287  path_state_rng_2D(kg, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
288  int label;
289 
291  kg, sd, bsdf_u, bsdf_v, &bsdf_eval, &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf);
292 
293  if (bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval))
294  return false;
295 
296  /* modify throughput */
297  path_radiance_bsdf_bounce(kg, L_state, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label);
298 
299  /* set labels */
300  if (!(label & LABEL_TRANSPARENT)) {
301  state->ray_pdf = bsdf_pdf;
302 #ifdef __LAMP_MIS__
303  state->ray_t = 0.0f;
304 #endif
305  state->min_ray_pdf = fminf(bsdf_pdf, state->min_ray_pdf);
306  }
307 
308  /* update path state */
310 
311  /* setup ray */
312  ray->P = ray_offset(sd->P, (label & LABEL_TRANSMIT) ? -sd->Ng : sd->Ng);
313  ray->D = normalize(bsdf_omega_in);
314 
315  if (state->bounce == 0)
316  ray->t -= sd->ray_length; /* clipping works through transparent */
317  else
318  ray->t = FLT_MAX;
319 
320 #ifdef __RAY_DIFFERENTIALS__
321  ray->dP = sd->dP;
322  ray->dD = bsdf_domega_in;
323 #endif
324 
325 #ifdef __VOLUME__
326  /* enter/exit volume */
327  if (label & LABEL_TRANSMIT)
328  kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
329 #endif
330  return true;
331  }
332 #ifdef __VOLUME__
333  else if (sd->flag & SD_HAS_ONLY_VOLUME) {
334  if (!path_state_volume_next(kg, state)) {
335  return false;
336  }
337 
338  if (state->bounce == 0)
339  ray->t -= sd->ray_length; /* clipping works through transparent */
340  else
341  ray->t = FLT_MAX;
342 
343  /* setup ray position, direction stays unchanged */
344  ray->P = ray_offset(sd->P, -sd->Ng);
345 # ifdef __RAY_DIFFERENTIALS__
346  ray->dP = sd->dP;
347 # endif
348 
349  /* enter/exit volume */
350  kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
351  return true;
352  }
353 #endif
354  else {
355  /* no bsdf or volume? */
356  return false;
357  }
358 }
359 
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNLIKELY(x)
ccl_device float3 bsdf_eval(KernelGlobals *kg, ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, float *pdf)
Definition: bsdf.h:485
const char * label
Light lamp
ccl_device_inline float3 ray_offset(float3 P, float3 Ng)
ccl_device_inline bool bsdf_eval_is_zero(BsdfEval *eval)
ccl_device_inline void path_radiance_accum_total_light(PathRadiance *L, ccl_addr_space PathState *state, float3 throughput, const BsdfEval *bsdf_eval)
ccl_device_inline void path_radiance_accum_light(KernelGlobals *kg, PathRadiance *L, ccl_addr_space PathState *state, float3 throughput, BsdfEval *bsdf_eval, float3 shadow, float shadow_fac, bool is_lamp)
ccl_device_inline void path_radiance_bsdf_bounce(KernelGlobals *kg, PathRadianceState *L_state, ccl_addr_space float3 *throughput, BsdfEval *bsdf_eval, float bsdf_pdf, int bounce, int bsdf_label)
#define kernel_data
#define ccl_addr_space
#define ccl_optional_struct_init
#define ccl_device
#define ccl_device_noinline_cpu
#define ccl_device_inline
#define CCL_NAMESPACE_END
#define fminf(x, y)
ccl_device_noinline_cpu bool direct_emission(KernelGlobals *kg, ShaderData *sd, ShaderData *emission_sd, LightSample *ls, ccl_addr_space PathState *state, Ray *ray, BsdfEval *eval, bool *is_lamp, float rand_terminate)
ccl_device_inline uint cmj_hash(uint i, uint p)
ccl_device_noinline bool light_sample(KernelGlobals *kg, int lamp, float randu, float randv, float time, float3 P, int bounce, LightSample *ls)
Definition: kernel_light.h:663
ccl_device_inline int light_select_num_samples(KernelGlobals *kg, int index)
Definition: kernel_light.h:700
ccl_device_inline bool light_select_reached_max_bounces(KernelGlobals *kg, int index, int bounce)
Definition: kernel_light.h:658
ccl_device_inline void path_state_next(KernelGlobals *kg, ccl_addr_space PathState *state, int label)
ccl_device_inline void path_state_branch(ccl_addr_space PathState *state, int branch, int num_branches)
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 void path_branched_rng_2D(KernelGlobals *kg, uint rng_hash, const ccl_addr_space PathState *state, int branch, int num_branches, int dimension, float *fx, float *fy)
ccl_device_inline float path_branched_rng_light_termination(KernelGlobals *kg, uint rng_hash, const ccl_addr_space PathState *state, int branch, int num_branches)
ccl_device_inline float path_state_rng_light_termination(KernelGlobals *kg, const ccl_addr_space PathState *state)
ccl_device int shader_bsdf_sample_closure(KernelGlobals *kg, ShaderData *sd, const ShaderClosure *sc, float randu, float randv, BsdfEval *bsdf_eval, float3 *omega_in, differential3 *domega_in, float *pdf)
ccl_device_inline int shader_bsdf_sample(KernelGlobals *kg, ShaderData *sd, float randu, float randv, BsdfEval *bsdf_eval, float3 *omega_in, differential3 *domega_in, float *pdf)
ccl_device_inline bool shadow_blocked(KernelGlobals *kg, ShaderData *sd, ShaderData *shadow_sd, ccl_addr_space PathState *state, Ray *ray, float3 *shadow)
@ SD_BSDF_HAS_EVAL
Definition: kernel_types.h:849
@ SD_HAS_ONLY_VOLUME
Definition: kernel_types.h:875
@ SD_BSDF
Definition: kernel_types.h:847
@ PRNG_BSDF_U
Definition: kernel_types.h:240
@ PRNG_LIGHT_U
Definition: kernel_types.h:242
@ PATH_RAY_SHADOW_CATCHER
Definition: kernel_types.h:306
ShaderData
@ LABEL_TRANSMIT
Definition: kernel_types.h:328
@ LABEL_TRANSPARENT
Definition: kernel_types.h:333
ShaderClosure
Definition: kernel_types.h:831
static ulong state[N]
#define L
static void sample(SocketReader *reader, int x, int y, float color[4])
__forceinline bool all(const avxb &b)
Definition: util_avxb.h:214
ccl_device_inline int ceil_to_int(float f)
Definition: util_math.h:342
ccl_device_inline float2 normalize(const float2 &a)
@ PROFILING_SURFACE_BOUNCE
@ PROFILING_CONNECT_LIGHT