Blender  V3.3
passes.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 
6 #include "kernel/geom/geom.h"
7 
10 
12 
13 /* Get pointer to pixel in render buffer. */
16 {
18  const uint64_t render_buffer_offset = (uint64_t)render_pixel_index *
19  kernel_data.film.pass_stride;
20  return render_buffer + render_buffer_offset;
21 }
22 
23 #ifdef __DENOISING_FEATURES__
24 
25 ccl_device_forceinline void kernel_write_denoising_features_surface(
26  KernelGlobals kg,
28  ccl_private const ShaderData *sd,
30 {
31  if (!(INTEGRATOR_STATE(state, path, flag) & PATH_RAY_DENOISING_FEATURES)) {
32  return;
33  }
34 
35  /* Skip implicitly transparent surfaces. */
36  if (sd->flag & SD_HAS_ONLY_VOLUME) {
37  return;
38  }
39 
41 
42  if (kernel_data.film.pass_denoising_depth != PASS_UNUSED) {
43  const float3 denoising_feature_throughput = INTEGRATOR_STATE(
44  state, path, denoising_feature_throughput);
45  const float depth = sd->ray_length - INTEGRATOR_STATE(state, ray, tmin);
46  const float denoising_depth = ensure_finite(average(denoising_feature_throughput) * depth);
47  kernel_write_pass_float(buffer + kernel_data.film.pass_denoising_depth, denoising_depth);
48  }
49 
51  float3 diffuse_albedo = zero_float3();
52  float3 specular_albedo = zero_float3();
53  float sum_weight = 0.0f, sum_nonspecular_weight = 0.0f;
54 
55  for (int i = 0; i < sd->num_closure; i++) {
56  ccl_private const ShaderClosure *sc = &sd->closure[i];
57 
58  if (!CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
59  continue;
60  }
61 
62  /* All closures contribute to the normal feature, but only diffuse-like ones to the albedo. */
63  normal += sc->N * sc->sample_weight;
64  sum_weight += sc->sample_weight;
65 
66  float3 closure_albedo = sc->weight;
67  /* Closures that include a Fresnel term typically have weights close to 1 even though their
68  * actual contribution is significantly lower.
69  * To account for this, we scale their weight by the average fresnel factor (the same is also
70  * done for the sample weight in the BSDF setup, so we don't need to scale that here). */
71  if (CLOSURE_IS_BSDF_MICROFACET_FRESNEL(sc->type)) {
73  closure_albedo *= bsdf->extra->fresnel_color;
74  }
75  else if (sc->type == CLOSURE_BSDF_PRINCIPLED_SHEEN_ID) {
77  closure_albedo *= bsdf->avg_value;
78  }
79  else if (sc->type == CLOSURE_BSDF_HAIR_PRINCIPLED_ID) {
80  closure_albedo *= bsdf_principled_hair_albedo(sc);
81  }
82  else if (sc->type == CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID) {
83  /* BSSRDF already accounts for weight, retro-reflection would double up. */
85  sc;
86  if (bsdf->components == PRINCIPLED_DIFFUSE_RETRO_REFLECTION) {
87  continue;
88  }
89  }
90 
91  if (bsdf_get_specular_roughness_squared(sc) > sqr(0.075f)) {
92  diffuse_albedo += closure_albedo;
93  sum_nonspecular_weight += sc->sample_weight;
94  }
95  else {
96  specular_albedo += closure_albedo;
97  }
98  }
99 
100  /* Wait for next bounce if 75% or more sample weight belongs to specular-like closures. */
101  if ((sum_weight == 0.0f) || (sum_nonspecular_weight * 4.0f > sum_weight)) {
102  if (sum_weight != 0.0f) {
103  normal /= sum_weight;
104  }
105 
106  if (kernel_data.film.pass_denoising_normal != PASS_UNUSED) {
107  /* Transform normal into camera space. */
108  const Transform worldtocamera = kernel_data.cam.worldtocamera;
109  normal = transform_direction(&worldtocamera, normal);
110 
111  const float3 denoising_normal = ensure_finite(normal);
112  kernel_write_pass_float3(buffer + kernel_data.film.pass_denoising_normal, denoising_normal);
113  }
114 
115  if (kernel_data.film.pass_denoising_albedo != PASS_UNUSED) {
116  const float3 denoising_feature_throughput = INTEGRATOR_STATE(
117  state, path, denoising_feature_throughput);
118  const float3 denoising_albedo = ensure_finite(denoising_feature_throughput * diffuse_albedo);
119  kernel_write_pass_float3(buffer + kernel_data.film.pass_denoising_albedo, denoising_albedo);
120  }
121 
123  }
124  else {
125  INTEGRATOR_STATE_WRITE(state, path, denoising_feature_throughput) *= specular_albedo;
126  }
127 }
128 
129 ccl_device_forceinline void kernel_write_denoising_features_volume(KernelGlobals kg,
131  const float3 albedo,
132  const bool scatter,
133  ccl_global float *ccl_restrict
135 {
137  const float3 denoising_feature_throughput = INTEGRATOR_STATE(
138  state, path, denoising_feature_throughput);
139 
140  if (scatter && kernel_data.film.pass_denoising_normal != PASS_UNUSED) {
141  /* Assume scatter is sufficiently diffuse to stop writing denoising features. */
143 
144  /* Write view direction as normal. */
145  const float3 denoising_normal = make_float3(0.0f, 0.0f, -1.0f);
146  kernel_write_pass_float3(buffer + kernel_data.film.pass_denoising_normal, denoising_normal);
147  }
148 
149  if (kernel_data.film.pass_denoising_albedo != PASS_UNUSED) {
150  /* Write albedo. */
151  const float3 denoising_albedo = ensure_finite(denoising_feature_throughput * albedo);
152  kernel_write_pass_float3(buffer + kernel_data.film.pass_denoising_albedo, denoising_albedo);
153  }
154 }
155 #endif /* __DENOISING_FEATURES__ */
156 
158  size_t depth,
159  float id,
160  float matte_weight)
161 {
162  kernel_write_id_slots(buffer, depth * 2, id, matte_weight);
163  return depth * 4;
164 }
165 
168  ccl_private const ShaderData *sd,
170 {
171 #ifdef __PASSES__
172  const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
173 
174  if (!(path_flag & PATH_RAY_TRANSPARENT_BACKGROUND)) {
175  return;
176  }
177 
178  const int flag = kernel_data.film.pass_flag;
179 
180  if (!(flag & PASS_ANY)) {
181  return;
182  }
183 
185 
186  if (!(path_flag & PATH_RAY_SINGLE_PASS_DONE)) {
187  if (!(sd->flag & SD_TRANSPARENT) || kernel_data.film.pass_alpha_threshold == 0.0f ||
188  average(shader_bsdf_alpha(kg, sd)) >= kernel_data.film.pass_alpha_threshold) {
189  if (INTEGRATOR_STATE(state, path, sample) == 0) {
190  if (flag & PASSMASK(DEPTH)) {
191  const float depth = camera_z_depth(kg, sd->P);
192  kernel_write_pass_float(buffer + kernel_data.film.pass_depth, depth);
193  }
194  if (flag & PASSMASK(OBJECT_ID)) {
195  const float id = object_pass_id(kg, sd->object);
196  kernel_write_pass_float(buffer + kernel_data.film.pass_object_id, id);
197  }
198  if (flag & PASSMASK(MATERIAL_ID)) {
199  const float id = shader_pass_id(kg, sd);
200  kernel_write_pass_float(buffer + kernel_data.film.pass_material_id, id);
201  }
202  if (flag & PASSMASK(POSITION)) {
203  const float3 position = sd->P;
204  kernel_write_pass_float3(buffer + kernel_data.film.pass_position, position);
205  }
206  }
207 
208  if (flag & PASSMASK(NORMAL)) {
209  const float3 normal = shader_bsdf_average_normal(kg, sd);
210  kernel_write_pass_float3(buffer + kernel_data.film.pass_normal, normal);
211  }
212  if (flag & PASSMASK(ROUGHNESS)) {
213  const float roughness = shader_bsdf_average_roughness(sd);
214  kernel_write_pass_float(buffer + kernel_data.film.pass_roughness, roughness);
215  }
216  if (flag & PASSMASK(UV)) {
217  const float3 uv = primitive_uv(kg, sd);
218  kernel_write_pass_float3(buffer + kernel_data.film.pass_uv, uv);
219  }
220  if (flag & PASSMASK(MOTION)) {
221  const float4 speed = primitive_motion_vector(kg, sd);
222  kernel_write_pass_float4(buffer + kernel_data.film.pass_motion, speed);
223  kernel_write_pass_float(buffer + kernel_data.film.pass_motion_weight, 1.0f);
224  }
225 
227  }
228  }
229 
230  if (kernel_data.film.cryptomatte_passes) {
231  const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
232  const float matte_weight = average(throughput) *
233  (1.0f - average(shader_bsdf_transparency(kg, sd)));
234  if (matte_weight > 0.0f) {
235  ccl_global float *cryptomatte_buffer = buffer + kernel_data.film.pass_cryptomatte;
236  if (kernel_data.film.cryptomatte_passes & CRYPT_OBJECT) {
237  const float id = object_cryptomatte_id(kg, sd->object);
238  cryptomatte_buffer += kernel_write_id_pass(
239  cryptomatte_buffer, kernel_data.film.cryptomatte_depth, id, matte_weight);
240  }
241  if (kernel_data.film.cryptomatte_passes & CRYPT_MATERIAL) {
242  const float id = shader_cryptomatte_id(kg, sd->shader);
243  cryptomatte_buffer += kernel_write_id_pass(
244  cryptomatte_buffer, kernel_data.film.cryptomatte_depth, id, matte_weight);
245  }
246  if (kernel_data.film.cryptomatte_passes & CRYPT_ASSET) {
247  const float id = object_cryptomatte_asset_id(kg, sd->object);
248  cryptomatte_buffer += kernel_write_id_pass(
249  cryptomatte_buffer, kernel_data.film.cryptomatte_depth, id, matte_weight);
250  }
251  }
252  }
253 
254  if (flag & PASSMASK(DIFFUSE_COLOR)) {
255  const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
256  kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_color,
257  shader_bsdf_diffuse(kg, sd) * throughput);
258  }
259  if (flag & PASSMASK(GLOSSY_COLOR)) {
260  const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
261  kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_color,
262  shader_bsdf_glossy(kg, sd) * throughput);
263  }
264  if (flag & PASSMASK(TRANSMISSION_COLOR)) {
265  const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
266  kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_color,
267  shader_bsdf_transmission(kg, sd) * throughput);
268  }
269  if (flag & PASSMASK(MIST)) {
270  /* Bring depth into 0..1 range. */
271  const float mist_start = kernel_data.film.mist_start;
272  const float mist_inv_depth = kernel_data.film.mist_inv_depth;
273 
274  const float depth = camera_distance(kg, sd->P);
275  float mist = saturatef((depth - mist_start) * mist_inv_depth);
276 
277  /* Falloff */
278  const float mist_falloff = kernel_data.film.mist_falloff;
279 
280  if (mist_falloff == 1.0f)
281  ;
282  else if (mist_falloff == 2.0f)
283  mist = mist * mist;
284  else if (mist_falloff == 0.5f)
285  mist = sqrtf(mist);
286  else
287  mist = powf(mist, mist_falloff);
288 
289  /* Modulate by transparency */
290  const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
291  const float3 alpha = shader_bsdf_alpha(kg, sd);
292  const float mist_output = (1.0f - mist) * average(throughput * alpha);
293 
294  /* Note that the final value in the render buffer we want is 1 - mist_output,
295  * to avoid having to tracking this in the Integrator state we do the negation
296  * after rendering. */
297  kernel_write_pass_float(buffer + kernel_data.film.pass_mist, mist_output);
298  }
299 #endif
300 }
301 
float float4[4]
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value NORMAL
CCL_NAMESPACE_BEGIN ccl_device_inline float bsdf_get_specular_roughness_squared(ccl_private const ShaderClosure *sc)
Definition: bsdf.h:31
ccl_device float3 bsdf_principled_hair_albedo(ccl_private const ShaderClosure *sc)
@ PRINCIPLED_DIFFUSE_RETRO_REFLECTION
#define ccl_restrict
Definition: cuda/compat.h:50
#define ccl_device_forceinline
Definition: cuda/compat.h:35
#define ccl_private
Definition: cuda/compat.h:48
#define ccl_device_inline
Definition: cuda/compat.h:34
#define ccl_global
Definition: cuda/compat.h:43
#define powf(x, y)
Definition: cuda/compat.h:103
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
ccl_device_inline void kernel_write_id_slots(ccl_global float *buffer, int num_slots, float id, float weight)
Definition: id_passes.h:16
IconTextureDrawCall normal
ccl_device_inline float3 transform_direction(ccl_private const Transform *t, const float3 a)
ccl_device_inline float camera_distance(KernelGlobals kg, float3 P)
ccl_device_inline float camera_z_depth(KernelGlobals kg, float3 P)
ccl_global float * buffer
ccl_gpu_kernel_postfix ccl_global KernelWorkTile const int ccl_global float * render_buffer
const uint64_t render_pixel_index
const int state
ccl_device_inline float object_pass_id(KernelGlobals kg, int object)
ccl_device_inline float object_cryptomatte_asset_id(KernelGlobals kg, int object)
ccl_device int shader_pass_id(KernelGlobals kg, ccl_private const ShaderData *sd)
ccl_device_inline float object_cryptomatte_id(KernelGlobals kg, int object)
ccl_device float3 shader_bsdf_average_normal(KernelGlobals kg, ccl_private const ShaderData *sd)
ccl_device float shader_bsdf_average_roughness(ccl_private const ShaderData *sd)
ccl_device float shader_cryptomatte_id(KernelGlobals kg, int shader)
ccl_device float3 shader_bsdf_transparency(KernelGlobals kg, ccl_private const ShaderData *sd)
ccl_device float3 shader_bsdf_transmission(KernelGlobals kg, ccl_private const ShaderData *sd)
ccl_device float3 shader_bsdf_diffuse(KernelGlobals kg, ccl_private const ShaderData *sd)
ccl_device float3 shader_bsdf_glossy(KernelGlobals kg, ccl_private const ShaderData *sd)
ccl_device float3 shader_bsdf_alpha(KernelGlobals kg, ccl_private const ShaderData *sd)
#define CLOSURE_IS_BSDF_MICROFACET_FRESNEL(type)
#define CLOSURE_IS_BSDF_OR_BSSRDF(type)
@ CLOSURE_BSDF_HAIR_PRINCIPLED_ID
@ CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID
@ CLOSURE_BSDF_PRINCIPLED_SHEEN_ID
@ SD_HAS_ONLY_VOLUME
Definition: kernel/types.h:770
@ SD_TRANSPARENT
Definition: kernel/types.h:754
#define PASS_UNUSED
Definition: kernel/types.h:44
@ PATH_RAY_SINGLE_PASS_DONE
Definition: kernel/types.h:232
@ PATH_RAY_DENOISING_FEATURES
Definition: kernel/types.h:266
@ PATH_RAY_TRANSPARENT_BACKGROUND
Definition: kernel/types.h:235
@ CRYPT_ASSET
Definition: kernel/types.h:411
@ CRYPT_OBJECT
Definition: kernel/types.h:409
@ CRYPT_MATERIAL
Definition: kernel/types.h:410
ShaderData
Definition: kernel/types.h:925
#define PASSMASK(pass)
Definition: kernel/types.h:331
ShaderClosure
Definition: kernel/types.h:726
#define PASS_ANY
Definition: kernel/types.h:405
ccl_device_inline float average(const float2 &a)
Definition: math_float2.h:170
ccl_device_inline float3 zero_float3()
Definition: math_float3.h:80
#define sqrtf(x)
Definition: metal/compat.h:243
#define make_float3(x, y, z)
Definition: metal/compat.h:204
static const pxr::TfToken roughness("roughness", pxr::TfToken::Immortal)
CCL_NAMESPACE_BEGIN ccl_device_forceinline ccl_global float * kernel_pass_pixel_render_buffer(KernelGlobals kg, ConstIntegratorState state, ccl_global float *ccl_restrict render_buffer)
Definition: passes.h:14
ccl_device_inline void kernel_write_data_passes(KernelGlobals kg, IntegratorState state, ccl_private const ShaderData *sd, ccl_global float *ccl_restrict render_buffer)
Definition: passes.h:166
ccl_device_inline size_t kernel_write_id_pass(ccl_global float *ccl_restrict buffer, size_t depth, float id, float matte_weight)
Definition: passes.h:157
ccl_device_forceinline float4 primitive_motion_vector(KernelGlobals kg, ccl_private const ShaderData *sd)
Definition: primitive.h:265
ccl_device_forceinline float3 primitive_uv(KernelGlobals kg, ccl_private const ShaderData *sd)
Definition: primitive.h:197
IntegratorStateCPU *ccl_restrict IntegratorState
Definition: state.h:147
#define INTEGRATOR_STATE_WRITE(state, nested_struct, member)
Definition: state.h:155
const IntegratorStateCPU *ccl_restrict ConstIntegratorState
Definition: state.h:148
#define INTEGRATOR_STATE(state, nested_struct, member)
Definition: state.h:154
unsigned int uint32_t
Definition: stdint.h:80
unsigned __int64 uint64_t
Definition: stdint.h:90
ccl_device_inline float ensure_finite(float v)
Definition: util/math.h:361
ccl_device_inline float sqr(float a)
Definition: util/math.h:746
ccl_device_inline float saturatef(float a)
Definition: util/math.h:404
CCL_NAMESPACE_BEGIN ccl_device_inline void kernel_write_pass_float(ccl_global float *ccl_restrict buffer, float value)
Definition: write_passes.h:12
ccl_device_inline void kernel_write_pass_float3(ccl_global float *ccl_restrict buffer, float3 value)
Definition: write_passes.h:21
ccl_device_inline void kernel_write_pass_float4(ccl_global float *ccl_restrict buffer, float4 value)
Definition: write_passes.h:39