Blender V4.3
denoising_passes.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
7#include "kernel/geom/geom.h"
8
9#include "kernel/film/write.h"
10
12
13#ifdef __DENOISING_FEATURES__
14ccl_device_forceinline void film_write_denoising_features_surface(KernelGlobals kg,
16 ccl_private const ShaderData *sd,
19{
20 const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
21 if (!(path_flag & PATH_RAY_DENOISING_FEATURES)) {
22 return;
23 }
24
25 /* Skip implicitly transparent surfaces. */
26 if (sd->flag & SD_HAS_ONLY_VOLUME) {
27 return;
28 }
29
30 /* Don't write denoising passes for paths that were split off for shadow catchers
31 * to avoid double-counting. */
32 if (path_flag & PATH_RAY_SHADOW_CATCHER_PASS) {
33 return;
34 }
35
37
38 if (kernel_data.film.pass_denoising_depth != PASS_UNUSED) {
39 const Spectrum denoising_feature_throughput = INTEGRATOR_STATE(
40 state, path, denoising_feature_throughput);
41 const float depth = sd->ray_length - INTEGRATOR_STATE(state, ray, tmin);
42 const float denoising_depth = ensure_finite(average(denoising_feature_throughput) * depth);
43 film_write_pass_float(buffer + kernel_data.film.pass_denoising_depth, denoising_depth);
44 }
45
46 float3 normal = zero_float3();
47 Spectrum diffuse_albedo = zero_spectrum();
48 Spectrum specular_albedo = zero_spectrum();
49 float sum_weight = 0.0f, sum_nonspecular_weight = 0.0f;
50
51 for (int i = 0; i < sd->num_closure; i++) {
52 ccl_private const ShaderClosure *sc = &sd->closure[i];
53
54 if (!CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
55 continue;
56 }
57
58 /* All closures contribute to the normal feature, but only diffuse-like ones to the albedo. */
59 /* If far-field hair, use fiber tangent as feature instead of normal. */
60 normal += (sc->type == CLOSURE_BSDF_HAIR_HUANG_ID ? safe_normalize(sd->dPdu) : sc->N) *
61 sc->sample_weight;
62 sum_weight += sc->sample_weight;
63
64 Spectrum closure_albedo = bsdf_albedo(kg, sd, sc, true, true);
65 if (bsdf_get_specular_roughness_squared(sc) > sqr(0.075f) ||
67 {
68 /* Far-field hair models "count" as diffuse. */
69 diffuse_albedo += closure_albedo;
70 sum_nonspecular_weight += sc->sample_weight;
71 }
72 else {
73 specular_albedo += closure_albedo;
74 }
75 }
76
77 /* Wait for next bounce if 75% or more sample weight belongs to specular-like closures. */
78 if ((sum_weight == 0.0f) || (sum_nonspecular_weight * 4.0f > sum_weight)) {
79 if (sum_weight != 0.0f) {
80 normal /= sum_weight;
81 }
82
83 if (kernel_data.film.pass_denoising_normal != PASS_UNUSED) {
84 /* Transform normal into camera space. */
85 const Transform worldtocamera = kernel_data.cam.worldtocamera;
86 normal = transform_direction(&worldtocamera, normal);
87
88 const float3 denoising_normal = ensure_finite(normal);
89 film_write_pass_float3(buffer + kernel_data.film.pass_denoising_normal, denoising_normal);
90 }
91
92 if (kernel_data.film.pass_denoising_albedo != PASS_UNUSED) {
93 const Spectrum denoising_feature_throughput = INTEGRATOR_STATE(
94 state, path, denoising_feature_throughput);
95 const Spectrum denoising_albedo = ensure_finite(denoising_feature_throughput *
96 diffuse_albedo);
97 film_write_pass_spectrum(buffer + kernel_data.film.pass_denoising_albedo, denoising_albedo);
98 }
99
100 INTEGRATOR_STATE_WRITE(state, path, flag) &= ~PATH_RAY_DENOISING_FEATURES;
101 }
102 else {
103 INTEGRATOR_STATE_WRITE(state, path, denoising_feature_throughput) *= specular_albedo;
104 }
105}
106
107ccl_device_forceinline void film_write_denoising_features_volume(KernelGlobals kg,
109 const Spectrum albedo,
110 const bool scatter,
113{
115 const Spectrum denoising_feature_throughput = INTEGRATOR_STATE(
116 state, path, denoising_feature_throughput);
117
118 if (scatter && kernel_data.film.pass_denoising_normal != PASS_UNUSED) {
119 /* Assume scatter is sufficiently diffuse to stop writing denoising features. */
120 INTEGRATOR_STATE_WRITE(state, path, flag) &= ~PATH_RAY_DENOISING_FEATURES;
121
122 /* Write view direction as normal. */
123 const float3 denoising_normal = make_float3(0.0f, 0.0f, -1.0f);
124 film_write_pass_float3(buffer + kernel_data.film.pass_denoising_normal, denoising_normal);
125 }
126
127 if (kernel_data.film.pass_denoising_albedo != PASS_UNUSED) {
128 /* Write albedo. */
129 const Spectrum denoising_albedo = ensure_finite(denoising_feature_throughput * albedo);
130 film_write_pass_spectrum(buffer + kernel_data.film.pass_denoising_albedo, denoising_albedo);
131 }
132}
133#endif /* __DENOISING_FEATURES__ */
134
CCL_NAMESPACE_BEGIN ccl_device_inline float bsdf_get_specular_roughness_squared(ccl_private const ShaderClosure *sc)
Definition bsdf.h:30
ccl_device_inline Spectrum bsdf_albedo(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private const ShaderClosure *sc, const bool reflection, const bool transmission)
Definition bsdf.h:604
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
#define ccl_restrict
#define ccl_device_forceinline
#define ccl_private
#define ccl_global
#define CCL_NAMESPACE_END
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
ccl_gpu_kernel_postfix ccl_global KernelWorkTile const int ccl_global float * render_buffer
#define CLOSURE_IS_BSDF_OR_BSSRDF(type)
@ CLOSURE_BSDF_HAIR_HUANG_ID
@ SD_HAS_ONLY_VOLUME
#define PASS_UNUSED
@ PATH_RAY_SHADOW_CATCHER_PASS
@ PATH_RAY_DENOISING_FEATURES
ShaderData
ShaderClosure
ccl_device_inline float average(const float2 a)
ccl_device_inline float2 safe_normalize(const float2 a)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:15
static ulong state[N]
#define N
IntegratorStateCPU *ccl_restrict IntegratorState
Definition state.h:228
#define INTEGRATOR_STATE_WRITE(state, nested_struct, member)
Definition state.h:236
#define INTEGRATOR_STATE(state, nested_struct, member)
Definition state.h:235
unsigned int uint32_t
Definition stdint.h:80
ccl_device_inline float3 transform_direction(ccl_private const Transform *t, const float3 a)
Definition transform.h:94
#define zero_spectrum
SPECTRUM_DATA_TYPE Spectrum
ccl_device_inline float ensure_finite(float v)
Definition util/math.h:373
ccl_device_inline float sqr(float a)
Definition util/math.h:782
uint8_t flag
Definition wm_window.cc:138
ccl_device_inline void film_write_pass_spectrum(ccl_global float *ccl_restrict buffer, Spectrum value)
Definition write.h:65
ccl_device_inline void film_write_pass_float3(ccl_global float *ccl_restrict buffer, float3 value)
Definition write.h:48
CCL_NAMESPACE_BEGIN ccl_device_forceinline ccl_global float * film_pass_pixel_render_buffer(KernelGlobals kg, ConstIntegratorState state, ccl_global float *ccl_restrict render_buffer)
Definition write.h:17
ccl_device_inline void film_write_pass_float(ccl_global float *ccl_restrict buffer, float value)
Definition write.h:39