EEVEE: Overscan/Border mixed resolution rendering
Mixed resolution rendering had some issues with overscan and border rendering. - `render_offset` was in display space and not in render space. Is now replaced by the `overscan_extent`. - `overscan_extent` introduced that stored the overscan of the render extent. - Fixed issues to determine the film sample weight when `scaling_factor` was used. It didn't match decompose the actual offset making the length of the same to large, what blurred the final samples. NOTE: there are some other issues related to border rendering which was already in main before mixed resolution rendering was added. I assume that viewport render image in camera view still adds an additional offset, which should be ignored. Fixes #119510 Fixes #119511 Pull Request: https://projects.blender.org/blender/blender/pulls/119524
This commit is contained in:
parent
ebf12765a6
commit
8945b29762
@ -151,7 +151,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.render_extent == b.render_extent) && (a.overscan == b.overscan) &&
|
||||
(a.filter_radius == b.filter_radius) && (a.scaling_factor == b.scaling_factor) &&
|
||||
(a.background_opacity == b.background_opacity);
|
||||
}
|
||||
@ -265,12 +265,11 @@ void Film::init(const int2 &extent, const rcti *output_rect)
|
||||
data_.offset = int2(output_rect->xmin, output_rect->ymin);
|
||||
data_.extent_inv = 1.0f / float2(data_.extent);
|
||||
data_.render_extent = math::divide_ceil(extent, int2(data_.scaling_factor));
|
||||
data_.render_offset = data_.offset;
|
||||
data_.overscan = 0;
|
||||
|
||||
if (inst_.camera.overscan() != 0.0f) {
|
||||
int2 overscan = int2(inst_.camera.overscan() * math::max(UNPACK2(data_.render_extent)));
|
||||
data_.render_extent += overscan * 2;
|
||||
data_.render_offset += overscan;
|
||||
data_.overscan = inst_.camera.overscan() * math::max(UNPACK2(data_.render_extent));
|
||||
data_.render_extent += data_.overscan * 2;
|
||||
}
|
||||
|
||||
/* Disable filtering if sample count is 1. */
|
||||
|
@ -262,10 +262,8 @@ struct FilmData {
|
||||
int2 extent;
|
||||
/** Offset to convert from Display space to Film space, in pixels. */
|
||||
int2 offset;
|
||||
/** Size of the render buffers when rendering the main views, in pixels. */
|
||||
/** Size of the render buffers including overscan 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.
|
||||
@ -276,6 +274,11 @@ struct FilmData {
|
||||
float2 subpixel_offset;
|
||||
/** Scaling factor to convert texel to uvs. */
|
||||
float2 extent_inv;
|
||||
/**
|
||||
* Number of border pixels on all sides inside the render_extent that do not contribute to the
|
||||
* final image.
|
||||
*/
|
||||
int overscan;
|
||||
/** Is true if history is valid and can be sampled. Bypass history to resets accumulation. */
|
||||
bool32_t use_history;
|
||||
/** Controlled by user in lookdev mode or by render settings. */
|
||||
@ -328,6 +331,7 @@ struct FilmData {
|
||||
/** Sum of the weights of all samples in the sample table. */
|
||||
float samples_weight_total;
|
||||
int _pad1;
|
||||
int _pad2;
|
||||
FilmSample samples[FILM_PRECOMP_SAMPLE_MAX];
|
||||
};
|
||||
BLI_STATIC_ASSERT_ALIGN(FilmData, 16)
|
||||
|
@ -216,7 +216,7 @@ void ShadingView::update_view()
|
||||
*/
|
||||
int2 scaling_factor = int2(inst_.film.scaling_factor_get());
|
||||
int2 display_extent = inst_.film.display_extent_get();
|
||||
int2 overscan = inst_.film.get_data().render_offset - inst_.film.get_data().offset;
|
||||
int overscan = inst_.film.get_data().overscan;
|
||||
int2 rescaled_render_extent = (extent_ - 2 * overscan) * scaling_factor;
|
||||
|
||||
if (rescaled_render_extent != display_extent) {
|
||||
|
@ -55,7 +55,8 @@ FilmSample film_sample_get(int sample_n, ivec2 texel_film)
|
||||
#else
|
||||
|
||||
FilmSample film_sample = uniform_buf.film.samples[sample_n];
|
||||
film_sample.texel += (texel_film / scaling_factor) + uniform_buf.film.render_offset;
|
||||
film_sample.texel += (texel_film + uniform_buf.film.offset) / scaling_factor +
|
||||
uniform_buf.film.overscan;
|
||||
/* Use extend on borders. */
|
||||
film_sample.texel = clamp(film_sample.texel, ivec2(0, 0), uniform_buf.film.render_extent - 1);
|
||||
|
||||
@ -64,9 +65,10 @@ FilmSample film_sample_get(int sample_n, ivec2 texel_film)
|
||||
if (scaling_factor > 1) {
|
||||
/* We need to compute the real distance and weight since a sample
|
||||
* can be used by many final pixel. */
|
||||
vec2 offset = (vec2(film_sample.texel) + 0.5 - uniform_buf.film.subpixel_offset) *
|
||||
vec2 offset = (vec2(film_sample.texel - uniform_buf.film.overscan) + 0.5 -
|
||||
uniform_buf.film.subpixel_offset) *
|
||||
scaling_factor -
|
||||
(vec2(texel_film) + 0.5);
|
||||
(vec2(texel_film + uniform_buf.film.offset) + 0.5);
|
||||
film_sample.weight = film_filter_weight(uniform_buf.film.filter_radius,
|
||||
length_squared(offset));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user