Image Editor: Remove drawing artifacts #106173
|
@ -732,6 +732,8 @@ set(GLSL_SRC
|
|||
engines/image/shaders/image_engine_color_vert.glsl
|
||||
engines/image/shaders/image_engine_depth_frag.glsl
|
||||
engines/image/shaders/image_engine_depth_vert.glsl
|
||||
engines/image/shaders/image_engine_color_depth_frag.glsl
|
||||
engines/image/shaders/image_engine_color_depth_vert.glsl
|
||||
)
|
||||
|
||||
set(GLSL_C)
|
||||
|
|
|
@ -585,7 +585,6 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
|
|||
if (!instance_data->flags.do_tile_drawing) {
|
||||
add_depth_shgroups(*instance_data, image, iuser);
|
||||
}
|
||||
add_shgroups(instance_data);
|
||||
}
|
||||
|
||||
void draw_finish(IMAGE_Data *vedata) const override
|
||||
|
@ -612,6 +611,65 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
|
|||
DRW_view_set_active(nullptr);
|
||||
GPU_framebuffer_bind(dfbl->default_fb);
|
||||
}
|
||||
}; // namespace clipping
|
||||
};
|
||||
|
||||
/**
|
||||
* Drawing mode that uses the GPU textures stored alongside the image for drawing.
|
||||
*
|
||||
* This is better for images with a dimension smaller than 8K as it will lead to smoother
|
||||
* interaction. Bigger images are required to use #ScreenSpaceDrawingMode.
|
||||
*/
|
||||
class ImageBasedDrawingMode : public AbstractDrawingMode {
|
||||
DRWPass *create_image_pass() const
|
||||
{
|
||||
/* Write depth is needed for background overlay rendering. Near depth is used for
|
||||
* transparency checker and Far depth is used for indicating the image size. */
|
||||
DRWState state = static_cast<DRWState>(DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH |
|
||||
DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ALPHA_PREMUL);
|
||||
return DRW_pass_create("Image", state);
|
||||
}
|
||||
|
||||
public:
|
||||
void begin_sync(IMAGE_Data *vedata) const override
|
||||
{
|
||||
IMAGE_InstanceData *instance_data = vedata->instance_data;
|
||||
DRWState state = static_cast<DRWState>(DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH |
|
||||
DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ALPHA_PREMUL);
|
||||
instance_data->passes.image_pass = DRW_pass_create("Image", state);
|
||||
instance_data->passes.depth_pass = nullptr;
|
||||
}
|
||||
|
||||
void image_sync(IMAGE_Data *vedata, Image *image, ImageUser *iuser) const override
|
||||
{
|
||||
IMAGE_InstanceData *instance_data = vedata->instance_data;
|
||||
|
||||
const bool is_tiled_texture = image->source == IMA_SRC_TILED;
|
||||
GPUTexture *texture = nullptr;
|
||||
if (is_tiled_texture) {
|
||||
}
|
||||
else {
|
||||
texture = BKE_image_get_gpu_texture(image, iuser, nullptr);
|
||||
}
|
||||
|
||||
if (texture == nullptr) {
|
||||
return;
|
||||
}
|
||||
// Add full screen rect.
|
||||
GPUShader *shader = IMAGE_shader_color_depth_get();
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(shader, instance_data->passes.image_pass);
|
||||
|
||||
DRW_shgroup_call_procedural_triangles(grp, nullptr, 1);
|
||||
}
|
||||
|
||||
void draw_viewport(IMAGE_Data *vedata) const override
|
||||
{
|
||||
IMAGE_InstanceData *instance_data = vedata->instance_data;
|
||||
DRW_draw_pass(instance_data->passes.image_pass);
|
||||
}
|
||||
|
||||
void draw_finish(IMAGE_Data * /*vedata*/) const override
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace blender::draw::image_engine
|
||||
|
|
|
@ -53,7 +53,8 @@ template<
|
|||
*
|
||||
* Useful during development to switch between drawing implementations.
|
||||
*/
|
||||
typename DrawingMode = ScreenSpaceDrawingMode<ScreenTileTextures<3>>>
|
||||
typename DrawingMode = ImageBasedDrawingMode>
|
||||
/*ScreenSpaceDrawingMode<ScreenTileTextures<3>>*/
|
||||
class ImageEngine {
|
||||
private:
|
||||
const DRWContextState *draw_ctx;
|
||||
|
|
|
@ -51,6 +51,7 @@ class AbstractDrawingMode {
|
|||
|
||||
GPUShader *IMAGE_shader_image_get();
|
||||
GPUShader *IMAGE_shader_depth_get();
|
||||
GPUShader *IMAGE_shader_color_depth_get();
|
||||
void IMAGE_shader_free();
|
||||
|
||||
} // namespace blender::draw::image_engine
|
||||
|
|
|
@ -19,6 +19,7 @@ namespace blender::draw::image_engine {
|
|||
struct IMAGE_Shaders {
|
||||
GPUShader *image_sh;
|
||||
GPUShader *depth_sh;
|
||||
GPUShader *color_depth_sh;
|
||||
};
|
||||
|
||||
static struct {
|
||||
|
@ -43,6 +44,15 @@ GPUShader *IMAGE_shader_depth_get()
|
|||
return sh_data->depth_sh;
|
||||
}
|
||||
|
||||
GPUShader *IMAGE_shader_color_depth_get()
|
||||
{
|
||||
IMAGE_Shaders *sh_data = &e_data.shaders;
|
||||
if (sh_data->color_depth_sh == nullptr) {
|
||||
sh_data->color_depth_sh = GPU_shader_create_from_info_name("image_engine_color_depth_shader");
|
||||
}
|
||||
return sh_data->color_depth_sh;
|
||||
}
|
||||
|
||||
void IMAGE_shader_free()
|
||||
{
|
||||
GPUShader **sh_data_as_array = (GPUShader **)&e_data.shaders;
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
#pragma BLENDER_REQUIRE(common_colormanagement_lib.glsl)
|
||||
|
||||
/* Keep in sync with image_engine.c */
|
||||
#define IMAGE_DRAW_FLAG_SHOW_ALPHA (1 << 0)
|
||||
#define IMAGE_DRAW_FLAG_APPLY_ALPHA (1 << 1)
|
||||
#define IMAGE_DRAW_FLAG_SHUFFLING (1 << 2)
|
||||
#define IMAGE_DRAW_FLAG_DEPTH (1 << 3)
|
||||
|
||||
#define FAR_DISTANCE farNearDistances.x
|
||||
#define NEAR_DISTANCE farNearDistances.y
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 uvs_clamped = ivec2(uv_screen);
|
||||
float depth = texelFetch(depth_texture, uvs_clamped, 0).r;
|
||||
if (depth == 1.0) {
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
|
||||
vec4 tex_color = texelFetch(imageTexture, uvs_clamped - offset, 0);
|
||||
|
||||
if ((drawFlags & IMAGE_DRAW_FLAG_APPLY_ALPHA) != 0) {
|
||||
if (!imgPremultiplied) {
|
||||
tex_color.rgb *= tex_color.a;
|
||||
}
|
||||
}
|
||||
if ((drawFlags & IMAGE_DRAW_FLAG_DEPTH) != 0) {
|
||||
tex_color = smoothstep(FAR_DISTANCE, NEAR_DISTANCE, tex_color);
|
||||
}
|
||||
|
||||
if ((drawFlags & IMAGE_DRAW_FLAG_SHUFFLING) != 0) {
|
||||
tex_color = vec4(dot(tex_color, shuffle));
|
||||
}
|
||||
if ((drawFlags & IMAGE_DRAW_FLAG_SHOW_ALPHA) == 0) {
|
||||
tex_color.a = 1.0;
|
||||
}
|
||||
fragColor = tex_color;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 image_pos = vec3(pos, 0.0);
|
||||
uv_screen = image_pos.xy;
|
||||
|
||||
vec4 position = point_world_to_ndc(image_pos);
|
||||
gl_Position = position;
|
||||
}
|
|
@ -32,3 +32,25 @@ GPU_SHADER_CREATE_INFO(image_engine_depth_shader)
|
|||
.additional_info("draw_modelmat")
|
||||
.depth_write(DepthWrite::ANY)
|
||||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(image_engine_color_depth_base)
|
||||
.vertex_in(0, Type::IVEC2, "pos")
|
||||
.vertex_in(1, Type::VEC2, "uv")
|
||||
.vertex_out(image_engine_color_iface)
|
||||
.fragment_out(0, Type::VEC4, "fragColor")
|
||||
.push_constant(Type::VEC4, "min_max_uv")
|
||||
.push_constant(Type::VEC4, "shuffle")
|
||||
.push_constant(Type::VEC2, "farNearDistances")
|
||||
.push_constant(Type::IVEC2, "offset")
|
||||
.push_constant(Type::INT, "drawFlags")
|
||||
.push_constant(Type::BOOL, "imgPremultiplied")
|
||||
.sampler(0, ImageType::FLOAT_2D, "imageTexture")
|
||||
.vertex_source("image_engine_color_depth_vert.glsl")
|
||||
.fragment_source("image_engine_color_depth_frag.glsl")
|
||||
.additional_info("draw_modelmat");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(image_engine_color_depth_shader)
|
||||
.additional_info("image_engine_color_depth_base")
|
||||
.sampler(0, ImageType::FLOAT_2D, "image_texture")
|
||||
.do_static_compilation(true);
|
||||
;
|
||||
|
|
Loading…
Reference in New Issue