EEVEE-Next: Viewport pixel size with up-scaling #118903
|
@ -1035,6 +1035,28 @@ class RENDER_PT_eevee_performance(RenderButtonsPanel, Panel):
|
|||
layout.prop(rd, "use_high_quality_normals")
|
||||
|
||||
|
||||
class RENDER_PT_eevee_performance_viewport(RenderButtonsPanel, Panel):
|
||||
bl_label = "Viewport"
|
||||
bl_parent_id = "RENDER_PT_eevee_performance"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
scene = context.scene
|
||||
rd = scene.render
|
||||
|
||||
col = layout.column()
|
||||
col.prop(rd, "preview_pixel_size", text="Pixel Size")
|
||||
|
||||
|
||||
class RENDER_PT_gpencil(RenderButtonsPanel, Panel):
|
||||
bl_label = "Grease Pencil"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
@ -1273,6 +1295,7 @@ classes = (
|
|||
RENDER_PT_eevee_next_volumes_lighting,
|
||||
RENDER_PT_eevee_next_volumes_shadows,
|
||||
RENDER_PT_eevee_performance,
|
||||
RENDER_PT_eevee_performance_viewport,
|
||||
RENDER_PT_eevee_hair,
|
||||
RENDER_PT_eevee_shadows,
|
||||
RENDER_PT_eevee_next_lights,
|
||||
|
|
|
@ -51,6 +51,7 @@ vec3 coordinate_camera(vec3 P);
|
|||
vec3 coordinate_screen(vec3 P);
|
||||
vec3 coordinate_reflect(vec3 P, vec3 N);
|
||||
vec3 coordinate_incoming(vec3 P);
|
||||
float film_scaling_factor_get();
|
||||
|
||||
/* Single BSDFs. */
|
||||
Closure closure_eval(ClosureDiffuse diffuse);
|
||||
|
|
|
@ -250,3 +250,8 @@ vec3 coordinate_incoming(vec3 P)
|
|||
return cameraVec(P);
|
||||
#endif
|
||||
}
|
||||
|
||||
float film_scaling_factor_get()
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
|
|
@ -62,6 +62,11 @@ vec3 coordinate_incoming(vec3 P)
|
|||
{
|
||||
return cameraVec(P);
|
||||
}
|
||||
|
||||
float film_scaling_factor_get()
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void main()
|
||||
|
|
|
@ -107,6 +107,11 @@ vec3 coordinate_incoming(vec3 P)
|
|||
return vec3(0.0);
|
||||
}
|
||||
|
||||
float film_scaling_factor_get()
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
float attr_load_temperature_post(float attr)
|
||||
{
|
||||
return attr;
|
||||
|
|
|
@ -241,6 +241,17 @@ void Film::init(const int2 &extent, const rcti *output_rect)
|
|||
enabled_passes_ &= ~EEVEE_RENDER_PASS_VECTOR;
|
||||
}
|
||||
}
|
||||
{
|
||||
data_.scaling_factor = 1;
|
||||
if (inst_.is_viewport()) {
|
||||
if (!bool(enabled_passes_ &
|
||||
(EEVEE_RENDER_PASS_CRYPTOMATTE_ASSET | EEVEE_RENDER_PASS_CRYPTOMATTE_MATERIAL |
|
||||
EEVEE_RENDER_PASS_CRYPTOMATTE_OBJECT | EEVEE_RENDER_PASS_NORMAL)))
|
||||
Jeroen-Bakker marked this conversation as resolved
Outdated
|
||||
{
|
||||
data_.scaling_factor = BKE_render_preview_pixel_size(&inst_.scene->r);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
rcti fallback_rect;
|
||||
if (BLI_rcti_is_empty(output_rect)) {
|
||||
|
@ -253,9 +264,6 @@ void Film::init(const int2 &extent, const rcti *output_rect)
|
|||
data_.extent = int2(BLI_rcti_size_x(output_rect), BLI_rcti_size_y(output_rect));
|
||||
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;
|
||||
|
||||
|
@ -380,7 +388,9 @@ void Film::init(const int2 &extent, const rcti *output_rect)
|
|||
}
|
||||
}
|
||||
{
|
||||
int2 weight_extent = inst_.camera.is_panoramic() ? data_.extent : int2(data_.scaling_factor);
|
||||
int2 weight_extent = (inst_.camera.is_panoramic() || (data_.scaling_factor > 1)) ?
|
||||
data_.extent :
|
||||
int2(1);
|
||||
|
||||
eGPUTextureFormat color_format = GPU_RGBA16F;
|
||||
eGPUTextureFormat float_format = GPU_R16F;
|
||||
|
@ -448,6 +458,7 @@ void Film::sync()
|
|||
accumulate_ps_.specialize_constant(sh, "enabled_categories", uint(enabled_categories_));
|
||||
accumulate_ps_.specialize_constant(sh, "samples_len", &data_.samples_len);
|
||||
accumulate_ps_.specialize_constant(sh, "use_reprojection", &use_reprojection_);
|
||||
accumulate_ps_.specialize_constant(sh, "scaling_factor", data_.scaling_factor);
|
||||
accumulate_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
|
||||
accumulate_ps_.shader_set(sh);
|
||||
accumulate_ps_.bind_resources(inst_.uniform_data);
|
||||
|
|
|
@ -120,6 +120,11 @@ class Film {
|
|||
return display_extent;
|
||||
}
|
||||
|
||||
int scaling_factor_get() const
|
||||
{
|
||||
return data_.scaling_factor;
|
||||
}
|
||||
|
||||
float2 pixel_jitter_get() const;
|
||||
|
||||
float background_opacity_get() const
|
||||
|
|
|
@ -143,8 +143,8 @@ void Sampling::step()
|
|||
}
|
||||
/* Using leaped Halton sequence so we can reused the same primes as lens. */
|
||||
double3 r, offset = {0, 0, 0};
|
||||
uint64_t leap = 11;
|
||||
uint3 primes = {5, 4, 7};
|
||||
uint64_t leap = 13;
|
||||
uint3 primes = {5, 7, 11};
|
||||
BLI_halton_3d(primes, offset, sample_raytrace * leap, r);
|
||||
data_.dimensions[SAMPLING_SHADOW_U] = r[0];
|
||||
data_.dimensions[SAMPLING_SHADOW_V] = r[1];
|
||||
|
|
|
@ -210,10 +210,26 @@ void ShadingView::update_view()
|
|||
float4x4 viewmat = main_view_.viewmat();
|
||||
float4x4 winmat = main_view_.winmat();
|
||||
|
||||
/* TODO(fclem): Mixed-resolution rendering: We need to make sure we render with exactly the same
|
||||
* distances between pixels to line up render samples and target pixels.
|
||||
* So if the target resolution is not a multiple of the resolution divisor, we need to make the
|
||||
* projection window bigger in the +X and +Y directions. */
|
||||
/*
|
||||
* Mixed resolution rendering. The center of the display pixels must align with the center of
|
||||
* the render pixels. If they don't align, the winmat needs to be re-projected.
|
||||
*/
|
||||
int2 scaling_factor = int2(inst_.film.scaling_factor_get());
|
||||
int2 rescaled_render_extent = extent_ * scaling_factor;
|
||||
int2 display_extent = inst_.film.display_extent_get();
|
||||
if (rescaled_render_extent != display_extent) {
|
||||
float left;
|
||||
float right;
|
||||
float bottom;
|
||||
float top;
|
||||
float near;
|
||||
float far;
|
||||
projmat_dimensions(winmat.ptr(), &left, &right, &bottom, &top, &near, &far);
|
||||
float2 scale = (float2(rescaled_render_extent) / float2(display_extent));
|
||||
right = left + ((right - left) * scale.x);
|
||||
top = bottom + ((top - bottom) * scale.y);
|
||||
winmat = math::projection::perspective(left, right, bottom, top, near, far);
|
||||
}
|
||||
|
||||
/* Anti-Aliasing / Super-Sampling jitter. */
|
||||
float2 jitter = inst_.film.pixel_jitter_get() / float2(extent_);
|
||||
|
|
|
@ -54,24 +54,22 @@ FilmSample film_sample_get(int sample_n, ivec2 texel_film)
|
|||
* reprojecting the incoming pixel data into film pixel space. */
|
||||
#else
|
||||
|
||||
# ifdef SCALED_RENDERING
|
||||
texel_film /= uniform_buf.film.scaling_factor;
|
||||
# endif
|
||||
|
||||
FilmSample film_sample = uniform_buf.film.samples[sample_n];
|
||||
film_sample.texel += texel_film + uniform_buf.film.render_offset;
|
||||
film_sample.texel += (texel_film / scaling_factor) + uniform_buf.film.render_offset;
|
||||
/* Use extend on borders. */
|
||||
film_sample.texel = clamp(film_sample.texel, ivec2(0, 0), uniform_buf.film.render_extent - 1);
|
||||
|
||||
/* TODO(fclem): Panoramic projection will need to compute the sample weight in the shader
|
||||
* instead of precomputing it on CPU. */
|
||||
# ifdef SCALED_RENDERING
|
||||
/* We need to compute the real distance and weight since a sample
|
||||
* can be used by many final pixel. */
|
||||
vec2 offset = uniform_buf.film.subpixel_offset -
|
||||
vec2(texel_film % uniform_buf.film.scaling_factor);
|
||||
film_sample.weight = film_filter_weight(uniform_buf.film.filter_size, length_squared(offset));
|
||||
# endif
|
||||
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) *
|
||||
scaling_factor -
|
||||
(vec2(texel_film) + 0.5);
|
||||
film_sample.weight = film_filter_weight(uniform_buf.film.filter_radius,
|
||||
length_squared(offset));
|
||||
}
|
||||
|
||||
#endif /* PANORAMIC */
|
||||
|
||||
|
@ -84,13 +82,14 @@ FilmSample film_sample_get(int sample_n, ivec2 texel_film)
|
|||
/* Returns the combined weights of all samples affecting this film pixel. */
|
||||
float film_weight_accumulation(ivec2 texel_film)
|
||||
{
|
||||
#if 0 /* TODO(fclem): Reference implementation, also needed for panoramic cameras. */
|
||||
float weight = 0.0;
|
||||
for (int i = 0; i < uniform_buf.film.samples_len; i++) {
|
||||
weight += film_sample_get(i, texel_film).weight;
|
||||
/* TODO(fclem): Reference implementation, also needed for panoramic cameras. */
|
||||
if (scaling_factor > 1) {
|
||||
float weight = 0.0;
|
||||
for (int i = 0; i < uniform_buf.film.samples_len; i++) {
|
||||
weight += film_sample_get(i, texel_film).weight;
|
||||
}
|
||||
return weight;
|
||||
}
|
||||
return weight;
|
||||
#endif
|
||||
return uniform_buf.film.samples_weight_total;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#pragma BLENDER_REQUIRE(gpu_shader_codegen_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(eevee_renderpass_lib.glsl)
|
||||
|
||||
#define filmScalingFactor float(uniform_buf.film.scaling_factor)
|
||||
Jeroen-Bakker marked this conversation as resolved
Clément Foucault
commented
Nitpick1: Don't use camecase, so Nitpicl2: Use functions instead of macros. Nitpick1: Don't use camecase, so `film_scaling_factor`. This is old codestyle and will eventually fade away.
Nitpicl2: Use functions instead of macros.
|
||||
|
||||
vec3 g_emission;
|
||||
vec3 g_transmittance;
|
||||
float g_holdout;
|
||||
|
@ -689,6 +691,20 @@ vec3 coordinate_incoming(vec3 P)
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Mixed render resolution
|
||||
*
|
||||
* Callbacks image texture sampling.
|
||||
*
|
||||
* \{ */
|
||||
|
||||
float film_scaling_factor_get()
|
||||
{
|
||||
return float(uniform_buf.film.scaling_factor);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Volume Attribute post
|
||||
*
|
||||
|
|
|
@ -26,6 +26,7 @@ GPU_SHADER_CREATE_INFO(eevee_film)
|
|||
.specialization_constant(Type::UINT, "enabled_categories", 0)
|
||||
.specialization_constant(Type::INT, "samples_len", 0)
|
||||
.specialization_constant(Type::BOOL, "use_reprojection", false)
|
||||
.specialization_constant(Type::INT, "scaling_factor", 1)
|
||||
.additional_info("eevee_shared")
|
||||
.additional_info("eevee_global_ubo")
|
||||
.additional_info("eevee_velocity_camera")
|
||||
|
|
|
@ -56,7 +56,16 @@ void point_map_to_tube(vec3 vin, out vec3 vout)
|
|||
|
||||
void node_tex_image_linear(vec3 co, sampler2D ima, out vec4 color, out float alpha)
|
||||
{
|
||||
#ifdef GPU_FRAGMENT_SHADER
|
||||
vec2 scaling_factor = vec2(film_scaling_factor_get());
|
||||
vec2 dx = dFdx(co.xy) / scaling_factor;
|
||||
vec2 dy = dFdy(co.xy) / scaling_factor;
|
||||
|
||||
color = safe_color(textureGrad(ima, co.xy, dx, dy));
|
||||
#else
|
||||
color = safe_color(texture(ima, co.xy));
|
||||
#endif
|
||||
|
||||
alpha = color.a;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
This is making all viewport reduce size even if preview pixel size is 1. This is very unconfortable and messes with a bunch of TAA algorithm that are reset because render size changes on navigation.
So remove that all-together.