Compositor: Backdrop mode changes node grid.

When viewing backdrop on top of the node grid, the grid would be
rendered black when the mode wasn't set to RGBA. This fix fixes this by
reverting the previous fix of drawing the backdrop and implement a
different one that recomputes the UV coordinates on the screen edges.
This commit is contained in:
Jeroen Bakker 2022-02-04 09:51:25 +01:00
parent f7a6e8db04
commit 5088d907e5
6 changed files with 54 additions and 31 deletions

View File

@ -71,7 +71,7 @@ class BatchUpdater {
float pos[4][2];
fill_tri_fan_from_rctf(pos, info.clipping_bounds);
float uv[4][2];
fill_tri_fan_from_rctf(uv, info.uv_bounds);
fill_tri_fan_from_rctf(uv, info.clipping_uv_bounds);
for (int i = 0; i < 4; i++) {
GPU_vertbuf_attr_set(vbo, pos_id, i, pos[i]);

View File

@ -26,6 +26,7 @@
#include "IMB_imbuf_types.h"
#include "BLI_float4x4.hh"
#include "BLI_math_vec_types.hh"
#include "image_batches.hh"
@ -61,11 +62,11 @@ struct OneTextureMethod {
}
}
void update_uv_bounds(const ARegion *region)
void update_region_uv_bounds(const ARegion *region)
{
TextureInfo &info = instance_data->texture_infos[0];
if (!BLI_rctf_compare(&info.uv_bounds, &region->v2d.cur, EPSILON_UV_BOUNDS)) {
info.uv_bounds = region->v2d.cur;
if (!BLI_rctf_compare(&info.region_uv_bounds, &region->v2d.cur, EPSILON_UV_BOUNDS)) {
info.region_uv_bounds = region->v2d.cur;
info.dirty = true;
}
@ -74,6 +75,25 @@ struct OneTextureMethod {
BLI_rctf_init_minmax(&instance_data->texture_infos[i].clipping_bounds);
}
}
void update_screen_uv_bounds()
{
for (int i = 0; i < SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN; i++) {
update_screen_uv_bounds(instance_data->texture_infos[0]);
}
}
void update_screen_uv_bounds(TextureInfo &info)
{
/* Although this works, computing an inverted matrix adds some precision issues and leads to
* tearing artifacts. This should be modified to use the scaling and transformation from the
* not inverted matrix.*/
float4x4 mat(instance_data->ss_to_texture);
float4x4 mat_inv = mat.inverted();
float3 min_uv = mat_inv * float3(0.0f, 0.0f, 0.0f);
float3 max_uv = mat_inv * float3(1.0f, 1.0f, 0.0f);
BLI_rctf_init(&info.clipping_uv_bounds, min_uv[0], max_uv[0], min_uv[1], max_uv[1]);
}
};
using namespace blender::bke::image::partial_update;
@ -248,8 +268,9 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
static_cast<float>(iterator.tile_data.tile_buffer->y) +
tile_offset_y);
rctf changed_overlapping_region_in_uv_space;
const bool region_overlap = BLI_rctf_isect(
&info.uv_bounds, &changed_region_in_uv_space, &changed_overlapping_region_in_uv_space);
const bool region_overlap = BLI_rctf_isect(&info.region_uv_bounds,
&changed_region_in_uv_space,
&changed_overlapping_region_in_uv_space);
if (!region_overlap) {
continue;
}
@ -257,15 +278,16 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
// TODO: first convert to ss_pixel space as integer based. and from there go back to texel
// space. But perhaps this isn't needed and we could use an extraction offset somehow.
rcti gpu_texture_region_to_update;
BLI_rcti_init(&gpu_texture_region_to_update,
floor((changed_overlapping_region_in_uv_space.xmin - info.uv_bounds.xmin) *
texture_width / BLI_rctf_size_x(&info.uv_bounds)),
floor((changed_overlapping_region_in_uv_space.xmax - info.uv_bounds.xmin) *
texture_width / BLI_rctf_size_x(&info.uv_bounds)),
ceil((changed_overlapping_region_in_uv_space.ymin - info.uv_bounds.ymin) *
texture_height / BLI_rctf_size_y(&info.uv_bounds)),
ceil((changed_overlapping_region_in_uv_space.ymax - info.uv_bounds.ymin) *
texture_height / BLI_rctf_size_y(&info.uv_bounds)));
BLI_rcti_init(
&gpu_texture_region_to_update,
floor((changed_overlapping_region_in_uv_space.xmin - info.region_uv_bounds.xmin) *
texture_width / BLI_rctf_size_x(&info.region_uv_bounds)),
floor((changed_overlapping_region_in_uv_space.xmax - info.region_uv_bounds.xmin) *
texture_width / BLI_rctf_size_x(&info.region_uv_bounds)),
ceil((changed_overlapping_region_in_uv_space.ymin - info.region_uv_bounds.ymin) *
texture_height / BLI_rctf_size_y(&info.region_uv_bounds)),
ceil((changed_overlapping_region_in_uv_space.ymax - info.region_uv_bounds.ymin) *
texture_height / BLI_rctf_size_y(&info.region_uv_bounds)));
rcti tile_region_to_extract;
BLI_rcti_init(
@ -289,11 +311,13 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
for (int y = gpu_texture_region_to_update.ymin; y < gpu_texture_region_to_update.ymax;
y++) {
float yf = y / (float)texture_height;
float v = info.uv_bounds.ymax * yf + info.uv_bounds.ymin * (1.0 - yf) - tile_offset_y;
float v = info.region_uv_bounds.ymax * yf + info.region_uv_bounds.ymin * (1.0 - yf) -
tile_offset_y;
for (int x = gpu_texture_region_to_update.xmin; x < gpu_texture_region_to_update.xmax;
x++) {
float xf = x / (float)texture_width;
float u = info.uv_bounds.xmax * xf + info.uv_bounds.xmin * (1.0 - xf) - tile_offset_x;
float u = info.region_uv_bounds.xmax * xf + info.region_uv_bounds.xmin * (1.0 - xf) -
tile_offset_x;
nearest_interpolation_color(tile_buffer,
nullptr,
&extracted_buffer.rect_float[offset * 4],
@ -405,8 +429,10 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
static_cast<float>(texture_height) / static_cast<float>(tile_buffer.y),
1.0f};
rescale_m4(uv_to_texel, scale);
uv_to_texel[3][0] += image_tile.get_tile_x_offset() / BLI_rctf_size_x(&texture_info.uv_bounds);
uv_to_texel[3][1] += image_tile.get_tile_y_offset() / BLI_rctf_size_y(&texture_info.uv_bounds);
uv_to_texel[3][0] += image_tile.get_tile_x_offset() /
BLI_rctf_size_x(&texture_info.region_uv_bounds);
uv_to_texel[3][1] += image_tile.get_tile_y_offset() /
BLI_rctf_size_y(&texture_info.region_uv_bounds);
uv_to_texel[3][0] *= texture_width;
uv_to_texel[3][1] *= texture_height;
invert_m4(uv_to_texel);
@ -457,7 +483,8 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
// screen space textures that aren't needed.
const ARegion *region = draw_ctx->region;
method.update_screen_space_bounds(region);
method.update_uv_bounds(region);
method.update_region_uv_bounds(region);
method.update_screen_uv_bounds();
// Step: Update the GPU textures based on the changes in the image.
instance_data->update_gpu_texture_allocations();

View File

@ -54,8 +54,6 @@ struct IMAGE_Data {
#define IMAGE_DRAW_FLAG_APPLY_ALPHA (1 << 1)
#define IMAGE_DRAW_FLAG_SHUFFLING (1 << 2)
#define IMAGE_DRAW_FLAG_DEPTH (1 << 3)
/** Flag to disable depth testing (used for node editor back drop drawing).*/
#define IMAGE_DRAW_FLAG_DEPTH_ALWAYS (1 << 4)
/**
* Abstract class for a drawing mode of the image engine.

View File

@ -56,7 +56,6 @@ class SpaceNodeAccessor : public AbstractSpaceAccessor {
void get_shader_parameters(ShaderParameters &r_shader_parameters, ImBuf *ibuf) override
{
r_shader_parameters.flags |= IMAGE_DRAW_FLAG_DEPTH_ALWAYS;
if ((snode->flag & SNODE_USE_ALPHA) != 0) {
/* Show RGBA */
r_shader_parameters.flags |= IMAGE_DRAW_FLAG_SHOW_ALPHA | IMAGE_DRAW_FLAG_APPLY_ALPHA;

View File

@ -44,8 +44,10 @@ struct TextureInfo {
/** \brief area of the texture in screen space. */
rctf clipping_bounds;
/** \brief uv area of the texture. */
rctf uv_bounds;
/** \brief uv area of the texture (copy from ARegion). */
rctf region_uv_bounds;
/** \brief uv area of the texture in screen space. */
rctf clipping_uv_bounds;
/**
* \brief Batch to draw the associated texton the screen.

View File

@ -5,7 +5,6 @@
#define IMAGE_DRAW_FLAG_APPLY_ALPHA (1 << 1)
#define IMAGE_DRAW_FLAG_SHUFFLING (1 << 2)
#define IMAGE_DRAW_FLAG_DEPTH (1 << 3)
#define IMAGE_DRAW_FLAG_DEPTH_ALWAYS (1 << 4)
#define FAR_DISTANCE farNearDistances.x
#define NEAR_DISTANCE farNearDistances.y
@ -13,11 +12,9 @@
void main()
{
ivec2 uvs_clamped = ivec2(uv_screen);
if ((drawFlags & IMAGE_DRAW_FLAG_DEPTH_ALWAYS) == 0) {
float depth = texelFetch(depth_texture, uvs_clamped, 0).r;
if (depth == 1.0) {
discard;
}
float depth = texelFetch(depth_texture, uvs_clamped, 0).r;
if (depth == 1.0) {
discard;
}
vec4 tex_color = texelFetch(imageTexture, uvs_clamped, 0);