Blender V5.0
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
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 const ccl_private 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;
50 float sum_nonspecular_weight = 0.0f;
51
52 for (int i = 0; i < sd->num_closure; i++) {
53 const ccl_private ShaderClosure *sc = &sd->closure[i];
54
55 if (!CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
56 continue;
57 }
58
59 /* All closures contribute to the normal feature, but only diffuse-like ones to the albedo. */
60 /* If far-field hair, use fiber tangent as feature instead of normal. */
61 normal += (sc->type == CLOSURE_BSDF_HAIR_HUANG_ID ? safe_normalize(sd->dPdu) : sc->N) *
62 sc->sample_weight;
63 sum_weight += sc->sample_weight;
64
65 const Spectrum closure_albedo = bsdf_albedo(kg, sd, sc, true, true);
66 if (bsdf_get_specular_roughness_squared(sc) > sqr(0.075f) ||
68 {
69 /* Far-field hair models "count" as diffuse. */
70 diffuse_albedo += closure_albedo;
71 sum_nonspecular_weight += sc->sample_weight;
72 }
73 else {
74 specular_albedo += closure_albedo;
75 }
76 }
77
78 /* Wait for next bounce if 75% or more sample weight belongs to specular-like closures. */
79 if ((sum_weight == 0.0f) || (sum_nonspecular_weight * 4.0f > sum_weight)) {
80 if (sum_weight != 0.0f) {
81 normal /= sum_weight;
82 }
83
84 if (kernel_data.film.pass_denoising_normal != PASS_UNUSED) {
85 /* Transform normal into camera space. */
86 const Transform worldtocamera = kernel_data.cam.worldtocamera;
87 normal = transform_direction(&worldtocamera, normal);
88
89 const float3 denoising_normal = ensure_finite(normal);
90 film_write_pass_float3(buffer + kernel_data.film.pass_denoising_normal, denoising_normal);
91 }
92
93 if (kernel_data.film.pass_denoising_albedo != PASS_UNUSED) {
94 const Spectrum denoising_feature_throughput = INTEGRATOR_STATE(
95 state, path, denoising_feature_throughput);
96 const Spectrum denoising_albedo = ensure_finite(denoising_feature_throughput *
97 diffuse_albedo);
98 film_write_pass_spectrum(buffer + kernel_data.film.pass_denoising_albedo, denoising_albedo);
99 }
100
102 }
103 else {
104 INTEGRATOR_STATE_WRITE(state, path, denoising_feature_throughput) *= specular_albedo;
105 }
106}
107
108ccl_device_forceinline void film_write_denoising_features_volume(KernelGlobals kg,
110 const Spectrum albedo,
111 const bool scatter,
114{
116 const Spectrum denoising_feature_throughput = INTEGRATOR_STATE(
117 state, path, denoising_feature_throughput);
118
119 if (scatter && kernel_data.film.pass_denoising_normal != PASS_UNUSED) {
120 /* Assume scatter is sufficiently diffuse to stop writing denoising features. */
122
123 /* Write view direction as normal. */
124 const float3 denoising_normal = make_float3(0.0f, 0.0f, -1.0f);
125 film_write_pass_float3(buffer + kernel_data.film.pass_denoising_normal, denoising_normal);
126 }
127
128 if (kernel_data.film.pass_denoising_albedo != PASS_UNUSED) {
129 /* Write albedo. */
130 const Spectrum denoising_albedo = ensure_finite(denoising_feature_throughput * albedo);
131 film_write_pass_spectrum(buffer + kernel_data.film.pass_denoising_albedo, denoising_albedo);
132 }
133}
134#endif /* __DENOISING_FEATURES__ */
135
CCL_NAMESPACE_BEGIN ccl_device_inline float bsdf_get_specular_roughness_squared(const ccl_private ShaderClosure *sc)
Definition bsdf.h:29
ccl_device_inline Spectrum bsdf_albedo(KernelGlobals kg, const ccl_private ShaderData *sd, const ccl_private ShaderClosure *sc, const bool reflection, const bool transmission)
Definition bsdf.h:648
#define kernel_data
#define PASS_UNUSED
#define ccl_restrict
#define ccl_device_forceinline
#define zero_spectrum
#define ccl_private
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_global
#define CLOSURE_IS_BSDF_OR_BSSRDF(type)
#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
@ CLOSURE_BSDF_HAIR_HUANG_ID
@ SD_HAS_ONLY_VOLUME
@ PATH_RAY_SHADOW_CATCHER_PASS
@ PATH_RAY_DENOISING_FEATURES
ccl_device_inline float ensure_finite(const float v)
Definition math_base.h:356
ccl_device_inline float2 safe_normalize(const float2 a)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:17
static ulong state[N]
#define N
float average(point a)
Definition node_math.h:144
closure color scatter(string phase, float Anisotropy, float IOR, float Backscatter, float Alpha, float Diameter)
#define sqr
#define INTEGRATOR_STATE_WRITE(state, nested_struct, member)
Definition state.h:236
#define INTEGRATOR_STATE(state, nested_struct, member)
Definition state.h:235
IntegratorStateCPU * IntegratorState
Definition state.h:228
i
Definition text_draw.cc:230
ccl_device_inline float3 transform_direction(const ccl_private Transform *t, const float3 a)
Definition transform.h:127
float3 Spectrum
uint8_t flag
Definition wm_window.cc:145
ccl_device_inline void film_write_pass_float3(ccl_global float *ccl_restrict buffer, const float3 value)
Definition write.h:68
ccl_device_inline void film_write_pass_spectrum(ccl_global float *ccl_restrict buffer, Spectrum value)
Definition write.h:86
ccl_device_inline void film_write_pass_float(ccl_global float *ccl_restrict buffer, const float value)
Definition write.h:58
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:24