39void Film::init_aovs(
const Set<std::string> &passes_used_by_viewport_compositor)
41 Vector<ViewLayerAOV *> aovs;
47 if (inst_.is_viewport()) {
62 if (inst_.is_viewport_compositor_enabled) {
69 if (passes_used_by_viewport_compositor.
contains(aov->
name)) {
83 inst_.info_append_i18n(
"Error: Too many AOVs");
95 if (!aovs.is_empty()) {
104 if (pass_tx ==
nullptr) {
116 Texture &accum_tx = is_value ? value_accum_tx_ : color_accum_tx_;
124 for (
uint4 candidate_hash : aovs_hash) {
125 if (candidate_hash.x ==
hash) {
132 if (aov_index == -1) {
138 int index = aov_index + (is_value ? data_.aov_value_id : data_.aov_color_id);
148void Film::sync_mist()
169 data_.
mist_bias = -mist_start / mist_distance;
204#define ENABLE_FROM_LEGACY(name_legacy, name_eevee) \
205 SET_FLAG_FROM_TEST(result, \
206 (view_layer->passflag & SCE_PASS_##name_legacy) != 0, \
207 EEVEE_RENDER_PASS_##name_eevee);
224#undef ENABLE_FROM_LEGACY
252 if (pass_type == 0) {
257 if (viewport_compositor_needed_passes.
contains(pass_name)) {
258 viewport_compositor_enabled_passes |= pass_type;
263 return viewport_compositor_enabled_passes;
268 using namespace math;
270 Sampling &sampling = inst_.sampling;
271 Scene &scene = *inst_.scene;
273 if (inst_.is_viewport()) {
280 inst_.sampling.reset();
288 if (inst_.is_viewport_compositor_enabled) {
291 passes_used_by_viewport_compositor, inst_.view_layer);
295 init_aovs(passes_used_by_viewport_compositor);
299 if (inst_.is_viewport()) {
302 inst_.v3d->shading.render_pass) |
303 viewport_compositor_enabled_passes_;
305 if (inst_.overlays_enabled() || inst_.gpencil_engine_enabled()) {
312 inst_.sampling.reset();
329 data_.scaling_factor = 1;
330 if (inst_.is_viewport()) {
334 data_.texture_lod_bias = 1.0f / (data_.scaling_factor * 1.5f);
340 output_rect = &fallback_rect;
343 display_extent = extent;
346 data_.offset =
int2(output_rect->
xmin, output_rect->
ymin);
347 data_.extent_inv = 1.0f /
float2(data_.extent);
348 data_.render_extent =
divide_ceil(data_.extent,
int2(data_.scaling_factor));
350 data_.render_extent += data_.overscan * 2;
354 if (!is_valid_render_extent_) {
355 inst_.info_append_i18n(
356 "Required render size ({}px) is larger than reported texture size limit ({}px).",
357 max_ii(data_.render_extent.x, data_.render_extent.y),
360 data_.extent =
int2(4, 4);
361 data_.render_extent =
int2(4, 4);
362 data_.extent_inv = 1.0f /
float2(data_.extent);
363 data_.offset =
int2(0, 0);
370 data_.filter_radius = 0.0f;
372 if (data_.scaling_factor > 1) {
376 data_.filter_radius =
math::max(data_.filter_radius, 0.0001f);
379 data_.cryptomatte_samples_len = inst_.view_layer->cryptomatte_levels;
382 if (inst_.is_viewport() &&
false ) {
383 data_.background_opacity = inst_.v3d->shading.studiolight_background;
402 if (enabled_passes_ & data_passes) {
405 if (enabled_passes_ & color_passes_1) {
408 if (enabled_passes_ & color_passes_2) {
411 if (enabled_passes_ & color_passes_3) {
432 int index = (enabled_passes_ & pass_type) ?
435 if (inst_.is_viewport() && inst_.v3d->shading.render_pass == pass_type) {
436 data_.display_id = index;
437 data_.display_storage_type = storage_type;
457 data_.aov_color_id = data_.color_len;
458 data_.aov_value_id = data_.value_len;
460 data_.aov_color_len =
aovs_info.color_len;
461 data_.aov_value_len =
aovs_info.value_len;
463 data_.color_len += data_.aov_color_len;
464 data_.value_len += data_.aov_value_len;
466 int cryptomatte_id = 0;
469 if (enabled_passes_ & pass_type) {
470 index = cryptomatte_id;
471 cryptomatte_id +=
divide_ceil_u(data_.cryptomatte_samples_len, 2u);
473 if (inst_.is_viewport() && inst_.v3d->shading.render_pass == pass_type) {
474 data_.display_id = index;
484 if ((enabled_passes_ &
492 int2 weight_extent = (inst_.camera.is_panoramic() || (data_.scaling_factor > 1)) ?
503 reset += depth_tx_.ensure_2d(depth_format, data_.extent);
504 reset += combined_tx_.current().ensure_2d(color_format, data_.extent);
505 reset += combined_tx_.next().ensure_2d(color_format, data_.extent);
507 reset += weight_tx_.current().ensure_2d_array(weight_format, weight_extent, 2);
508 reset += weight_tx_.next().ensure_2d_array(weight_format, weight_extent, 2);
509 reset += color_accum_tx_.ensure_2d_array(color_format,
510 (data_.color_len > 0) ? data_.extent :
int2(1),
511 (data_.color_len > 0) ? data_.color_len : 1);
512 reset += value_accum_tx_.ensure_2d_array(float_format,
513 (data_.value_len > 0) ? data_.extent :
int2(1),
514 (data_.value_len > 0) ? data_.value_len : 1);
518 reset += cryptomatte_tx_.ensure_2d_array(cryptomatte_format,
519 (cryptomatte_array_len > 0) ? data_.extent :
int2(1),
520 (cryptomatte_array_len > 0) ? cryptomatte_array_len :
524 data_.use_history = 0;
525 use_reprojection_ =
false;
528 color_accum_tx_.clear(
float4(0.0f));
529 value_accum_tx_.clear(
float4(0.0f));
530 combined_tx_.current().clear(
float4(0.0f));
531 weight_tx_.current().clear(
float4(0.0f));
532 depth_tx_.clear(
float4(0.0f));
533 cryptomatte_tx_.clear(
float4(0.0f));
545 use_compute_ = !inst_.is_viewport() ||
552 gpu::Shader *sh = inst_.shaders.static_shader_get(shader);
553 accumulate_ps_.
init();
554 init_pass(accumulate_ps_, sh);
565 if (use_compute_ && inst_.is_viewport()) {
566 init_pass(copy_ps_, inst_.shaders.static_shader_get(
FILM_COPY));
571 const bool is_cryptomatte_pass_enabled = cryptomatte_layer_count > 0;
572 const bool do_cryptomatte_sorting = !inst_.is_viewport() || inst_.is_viewport_compositor_enabled;
573 cryptomatte_post_ps_.init();
574 if (is_cryptomatte_pass_enabled && do_cryptomatte_sorting) {
577 cryptomatte_post_ps_.bind_image(
"cryptomatte_img", &cryptomatte_tx_);
578 cryptomatte_post_ps_.bind_resources(inst_.uniform_data);
579 cryptomatte_post_ps_.push_constant(
"cryptomatte_layer_len", cryptomatte_layer_count);
580 cryptomatte_post_ps_.push_constant(
"cryptomatte_samples_per_layer",
581 inst_.view_layer->cryptomatte_levels);
584 cryptomatte_post_ps_.dispatch(
int3(
UNPACK2(dispatch_size), 1));
592 VelocityModule &velocity = inst_.
velocity;
610 pass.
bind_ubo(
"camera_next", &(*velocity.camera_steps[step_next]));
614 pass.
bind_texture(
"rp_color_tx", &rbuffers.rp_color_tx);
615 pass.
bind_texture(
"rp_value_tx", &rbuffers.rp_value_tx);
616 pass.
bind_texture(
"cryptomatte_tx", &rbuffers.cryptomatte_tx);
620 pass.
bind_image(
"in_weight_img", &weight_tx_.current());
621 pass.
bind_image(
"out_weight_img", &weight_tx_.next());
623 pass.
bind_image(
"out_combined_img", &combined_tx_.next());
625 pass.
bind_image(
"color_accum_img", &color_accum_tx_);
626 pass.
bind_image(
"value_accum_img", &value_accum_tx_);
627 pass.
bind_image(
"cryptomatte_img", &cryptomatte_tx_);
633 use_reprojection_ = inst_.sampling.interactive_mode();
636 if (inst_.is_viewport() && !use_reprojection_ && inst_.sampling.is_reset()) {
637 use_reprojection_ =
false;
638 data_.use_history =
false;
648 update_sample_table();
650 inst_.manager->warm_shader_specialization(accumulate_ps_);
651 inst_.manager->warm_shader_specialization(copy_ps_);
652 inst_.manager->warm_shader_specialization(cryptomatte_post_ps_);
666 const float bias = 0.5f;
674 if (data_.scaling_factor > 1) {
679 const int scale = data_.scaling_factor;
683 int prime = (render_pixel_per_final_pixel / 2) - 1;
685 uint64_t index = (inst_.sampling.sample_index() * prime) % render_pixel_per_final_pixel;
690 jitter += ((
float2(pixel_co) + 0.5f) /
scale) - 0.5f;
697 if (inst_.is_viewport() && use_reprojection_) {
701 return enabled_passes_;
707 result += data_.cryptomatte_object_id == -1 ? 0 : 1;
708 result += data_.cryptomatte_asset_id == -1 ? 0 : 1;
709 result += data_.cryptomatte_material_id == -1 ? 0 : 1;
713void Film::update_sample_table()
733 for (
int y = 0;
y <= 1;
y++) {
734 for (
int x = 0;
x <= 1;
x++) {
741 data_.samples_weight_total = -1.0f;
745 data_.samples[0].texel =
int2(0, 0);
746 data_.samples[0].weight = 1.0f;
747 data_.samples_weight_total = 1.0f;
748 data_.samples_len = 1;
751 else if (data_.filter_radius < 2.20f) {
753 int closest_index = 0;
754 float closest_distance =
FLT_MAX;
755 data_.samples_weight_total = 0.0f;
757 for (
int y = -filter_radius_ceil;
y <= filter_radius_ceil;
y++) {
758 for (
int x = -filter_radius_ceil;
x <= filter_radius_ceil;
x++) {
761 if (distance_sqr < filter_radius_sqr) {
766 FilmSample &
sample = data_.samples[data_.samples_len];
769 data_.samples_weight_total +=
sample.weight;
771 if (distance_sqr < closest_distance) {
772 closest_distance = distance_sqr;
773 closest_index = data_.samples_len;
780 if (closest_index != 0) {
781 std::swap(data_.samples[closest_index], data_.samples[0]);
785 if (data_.samples_len <= 9) {
786 data_.samples_len = 9;
795 data_.samples_len = sample_table.size();
796 data_.samples_weight_total = 0.0f;
799 for (FilmSample &
sample : sample_table) {
811 data_.samples_weight_total +=
sample.weight;
818 if (data_.samples_len == 1) {
819 data_.samples_len = 1;
821 else if (data_.samples_len <= 4) {
822 data_.samples_len = 4;
824 else if (data_.samples_len <= 9) {
825 data_.samples_len = 9;
827 else if (data_.samples_len <= 16) {
828 data_.samples_len = 16;
837 if (inst_.is_viewport()) {
843 float4 clear_color = {0.0f, 0.0f, 0.0f, 0.0f};
849 update_sample_table();
851 combined_final_tx_ = combined_final_tx;
853 data_.display_only =
false;
854 inst_.uniform_data.push_update();
856 inst_.manager->submit(accumulate_ps_,
view);
857 inst_.manager->submit(copy_ps_,
view);
863 if (data_.use_history == 0) {
864 data_.use_history = 1;
873 inst_.render_buffers.acquire(
int2(1));
879 combined_final_tx_ = inst_.render_buffers.combined_tx;
881 data_.display_only =
true;
882 inst_.uniform_data.push_update();
888 inst_.render_buffers.release();
924 combined_tx_.current() :
927 (is_cryptomatte ? cryptomatte_tx_ :
928 (is_value ? value_accum_tx_ : color_accum_tx_));
936 return accum_tx.
layer_view(index + layer_offset);
984 viewport_compositor_enabled_passes_ & (1 <<
i));
985 if (pass_type == 0) {
1009 const char *pass_name = pass_names[pass_offset].c_str();
1013 PassSimple write_pass_ps = {
"Film.WriteViewportCompositorPass"};
1015 write_pass_ps.
shader_set(inst_.shaders.static_shader_get(write_shader_type));
1018 write_pass_ps.
bind_image(
"output_img", output_pass_texture);
1021 inst_.manager->submit(write_pass_ps);
1031 if (!pass_texture) {
1039 PassSimple write_pass_ps = {
"Film.WriteViewportCompositorPass"};
1041 write_pass_ps.
shader_set(inst_.shaders.static_shader_get(write_shader_type));
1044 write_pass_ps.
bind_image(
"output_img", output_pass_texture);
1047 inst_.manager->submit(write_pass_ps);
int BKE_render_preview_pixel_size(const RenderData *r)
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
BLI_INLINE unsigned int BLI_hash_string(const char *str)
#define LISTBASE_FOREACH(type, var, list)
void * BLI_findstring(const ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE uint divide_ceil_u(uint a, uint b)
MINLINE float pow2f(float x)
MINLINE float clamp_f(float value, float min, float max)
MINLINE int square_i(int a)
MINLINE int max_ii(int a, int b)
MINLINE float square_f(float a)
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
bool BLI_rcti_is_empty(const struct rcti *rect)
#define SET_FLAG_FROM_TEST(value, test, flag)
@ VIEW_LAYER_CRYPTOMATTE_MATERIAL
@ VIEW_LAYER_CRYPTOMATTE_ASSET
@ VIEW_LAYER_CRYPTOMATTE_OBJECT
#define EEVEE_RENDER_PASS_MAX_BIT
@ EEVEE_RENDER_PASS_UNUSED_8
@ EEVEE_RENDER_PASS_CRYPTOMATTE_MATERIAL
@ EEVEE_RENDER_PASS_NORMAL
@ EEVEE_RENDER_PASS_UNUSED_14
@ EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT
@ EEVEE_RENDER_PASS_DIFFUSE_LIGHT
@ EEVEE_RENDER_PASS_VOLUME_LIGHT
@ EEVEE_RENDER_PASS_DIFFUSE_COLOR
@ EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET
@ EEVEE_RENDER_PASS_ENVIRONMENT
@ EEVEE_RENDER_PASS_COMBINED
@ EEVEE_RENDER_PASS_SPECULAR_LIGHT
@ EEVEE_RENDER_PASS_VECTOR
@ EEVEE_RENDER_PASS_SPECULAR_COLOR
@ EEVEE_RENDER_PASS_DEPTH
@ EEVEE_RENDER_PASS_TRANSPARENT
@ EEVEE_RENDER_PASS_SHADOW
@ EEVEE_RENDER_PASS_POSITION
struct ViewLayerAOV ViewLayerAOV
@ WO_MIST_INVERSE_QUADRATIC
int GPU_max_texture_size()
void GPU_framebuffer_viewport_set(blender::gpu::FrameBuffer *fb, int x, int y, int width, int height)
void GPU_framebuffer_clear_color(blender::gpu::FrameBuffer *fb, const float clear_col[4])
void GPU_framebuffer_bind(blender::gpu::FrameBuffer *fb)
@ GPU_BARRIER_TEXTURE_FETCH
@ GPU_BARRIER_SHADER_IMAGE_ACCESS
@ GPU_BARRIER_TEXTURE_UPDATE
void GPU_memory_barrier(GPUBarrier barrier)
int GPU_texture_height(const blender::gpu::Texture *texture)
blender::gpu::TextureFormat GPU_texture_format(const blender::gpu::Texture *texture)
int GPU_texture_width(const blender::gpu::Texture *texture)
void * GPU_texture_read(blender::gpu::Texture *texture, eGPUDataFormat data_format, int mip_level)
@ GPU_SAMPLER_FILTERING_LINEAR
unsigned long long int uint64_t
void reset()
clear internal cached data and reset random seed
bool contains(const Key &key) const
void append(const T &value)
const T & last(const int64_t n=0) const
bool contains(const Key &key) const
void submit(PassSimple &pass, View &view)
void acquire(int2 extent, blender::gpu::TextureFormat format, eGPUTextureUsage usage=GPU_TEXTURE_USAGE_GENERAL)
bool ensure_layer_views(bool cube_as_array=false)
gpu::Texture * layer_view(int layer)
static View & default_get()
void bind_resources(U &resources)
void shader_set(gpu::Shader *shader)
void bind_texture(const char *name, gpu::Texture *texture, GPUSamplerState state=sampler_auto)
void specialize_constant(gpu::Shader *shader, const char *name, const float &data)
void bind_image(const char *name, gpu::Texture *image)
void dispatch(int group_len)
void state_set(DRWState state, int clip_plane_count=0)
void barrier(GPUBarrier type)
void bind_ubo(const char *name, gpu::UniformBuf *buffer)
void push_constant(const char *name, const float &data)
const CameraData & data_get() const
float2 pixel_jitter_get() const
int pass_id_get(eViewLayerEEVEEPassType pass_type) const
static bool pass_is_float3(eViewLayerEEVEEPassType pass_type)
gpu::Texture * get_pass_texture(eViewLayerEEVEEPassType pass_type, int layer_offset)
struct blender::eevee::Film::DepthState depth
static const Vector< std::string > pass_to_render_pass_names(eViewLayerEEVEEPassType pass_type, const ViewLayer *view_layer)
int cryptomatte_layer_len_get() const
static ePassStorageType pass_storage_type(eViewLayerEEVEEPassType pass_type)
float * read_pass(eViewLayerEEVEEPassType pass_type, int layer_offset)
void write_viewport_compositor_passes()
static int overscan_pixels_get(float overscan, int2 extent)
void accumulate(View &view, gpu::Texture *combined_final_tx)
void init(const int2 &full_extent, const rcti *output_rect)
float * read_aov(ViewLayerAOV *aov)
StorageBuffer< AOVsInfoData > aovs_info
eViewLayerEEVEEPassType enabled_passes_get() const
static constexpr bool use_box_filter
gpu::Texture * get_aov_texture(ViewLayerAOV *aov)
RenderBuffers render_buffers
UniformDataModule uniform_data
static float2 sample_disk(const float2 &rand)
uint64_t sample_count() const
static float2 sample_spiral(const float2 &rand)
virtual void init(const shader::ShaderCreateInfo &info, bool is_batch_compilation)=0
blender::draw::TextureFromPool & DRW_viewport_pass_texture_get(const char *pass_name)
blender::draw::Manager * DRW_manager_get()
@ DRW_STATE_DEPTH_GREATER_EQUAL
#define ENABLE_FROM_LEGACY(name_legacy, name_eevee)
#define FILM_PRECOMP_SAMPLE_MAX
Set< std::string > get_used_passes(const Scene &scene, const ViewLayer *view_layer)
detail::Pass< command::DrawCommandBuf > PassSimple
@ FILM_PASS_CONVERT_COMBINED
@ FILM_PASS_CONVERT_CRYPTOMATTE
@ FILM_PASS_CONVERT_COLOR
@ FILM_PASS_CONVERT_VALUE
@ FILM_PASS_CONVERT_DEPTH
static eShaderType get_write_pass_shader_type(eViewLayerEEVEEPassType pass_type)
static float film_filter_weight(float filter_radius, float sample_distance_sqr)
bool operator!=(const CameraData &a, const CameraData &b)
static eShaderType get_aov_write_pass_shader_type(const ViewLayerAOV *aov)
static eViewLayerEEVEEPassType enabled_passes(const ViewLayer *view_layer)
bool operator==(const CameraData &a, const CameraData &b)
static eViewLayerEEVEEPassType get_viewport_compositor_enabled_passes(const Set< std::string > &viewport_compositor_needed_passes, const ViewLayer *view_layer)
@ PASS_STORAGE_CRYPTOMATTE
@ PASS_CATEGORY_CRYPTOMATTE
T length_squared(const VecBase< T, Size > &a)
MatBase< T, NumCol, NumRow > scale(const MatBase< T, NumCol, NumRow > &mat, const VectorT &scale)
VecBase< T, Size > divide_ceil(const VecBase< T, Size > &a, const VecBase< T, Size > &b)
T max(const T &a, const T &b)
VecBase< uint32_t, 4 > uint4
bool assign_if_different(T &old_value, T new_value)
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
VecBase< int32_t, 3 > int3
VecBase< float, 3 > float3
static void update(bNodeTree *ntree)
blender::gpu::FrameBuffer * default_fb
blender::gpu::Texture * color
ColorManagedViewSettings view_settings
struct ViewLayerEEVEE eevee
FilmSample samples[FILM_PRECOMP_SAMPLE_MAX]