From 7e33c405fb3b9d1674eb8f534642516f5f70b9ff Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Fri, 1 Sep 2023 17:15:38 +0200 Subject: [PATCH] Fix: EEVEE-Next: Render Region Fix render regions and make them work with overscan: - Clarify and improve the naming used by the Film module. - Convert Display texel coordinates to Film texel coordinates before calling `film_process_data`, and convert from Film texel coordinates to Render texel coordinates in `film_sample_get`. - Returns the actual display extent (and not the film extent) in `Film::display_extent_get` so the overscan camera matrix is computed correctly when using render regions. Regression caused by 567a2e5a6f09fd4b2dd00d0b133cfb9307869310. Pull Request: https://projects.blender.org/blender/blender/pulls/111691 --- .../draw/engines/eevee_next/eevee_film.cc | 14 ++++++++------ .../draw/engines/eevee_next/eevee_film.hh | 16 +++++++++++++--- .../engines/eevee_next/eevee_shader_shared.hh | 8 +++++--- .../eevee_next/shaders/eevee_film_frag.glsl | 2 +- .../eevee_next/shaders/eevee_film_lib.glsl | 2 +- 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/source/blender/draw/engines/eevee_next/eevee_film.cc b/source/blender/draw/engines/eevee_next/eevee_film.cc index 50a91d4a98c..0bcfc0e0038 100644 --- a/source/blender/draw/engines/eevee_next/eevee_film.cc +++ b/source/blender/draw/engines/eevee_next/eevee_film.cc @@ -5,7 +5,7 @@ /** \file * \ingroup eevee * - * A film is a full-screen buffer (usually at output extent) + * A film is a buffer (usually at display extent) * that will be able to accumulate sample in any distorted camera_type * using a pixel filter. * @@ -147,6 +147,7 @@ void Film::sync_mist() inline bool operator==(const FilmData &a, const FilmData &b) { return (a.extent == b.extent) && (a.offset == b.offset) && + (a.render_extent == b.render_extent) && (a.render_offset == b.render_offset) && (a.filter_radius == b.filter_radius) && (a.scaling_factor == b.scaling_factor) && (a.background_opacity == b.background_opacity); } @@ -248,21 +249,22 @@ void Film::init(const int2 &extent, const rcti *output_rect) output_rect = &fallback_rect; } - display_offset = int2(output_rect->xmin, output_rect->ymin); + display_extent = extent; FilmData data = data_; data.extent = int2(BLI_rcti_size_x(output_rect), BLI_rcti_size_y(output_rect)); - data.offset = display_offset; + data.offset = int2(output_rect->xmin, output_rect->ymin); data.extent_inv = 1.0f / float2(data.extent); /* TODO(fclem): parameter hidden in experimental. * We need to figure out LOD bias first in order to preserve texture crispiness. */ data.scaling_factor = 1; data.render_extent = math::divide_ceil(extent, int2(data.scaling_factor)); + data.render_offset = data.offset; if (inst_.camera.overscan() != 0.0f) { int2 overscan = int2(inst_.camera.overscan() * math::max(UNPACK2(data.render_extent))); data.render_extent += overscan * 2; - data.offset += overscan; + data.render_offset += overscan; } /* Disable filtering if sample count is 1. */ @@ -636,7 +638,7 @@ void Film::accumulate(const DRWView *view, GPUTexture *combined_final_tx) float4 clear_color = {0.0f, 0.0f, 0.0f, 0.0f}; GPU_framebuffer_clear_color(dfbl->default_fb, clear_color); } - GPU_framebuffer_viewport_set(dfbl->default_fb, UNPACK2(display_offset), UNPACK2(data_.extent)); + GPU_framebuffer_viewport_set(dfbl->default_fb, UNPACK2(data.offset), UNPACK2(data_.extent)); } update_sample_table(); @@ -668,7 +670,7 @@ void Film::display() DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); GPU_framebuffer_bind(dfbl->default_fb); - GPU_framebuffer_viewport_set(dfbl->default_fb, UNPACK2(display_offset), UNPACK2(data_.extent)); + GPU_framebuffer_viewport_set(dfbl->default_fb, UNPACK2(data.offset), UNPACK2(data_.extent)); combined_final_tx_ = inst_.render_buffers.combined_tx; diff --git a/source/blender/draw/engines/eevee_next/eevee_film.hh b/source/blender/draw/engines/eevee_next/eevee_film.hh index fe83387251d..620efcf99d0 100644 --- a/source/blender/draw/engines/eevee_next/eevee_film.hh +++ b/source/blender/draw/engines/eevee_next/eevee_film.hh @@ -14,6 +14,16 @@ * - 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. + * + * The Film module uses the following terms to refer to different spaces/extents: + * + * - Display: The full output extent (matches the full viewport or the final image resolution). + * + * - Film: The same extent as display, or a subset of it when a Render Region is used. + * + * - Render: The extent used internally by the engine for rendering the main views. + * Equals to the full display extent + overscan (even when a Render Region is used) + * and its resolution can be scaled. */ #pragma once @@ -66,7 +76,7 @@ class Film { PassSimple cryptomatte_post_ps_ = {"Film.Cryptomatte.Post"}; FilmDataBuf data_; - int2 display_offset; + int2 display_extent; eViewLayerEEVEEPassType enabled_passes_ = eViewLayerEEVEEPassType(0); @@ -97,10 +107,10 @@ class Film { return data_.render_extent; } - /** Returns render output resolution. */ + /** Returns final output resolution. */ int2 display_extent_get() const { - return data_.extent; + return display_extent; } float2 pixel_jitter_get() const; diff --git a/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh b/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh index 079d6e67f43..f2b1d13492a 100644 --- a/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh +++ b/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh @@ -229,10 +229,12 @@ BLI_STATIC_ASSERT_ALIGN(FilmSample, 16) struct FilmData { /** Size of the film in pixels. */ int2 extent; - /** Offset of the film in the full-res frame, in pixels. */ + /** Offset to convert from Display space to Film space, in pixels. */ int2 offset; - /** Extent used by the render buffers when rendering the main views. */ + /** Size of the render buffers when rendering the main views, in pixels. */ int2 render_extent; + /** Offset to convert from Film space to Render space, in pixels. */ + int2 render_offset; /** * Sub-pixel offset applied to the window matrix. * NOTE: In final film pixel unit. @@ -254,7 +256,7 @@ struct FilmData { bool1 any_render_pass_2; /** Controlled by user in lookdev mode or by render settings. */ float background_opacity; - float _pad0; + float _pad0, _pad1, _pad2; /** Output counts per type. */ int color_len, value_len; /** Index in color_accum_img or value_accum_img of each pass. -1 if pass is not enabled. */ diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_film_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_film_frag.glsl index 0d2de506287..ee244eb22f9 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_film_frag.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_film_frag.glsl @@ -7,7 +7,7 @@ void main() { - ivec2 texel_film = ivec2(gl_FragCoord.xy); + ivec2 texel_film = ivec2(gl_FragCoord.xy) - film_buf.offset; float out_depth; if (film_buf.display_only) { diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl index 60213f822e8..b080f463659 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl @@ -59,7 +59,7 @@ FilmSample film_sample_get(int sample_n, ivec2 texel_film) # endif FilmSample film_sample = film_buf.samples[sample_n]; - film_sample.texel += texel_film + film_buf.offset; + film_sample.texel += texel_film + film_buf.render_offset; /* Use extend on borders. */ film_sample.texel = clamp(film_sample.texel, ivec2(0, 0), film_buf.render_extent - 1);