Blender  V3.3
pass_accessor.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
5 
6 #include "session/buffers.h"
7 #include "util/log.h"
8 
9 // clang-format off
11 #include "kernel/types.h"
12 // clang-format on
13 
15 
16 /* --------------------------------------------------------------------
17  * Pass input information.
18  */
19 
21  : type(pass.type),
22  mode(pass.mode),
23  include_albedo(pass.include_albedo),
24  is_lightgroup(!pass.lightgroup.empty()),
25  offset(pass.offset)
26 {
27 }
28 
29 /* --------------------------------------------------------------------
30  * Pass destination.
31  */
32 
34  : pixels(pixels), num_components(num_components)
35 {
36 }
37 
39  : Destination(pass_type)
40 {
42 }
43 
45 {
46  const PassInfo pass_info = Pass::get_info(pass_type);
47  num_components = pass_info.num_components;
48 }
49 
50 /* --------------------------------------------------------------------
51  * Pass source.
52  */
53 
55  : pixels(pixels), num_components(num_components)
56 {
57 }
58 
59 /* --------------------------------------------------------------------
60  * Pass accessor.
61  */
62 
63 PassAccessor::PassAccessor(const PassAccessInfo &pass_access_info, float exposure, int num_samples)
64  : pass_access_info_(pass_access_info), exposure_(exposure), num_samples_(num_samples)
65 {
66 }
67 
69  const Destination &destination) const
70 {
71  if (render_buffers == nullptr || render_buffers->buffer.data() == nullptr) {
72  return false;
73  }
74 
75  return get_render_tile_pixels(render_buffers, render_buffers->params, destination);
76 }
77 
78 static void pad_pixels(const BufferParams &buffer_params,
79  const PassAccessor::Destination &destination,
80  const int src_num_components)
81 {
82  /* When requesting a single channel pass as RGBA, or RGB pass as RGBA,
83  * fill in the additional components for convenience. */
84  const int dest_num_components = destination.num_components;
85 
86  if (src_num_components >= dest_num_components) {
87  return;
88  }
89 
90  const size_t size = static_cast<size_t>(buffer_params.width) * buffer_params.height;
91  if (destination.pixels) {
92  const size_t pixel_stride = destination.pixel_stride ? destination.pixel_stride :
93  destination.num_components;
94 
95  float *pixel = destination.pixels + pixel_stride * destination.offset;
96 
97  for (size_t i = 0; i < size; i++, pixel += dest_num_components) {
98  if (dest_num_components >= 3 && src_num_components == 1) {
99  pixel[1] = pixel[0];
100  pixel[2] = pixel[0];
101  }
102  if (dest_num_components >= 4) {
103  pixel[3] = 1.0f;
104  }
105  }
106  }
107 
108  if (destination.pixels_half_rgba) {
109  const half one = float_to_half_display(1.0f);
110  half4 *pixel = destination.pixels_half_rgba + destination.offset;
111 
112  for (size_t i = 0; i < size; i++, pixel++) {
113  if (dest_num_components >= 3 && src_num_components == 1) {
114  pixel[0].y = pixel[0].x;
115  pixel[0].z = pixel[0].x;
116  }
117  if (dest_num_components >= 4) {
118  pixel[0].w = one;
119  }
120  }
121  }
122 }
123 
125  const BufferParams &buffer_params,
126  const Destination &destination) const
127 {
128  if (render_buffers == nullptr || render_buffers->buffer.data() == nullptr) {
129  return false;
130  }
131 
133  const PassMode mode = pass_access_info_.mode;
134  const PassInfo pass_info = Pass::get_info(
136  int num_written_components = pass_info.num_components;
137 
138  if (pass_info.num_components == 1) {
139  /* Single channel passes. */
140  if (mode == PassMode::DENOISED) {
141  /* Denoised passes store their final pixels, no need in special calculation. */
142  get_pass_float(render_buffers, buffer_params, destination);
143  }
144  else if (type == PASS_DEPTH) {
145  get_pass_depth(render_buffers, buffer_params, destination);
146  }
147  else if (type == PASS_MIST) {
148  get_pass_mist(render_buffers, buffer_params, destination);
149  }
150  else if (type == PASS_SAMPLE_COUNT) {
151  get_pass_sample_count(render_buffers, buffer_params, destination);
152  }
153  else {
154  get_pass_float(render_buffers, buffer_params, destination);
155  }
156  }
157  else if (type == PASS_MOTION) {
158  /* Motion pass. */
159  DCHECK_EQ(destination.num_components, 4) << "Motion pass must have 4 components";
160  get_pass_motion(render_buffers, buffer_params, destination);
161  }
162  else if (type == PASS_CRYPTOMATTE) {
163  /* Cryptomatte pass. */
164  DCHECK_EQ(destination.num_components, 4) << "Cryptomatte pass must have 4 components";
165  get_pass_cryptomatte(render_buffers, buffer_params, destination);
166  }
167  else {
168  /* RGB, RGBA and vector passes. */
169  DCHECK(destination.num_components == 3 || destination.num_components == 4)
170  << pass_type_as_string(type) << " pass must have 3 or 4 components";
171 
173  /* Denoised matte with shadow needs to do calculation (will use denoised shadow catcher pass
174  * to approximate shadow with). */
175  get_pass_shadow_catcher_matte_with_shadow(render_buffers, buffer_params, destination);
176  }
177  else if (type == PASS_SHADOW_CATCHER && mode != PassMode::DENOISED) {
178  /* Shadow catcher pass. */
179  get_pass_shadow_catcher(render_buffers, buffer_params, destination);
180  }
181  else if ((pass_info.divide_type != PASS_NONE || pass_info.direct_type != PASS_NONE ||
182  pass_info.indirect_type != PASS_NONE) &&
183  mode != PassMode::DENOISED) {
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. */
198  num_written_components = destination.num_components;
199  }
200  }
201  else if (pass_info.num_components == 4) {
202  if (destination.num_components == 3) {
203  /* Special case for denoiser access of RGBA passes ignoring alpha channel. */
204  get_pass_float3(render_buffers, buffer_params, destination);
205  }
206  else if (type == PASS_COMBINED || type == PASS_SHADOW_CATCHER ||
208  /* Passes with transparency as 4th component. */
209  get_pass_combined(render_buffers, buffer_params, destination);
210  }
211  else {
212  /* Passes with alpha as 4th component. */
213  get_pass_float4(render_buffers, buffer_params, destination);
214  }
215  }
216  }
217  }
218 
219  pad_pixels(buffer_params, destination, num_written_components);
220 
221  return true;
222 }
223 
225  const BufferParams &buffer_params,
226  const Destination &destination) const
227 {
228  const PassMode mode = pass_access_info_.mode;
229  const PassInfo &pass_info = Pass::get_info(
231 
232  kfilm_convert->pass_offset = pass_access_info_.offset;
233  kfilm_convert->pass_stride = buffer_params.pass_stride;
234 
235  kfilm_convert->pass_use_exposure = pass_info.use_exposure;
236  kfilm_convert->pass_use_filter = pass_info.use_filter;
237 
238  /* TODO(sergey): Some of the passes needs to become denoised when denoised pass is accessed. */
239  if (pass_info.direct_type != PASS_NONE) {
240  kfilm_convert->pass_offset = buffer_params.get_pass_offset(pass_info.direct_type);
241  }
242  kfilm_convert->pass_indirect = buffer_params.get_pass_offset(pass_info.indirect_type);
243  kfilm_convert->pass_divide = buffer_params.get_pass_offset(pass_info.divide_type);
244 
245  kfilm_convert->pass_combined = buffer_params.get_pass_offset(PASS_COMBINED);
246  kfilm_convert->pass_sample_count = buffer_params.get_pass_offset(PASS_SAMPLE_COUNT);
247  kfilm_convert->pass_adaptive_aux_buffer = buffer_params.get_pass_offset(
249  kfilm_convert->pass_motion_weight = buffer_params.get_pass_offset(PASS_MOTION_WEIGHT);
250  kfilm_convert->pass_shadow_catcher = buffer_params.get_pass_offset(PASS_SHADOW_CATCHER, mode);
251  kfilm_convert->pass_shadow_catcher_sample_count = buffer_params.get_pass_offset(
253  kfilm_convert->pass_shadow_catcher_matte = buffer_params.get_pass_offset(
255 
256  /* Background is not denoised, so always use noisy pass. */
257  kfilm_convert->pass_background = buffer_params.get_pass_offset(PASS_BACKGROUND);
258 
259  if (pass_info.use_filter) {
260  kfilm_convert->scale = num_samples_ != 0 ? 1.0f / num_samples_ : 0.0f;
261  }
262  else {
263  kfilm_convert->scale = 1.0f;
264  }
265 
266  if (pass_info.use_exposure) {
267  kfilm_convert->exposure = exposure_;
268  }
269  else {
270  kfilm_convert->exposure = 1.0f;
271  }
272 
273  kfilm_convert->scale_exposure = kfilm_convert->scale * kfilm_convert->exposure;
274 
279 
280  kfilm_convert->num_components = destination.num_components;
281  kfilm_convert->pixel_stride = destination.pixel_stride ? destination.pixel_stride :
282  destination.num_components;
283 
284  kfilm_convert->is_denoised = (mode == PassMode::DENOISED);
285 }
286 
287 bool PassAccessor::set_render_tile_pixels(RenderBuffers *render_buffers, const Source &source)
288 {
289  if (render_buffers == nullptr || render_buffers->buffer.data() == nullptr) {
290  return false;
291  }
292 
293  const PassInfo pass_info = Pass::get_info(
295 
296  const BufferParams &buffer_params = render_buffers->params;
297 
298  float *buffer_data = render_buffers->buffer.data();
299  const int size = buffer_params.width * buffer_params.height;
300 
301  const int out_stride = buffer_params.pass_stride;
302  const int in_stride = source.num_components;
303  const int num_components_to_copy = min(source.num_components, pass_info.num_components);
304 
305  float *out = buffer_data + pass_access_info_.offset;
306  const float *in = source.pixels + source.offset * in_stride;
307 
308  for (int i = 0; i < size; i++, out += out_stride, in += in_stride) {
309  memcpy(out, in, sizeof(float) * num_components_to_copy);
310  }
311 
312  return true;
313 }
314 
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
int pass_stride
Definition: buffers.h:93
int height
Definition: buffers.h:72
int get_pass_offset(PassType type, PassMode mode=PassMode::NOISY) const
Definition: buffers.cpp:168
NODE_DECLARE int width
Definition: buffers.h:71
const float * pixels
Definition: pass_accessor.h:89
bool set_render_tile_pixels(RenderBuffers *render_buffers, const Source &source)
PassAccessor(const PassAccessInfo &pass_access_info, float exposure, int num_samples)
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:136
device_vector< float > buffer
Definition: buffers.h:159
BufferParams params
Definition: buffers.h:156
Definition: half.h:41
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
ccl_device_inline half float_to_half_display(const float f)
Definition: half.h:139
ccl_gpu_kernel_postfix ccl_global float int int int int int int int int int int int int num_components
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
ccl_gpu_kernel_postfix ccl_global float int int int int ccl_global const float int int int int int int int int int int int int num_samples
PassType
Definition: kernel/types.h:334
@ PASS_SHADOW_CATCHER_SAMPLE_COUNT
Definition: kernel/types.h:393
@ PASS_BACKGROUND
Definition: kernel/types.h:340
@ PASS_TRANSMISSION_COLOR
Definition: kernel/types.h:374
@ PASS_SHADOW_CATCHER_MATTE
Definition: kernel/types.h:394
@ PASS_DEPTH
Definition: kernel/types.h:358
@ PASS_MIST
Definition: kernel/types.h:376
@ PASS_SHADOW_CATCHER
Definition: kernel/types.h:392
@ PASS_MOTION
Definition: kernel/types.h:365
@ PASS_COMBINED
Definition: kernel/types.h:338
@ PASS_ADAPTIVE_AUX_BUFFER
Definition: kernel/types.h:370
@ PASS_NONE
Definition: kernel/types.h:335
@ PASS_CRYPTOMATTE
Definition: kernel/types.h:367
@ PASS_DIFFUSE_COLOR
Definition: kernel/types.h:372
@ PASS_SAMPLE_COUNT
Definition: kernel/types.h:371
@ PASS_MOTION_WEIGHT
Definition: kernel/types.h:366
@ PASS_GLOSSY_COLOR
Definition: kernel/types.h:373
#define DCHECK(expression)
Definition: log.h:55
#define DCHECK_EQ(a, b)
Definition: log.h:64
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
CCL_NAMESPACE_BEGIN const char * pass_type_as_string(const PassType type)
Definition: pass.cpp:11
PassMode
Definition: pass.h:19
static void pad_pixels(const BufferParams &buffer_params, const PassAccessor::Destination &destination, const int src_num_components)
#define min(a, b)
Definition: sort.c:35
int use_approximate_shadow_catcher_background
int use_approximate_shadow_catcher
int pass_shadow_catcher_sample_count
Definition: pass.h:26
PassType direct_type
Definition: pass.h:32
int num_components
Definition: pass.h:27
bool use_filter
Definition: pass.h:28
PassType divide_type
Definition: pass.h:31
bool use_exposure
Definition: pass.h:29
PassType indirect_type
Definition: pass.h:33
Definition: half.h:64
half x
Definition: half.h:65
half w
Definition: half.h:65
half z
Definition: half.h:65
half y
Definition: half.h:65