diff options
Diffstat (limited to 'source/blender/draw/engines/eevee_next/eevee_film.hh')
-rw-r--r-- | source/blender/draw/engines/eevee_next/eevee_film.hh | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/source/blender/draw/engines/eevee_next/eevee_film.hh b/source/blender/draw/engines/eevee_next/eevee_film.hh new file mode 100644 index 00000000000..1165b9a4c12 --- /dev/null +++ b/source/blender/draw/engines/eevee_next/eevee_film.hh @@ -0,0 +1,220 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2021 Blender Foundation. + */ + +/** \file + * \ingroup eevee + * + * The film class handles accumulation of samples with any distorted camera_type + * using a pixel filter. Inputs needs to be jittered so that the filter converges to the right + * result. + * + * In viewport, we switch between 2 accumulation mode depending on the scene state. + * - For static scene, we use a classic weighted accumulation. + * - For dynamic scene (if an update is detected), we use a more temporally stable accumulation + * following the Temporal Anti-Aliasing method (a.k.a. Temporal Super-Sampling). This does + * history reprojection and rectification to avoid most of the flickering. + */ + +#pragma once + +#include "DRW_render.h" + +#include "eevee_shader_shared.hh" + +namespace blender::eevee { + +class Instance; + +/* -------------------------------------------------------------------- */ +/** \name Film + * \{ */ + +class Film { + public: + /** Stores indirection table of AOVs based on their name hash and their type. */ + AOVsInfoDataBuf aovs_info; + /** For debugging purpose but could be a user option in the future. */ + static constexpr bool use_box_filter = false; + + private: + Instance &inst_; + + /** Main accumulation textures containing every render-pass except depth and combined. */ + Texture color_accum_tx_; + Texture value_accum_tx_; + /** Depth accumulation texture. Separated because using a different format. */ + Texture depth_tx_; + /** Combined "Color" buffer. Double buffered to allow re-projection. */ + SwapChain<Texture, 2> combined_tx_; + /** Static reference as SwapChain does not actually move the objects when swapping. */ + GPUTexture *combined_src_tx_ = nullptr; + GPUTexture *combined_dst_tx_ = nullptr; + /** Weight buffers. Double buffered to allow updating it during accumulation. */ + SwapChain<Texture, 2> weight_tx_; + /** Static reference as SwapChain does not actually move the objects when swapping. */ + GPUTexture *weight_src_tx_ = nullptr; + GPUTexture *weight_dst_tx_ = nullptr; + /** User setting to disable reprojection. Useful for debugging or have a more precise render. */ + bool force_disable_reprojection_ = false; + + DRWPass *accumulate_ps_ = nullptr; + + FilmDataBuf data_; + + eViewLayerEEVEEPassType enabled_passes_ = eViewLayerEEVEEPassType(0); + + public: + Film(Instance &inst) : inst_(inst){}; + ~Film(){}; + + void init(const int2 &full_extent, const rcti *output_rect); + + void sync(); + void end_sync(); + + /** Accumulate the newly rendered sample contained in #RenderBuffers and blit to display. */ + void accumulate(const DRWView *view); + + /** Blit to display. No rendered sample needed. */ + void display(); + + float *read_pass(eViewLayerEEVEEPassType pass_type); + float *read_aov(ViewLayerAOV *aov); + + int2 render_extent_get() const + { + return data_.render_extent; + } + + float2 pixel_jitter_get() const; + + float background_opacity_get() const + { + return data_.background_opacity; + } + + eViewLayerEEVEEPassType enabled_passes_get() const; + + static bool pass_is_value(eViewLayerEEVEEPassType pass_type) + { + switch (pass_type) { + case EEVEE_RENDER_PASS_Z: + case EEVEE_RENDER_PASS_MIST: + case EEVEE_RENDER_PASS_SHADOW: + case EEVEE_RENDER_PASS_AO: + return true; + default: + return false; + } + } + + static bool pass_is_float3(eViewLayerEEVEEPassType pass_type) + { + switch (pass_type) { + case EEVEE_RENDER_PASS_NORMAL: + case EEVEE_RENDER_PASS_DIFFUSE_LIGHT: + case EEVEE_RENDER_PASS_DIFFUSE_COLOR: + case EEVEE_RENDER_PASS_SPECULAR_LIGHT: + case EEVEE_RENDER_PASS_SPECULAR_COLOR: + case EEVEE_RENDER_PASS_VOLUME_LIGHT: + case EEVEE_RENDER_PASS_EMIT: + case EEVEE_RENDER_PASS_ENVIRONMENT: + return true; + default: + return false; + } + } + + /* Returns layer offset in the accumulation texture. -1 if the pass is not enabled. */ + int pass_id_get(eViewLayerEEVEEPassType pass_type) const + { + switch (pass_type) { + case EEVEE_RENDER_PASS_COMBINED: + return data_.combined_id; + case EEVEE_RENDER_PASS_Z: + return data_.depth_id; + case EEVEE_RENDER_PASS_MIST: + return data_.mist_id; + case EEVEE_RENDER_PASS_NORMAL: + return data_.normal_id; + case EEVEE_RENDER_PASS_DIFFUSE_LIGHT: + return data_.diffuse_light_id; + case EEVEE_RENDER_PASS_DIFFUSE_COLOR: + return data_.diffuse_color_id; + case EEVEE_RENDER_PASS_SPECULAR_LIGHT: + return data_.specular_light_id; + case EEVEE_RENDER_PASS_SPECULAR_COLOR: + return data_.specular_color_id; + case EEVEE_RENDER_PASS_VOLUME_LIGHT: + return data_.volume_light_id; + case EEVEE_RENDER_PASS_EMIT: + return data_.emission_id; + case EEVEE_RENDER_PASS_ENVIRONMENT: + return data_.environment_id; + case EEVEE_RENDER_PASS_SHADOW: + return data_.shadow_id; + case EEVEE_RENDER_PASS_AO: + return data_.ambient_occlusion_id; + case EEVEE_RENDER_PASS_CRYPTOMATTE: + return -1; /* TODO */ + case EEVEE_RENDER_PASS_VECTOR: + return data_.vector_id; + default: + return -1; + } + } + + static const char *pass_to_render_pass_name(eViewLayerEEVEEPassType pass_type) + { + switch (pass_type) { + case EEVEE_RENDER_PASS_COMBINED: + return RE_PASSNAME_COMBINED; + case EEVEE_RENDER_PASS_Z: + return RE_PASSNAME_Z; + case EEVEE_RENDER_PASS_MIST: + return RE_PASSNAME_MIST; + case EEVEE_RENDER_PASS_NORMAL: + return RE_PASSNAME_NORMAL; + case EEVEE_RENDER_PASS_DIFFUSE_LIGHT: + return RE_PASSNAME_DIFFUSE_DIRECT; + case EEVEE_RENDER_PASS_DIFFUSE_COLOR: + return RE_PASSNAME_DIFFUSE_COLOR; + case EEVEE_RENDER_PASS_SPECULAR_LIGHT: + return RE_PASSNAME_GLOSSY_DIRECT; + case EEVEE_RENDER_PASS_SPECULAR_COLOR: + return RE_PASSNAME_GLOSSY_COLOR; + case EEVEE_RENDER_PASS_VOLUME_LIGHT: + return RE_PASSNAME_VOLUME_LIGHT; + case EEVEE_RENDER_PASS_EMIT: + return RE_PASSNAME_EMIT; + case EEVEE_RENDER_PASS_ENVIRONMENT: + return RE_PASSNAME_ENVIRONMENT; + case EEVEE_RENDER_PASS_SHADOW: + return RE_PASSNAME_SHADOW; + case EEVEE_RENDER_PASS_AO: + return RE_PASSNAME_AO; + case EEVEE_RENDER_PASS_CRYPTOMATTE: + BLI_assert_msg(0, "Cryptomatte is not implemented yet."); + return ""; /* TODO */ + case EEVEE_RENDER_PASS_VECTOR: + return RE_PASSNAME_VECTOR; + default: + BLI_assert(0); + return ""; + } + } + + private: + void init_aovs(); + void sync_mist(); + + /** + * Precompute sample weights if they are uniform across the whole film extent. + */ + void update_sample_table(); +}; + +/** \} */ + +} // namespace blender::eevee |