Blender V5.0
pass_accessor.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
6
7#include "kernel/types.h"
8#include "session/buffers.h"
9
10#include "util/log.h"
11
13
14/* --------------------------------------------------------------------
15 * Pass input information.
16 */
17
19 : type(pass.type),
20 mode(pass.mode),
22 is_lightgroup(!pass.lightgroup.empty()),
23 offset(pass.offset)
24{
25}
26
27/* --------------------------------------------------------------------
28 * Pass destination.
29 */
30
35
37{
38 const PassInfo pass_info = Pass::get_info(pass_type, pass_mode);
40}
41
42/* --------------------------------------------------------------------
43 * Pass source.
44 */
45
50
51/* --------------------------------------------------------------------
52 * Pass accessor.
53 */
54
56 const float exposure,
57 const int num_samples)
58 : pass_access_info_(pass_access_info), exposure_(exposure), num_samples_(num_samples)
59{
60}
61
63 const Destination &destination) const
64{
65 if (render_buffers == nullptr || render_buffers->buffer.data() == nullptr) {
66 return false;
67 }
68
69 return get_render_tile_pixels(render_buffers, render_buffers->params, destination);
70}
71
72static void pad_pixels(const BufferParams &buffer_params,
73 const PassAccessor::Destination &destination,
74 const int src_num_components)
75{
76 /* When requesting a single channel pass as RGBA, or RGB pass as RGBA,
77 * fill in the additional components for convenience. */
78 const int dest_num_components = destination.num_components;
79
80 if (src_num_components >= dest_num_components) {
81 return;
82 }
83
84 const size_t size = static_cast<size_t>(buffer_params.width) * buffer_params.height;
85 if (destination.pixels) {
86 const size_t pixel_stride = destination.pixel_stride ? destination.pixel_stride :
87 destination.num_components;
88
89 float *pixel = destination.pixels + pixel_stride * destination.offset;
90
91 for (size_t i = 0; i < size; i++, pixel += dest_num_components) {
92 if (dest_num_components >= 3 && src_num_components == 1) {
93 pixel[1] = pixel[0];
94 pixel[2] = pixel[0];
95 }
96 if (dest_num_components >= 4) {
97 pixel[3] = 1.0f;
98 }
99 }
100 }
101
102 if (destination.pixels_half_rgba) {
103 const half one = float_to_half_display(1.0f);
104 half4 *pixel = destination.pixels_half_rgba + destination.offset;
105
106 for (size_t i = 0; i < size; i++, pixel++) {
107 if (dest_num_components >= 3 && src_num_components == 1) {
108 pixel[0].y = pixel[0].x;
109 pixel[0].z = pixel[0].x;
110 }
111 if (dest_num_components >= 4) {
112 pixel[0].w = one;
113 }
114 }
115 }
116}
117
119 const BufferParams &buffer_params,
120 const Destination &destination) const
121{
122 if (render_buffers == nullptr || render_buffers->buffer.data() == nullptr) {
123 return false;
124 }
125
126 const PassType type = pass_access_info_.type;
127 const PassMode mode = pass_access_info_.mode;
128 const PassInfo pass_info = Pass::get_info(
129 type, mode, pass_access_info_.include_albedo, pass_access_info_.is_lightgroup);
130 int num_written_components = pass_info.num_components;
131
132 if (pass_info.num_components == 1) {
133 if (is_volume_guiding_pass(type)) {
134 get_pass_rgbe(render_buffers, buffer_params, destination);
135 num_written_components = 3;
136 }
137 /* Single channel passes. */
138 else if (mode == PassMode::DENOISED) {
139 /* Denoised passes store their final pixels, no need in special calculation. */
140 get_pass_float(render_buffers, buffer_params, destination);
141 }
142 else if (type == PASS_DEPTH) {
143 get_pass_depth(render_buffers, buffer_params, destination);
144 }
145 else if (type == PASS_MIST) {
146 get_pass_mist(render_buffers, buffer_params, destination);
147 }
148 else if (type == PASS_VOLUME_MAJORANT) {
149 get_pass_volume_majorant(render_buffers, buffer_params, destination);
150 }
151 else if (type == PASS_SAMPLE_COUNT) {
152 get_pass_sample_count(render_buffers, buffer_params, destination);
153 }
154 else {
155 get_pass_float(render_buffers, buffer_params, destination);
156 }
157 }
158 else if (type == PASS_MOTION) {
159 /* Motion pass. */
160 DCHECK_EQ(destination.num_components, 4) << "Motion pass must have 4 components";
161 get_pass_motion(render_buffers, buffer_params, destination);
162 }
163 else if (type == PASS_CRYPTOMATTE) {
164 /* Cryptomatte pass. */
165 DCHECK_EQ(destination.num_components, 4) << "Cryptomatte pass must have 4 components";
166 get_pass_cryptomatte(render_buffers, buffer_params, destination);
167 }
168 else {
169 /* RGB, RGBA and vector passes. */
170 DCHECK(destination.num_components == 3 || destination.num_components == 4)
171 << pass_type_as_string(type) << " pass must have 3 or 4 components";
172
173 if (type == PASS_SHADOW_CATCHER_MATTE && pass_access_info_.use_approximate_shadow_catcher) {
174 /* Denoised matte with shadow needs to do calculation (will use denoised shadow catcher pass
175 * to approximate shadow with). */
176 get_pass_shadow_catcher_matte_with_shadow(render_buffers, buffer_params, destination);
177 }
178 else if (type == PASS_SHADOW_CATCHER && mode != PassMode::DENOISED) {
179 /* Shadow catcher pass. */
180 get_pass_shadow_catcher(render_buffers, buffer_params, destination);
181 }
182 else if ((pass_info.divide_type != PASS_NONE || pass_info.direct_type != PASS_NONE ||
183 pass_info.indirect_type != PASS_NONE) &&
184 mode != PassMode::DENOISED)
185 {
186 /* RGB lighting passes that need to divide out color and/or sum direct and indirect.
187 * These can also optionally write alpha like the combined pass. */
188 get_pass_light_path(render_buffers, buffer_params, destination);
189 num_written_components = 4;
190 }
191 else {
192 /* Passes that need no special computation, or denoised passes that already
193 * had the computation done. */
194 if (pass_info.num_components == 3) {
195 get_pass_float3(render_buffers, buffer_params, destination);
196
197 /* Use alpha for colors passes. */
198 if (type == PASS_DIFFUSE_COLOR || type == PASS_GLOSSY_COLOR ||
200 {
201 num_written_components = destination.num_components;
202 }
203 }
204 else if (pass_info.num_components == 4) {
205 if (destination.num_components == 3) {
206 /* Special case for denoiser access of RGBA passes ignoring alpha channel. */
207 get_pass_float3(render_buffers, buffer_params, destination);
208 }
209 else if (type == PASS_COMBINED || type == PASS_SHADOW_CATCHER ||
211 {
212 /* Passes with transparency as 4th component. */
213 get_pass_combined(render_buffers, buffer_params, destination);
214 }
215 else {
216 /* Passes with alpha as 4th component. */
217 get_pass_float4(render_buffers, buffer_params, destination);
218 }
219 }
220 }
221 }
222
223 pad_pixels(buffer_params, destination, num_written_components);
224
225 return true;
226}
227
229 const BufferParams &buffer_params,
230 const Destination &destination) const
231{
232 const PassType type = pass_access_info_.type;
233 const PassMode mode = pass_access_info_.mode;
234 const PassInfo &pass_info = Pass::get_info(
235 type, mode, pass_access_info_.include_albedo, pass_access_info_.is_lightgroup);
236
237 kfilm_convert->pass_offset = pass_access_info_.offset;
238 kfilm_convert->pass_stride = buffer_params.pass_stride;
239
240 kfilm_convert->pass_use_exposure = pass_info.use_exposure;
241 kfilm_convert->pass_use_filter = pass_info.use_filter;
242
243 /* TODO(sergey): Some of the passes needs to become denoised when denoised pass is accessed. */
244 if (pass_info.direct_type != PASS_NONE) {
245 kfilm_convert->pass_offset = buffer_params.get_pass_offset(pass_info.direct_type);
246 }
247 kfilm_convert->pass_indirect = buffer_params.get_pass_offset(pass_info.indirect_type);
248 kfilm_convert->pass_divide = buffer_params.get_pass_offset(pass_info.divide_type);
249
250 kfilm_convert->pass_combined = buffer_params.get_pass_offset(PASS_COMBINED);
251 kfilm_convert->pass_sample_count = buffer_params.get_pass_offset(PASS_SAMPLE_COUNT);
252 kfilm_convert->pass_adaptive_aux_buffer = buffer_params.get_pass_offset(
254 kfilm_convert->pass_motion_weight = buffer_params.get_pass_offset(PASS_MOTION_WEIGHT);
255 kfilm_convert->pass_shadow_catcher = buffer_params.get_pass_offset(PASS_SHADOW_CATCHER, mode);
256 kfilm_convert->pass_shadow_catcher_sample_count = buffer_params.get_pass_offset(
258 kfilm_convert->pass_shadow_catcher_matte = buffer_params.get_pass_offset(
260
261 /* Background is not denoised, so always use noisy pass. */
262 kfilm_convert->pass_background = buffer_params.get_pass_offset(PASS_BACKGROUND);
263
264 /* If we have a sample count pass, we must perform the division in the kernel instead
265 * (unless the sample count pass is the one being read). */
266 const bool divide_by_samples = (type == PASS_SAMPLE_COUNT) ||
267 (kfilm_convert->pass_sample_count == PASS_UNUSED);
268 if (pass_info.use_filter && divide_by_samples) {
269 kfilm_convert->scale = num_samples_ != 0 ? pass_info.scale / num_samples_ : 0.0f;
270 }
271 else {
272 kfilm_convert->scale = pass_info.scale;
273 }
274
275 if (pass_info.use_exposure) {
276 kfilm_convert->exposure = exposure_;
277 }
278 else {
279 kfilm_convert->exposure = 1.0f;
280 }
281
282 kfilm_convert->scale_exposure = kfilm_convert->scale * kfilm_convert->exposure;
283
284 kfilm_convert->use_approximate_shadow_catcher = pass_access_info_.use_approximate_shadow_catcher;
286 pass_access_info_.use_approximate_shadow_catcher_background;
287 kfilm_convert->show_active_pixels = pass_access_info_.show_active_pixels;
288
289 kfilm_convert->num_components = destination.num_components;
290 kfilm_convert->pixel_stride = destination.pixel_stride ? destination.pixel_stride :
291 destination.num_components;
292
293 kfilm_convert->is_denoised = (mode == PassMode::DENOISED);
294}
295
297{
298 if (render_buffers == nullptr || render_buffers->buffer.data() == nullptr) {
299 return false;
300 }
301
302 const PassInfo pass_info = Pass::get_info(pass_access_info_.type,
304 pass_access_info_.include_albedo,
305 pass_access_info_.is_lightgroup);
306
307 const BufferParams &buffer_params = render_buffers->params;
308
309 float *buffer_data = render_buffers->buffer.data();
310 const int size = buffer_params.width * buffer_params.height;
311
312 const int out_stride = buffer_params.pass_stride;
313 const int in_stride = source.num_components;
314 const int num_components_to_copy = min(source.num_components, pass_info.num_components);
315
316 float *out = buffer_data + pass_access_info_.offset;
317 const float *in = source.pixels + source.offset * in_stride;
318
319 for (int i = 0; i < size; i++, out += out_stride, in += in_stride) {
320 memcpy(out, in, sizeof(float) * num_components_to_copy);
321 }
322
323 return true;
324}
325
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
int pass_stride
Definition buffers.h:92
int get_pass_offset(PassType type, PassMode mode=PassMode::NOISY) const
Definition buffers.cpp:164
NODE_DECLARE int width
Definition buffers.h:70
const float * pixels
PassAccessor(const PassAccessInfo &pass_access_info, const float exposure, const int num_samples)
bool set_render_tile_pixels(RenderBuffers *render_buffers, const Source &source)
bool get_render_tile_pixels(const RenderBuffers *render_buffers, const Destination &destination) const
virtual void init_kernel_film_convert(KernelFilmConvert *kfilm_convert, const BufferParams &buffer_params, const Destination &destination) const
PassAccessInfo pass_access_info_
PassInfo get_info() const
Definition pass.cpp:146
device_vector< float > buffer
Definition buffers.h:158
BufferParams params
Definition buffers.h:155
Definition half.h:41
#define PASS_UNUSED
#define CCL_NAMESPACE_END
#define in
#define out
ccl_device_inline half float_to_half_display(const float f)
Definition half.h:135
PassType
@ PASS_SHADOW_CATCHER_SAMPLE_COUNT
@ PASS_BACKGROUND
@ PASS_TRANSMISSION_COLOR
@ PASS_SHADOW_CATCHER_MATTE
@ PASS_DEPTH
@ PASS_MIST
@ PASS_SHADOW_CATCHER
@ PASS_VOLUME_MAJORANT
@ PASS_MOTION
@ PASS_COMBINED
@ PASS_ADAPTIVE_AUX_BUFFER
@ PASS_NONE
@ PASS_CRYPTOMATTE
@ PASS_DIFFUSE_COLOR
@ PASS_SAMPLE_COUNT
@ PASS_MOTION_WEIGHT
@ PASS_GLOSSY_COLOR
#define DCHECK(expression)
Definition log.h:135
#define DCHECK_EQ(a, b)
Definition log.h:144
CCL_NAMESPACE_BEGIN const char * pass_type_as_string(const PassType type)
Definition pass.cpp:12
bool is_volume_guiding_pass(const PassType pass_type)
Definition pass.cpp:474
PassMode
Definition pass.h:20
@ DENOISED
Definition pass.h:22
static void pad_pixels(const BufferParams &buffer_params, const PassAccessor::Destination &destination, const int src_num_components)
#define min(a, b)
Definition sort.cc:36
int use_approximate_shadow_catcher_background
int pass_shadow_catcher_sample_count
PassType direct_type
Definition pass.h:34
int num_components
Definition pass.h:28
float scale
Definition pass.h:32
bool use_filter
Definition pass.h:29
PassType divide_type
Definition pass.h:33
bool use_exposure
Definition pass.h:30
PassType indirect_type
Definition pass.h:35
Definition half.h:60
half x
Definition half.h:61
half w
Definition half.h:61
half z
Definition half.h:61
half y
Definition half.h:61
i
Definition text_draw.cc:230