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