ImageEngine: Improve Performance and Quality. #107213
|
@ -46,24 +46,8 @@ class BatchUpdater {
|
||||||
GPU_batch_init_ex(info.batch, GPU_PRIM_TRI_FAN, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
GPU_batch_init_ex(info.batch, GPU_PRIM_TRI_FAN, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUVertBuf *create_vbo()
|
template<typename DataType, typename RectType>
|
||||||
{
|
static void fill_tri_fan_from_rect(DataType result[4][2], RectType &rect)
|
||||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
||||||
GPU_vertbuf_data_alloc(vbo, 4);
|
|
||||||
float pos[4][2];
|
|
||||||
fill_tri_fan_from_rctf(pos, info.clipping_bounds);
|
|
||||||
float uv[4][2];
|
|
||||||
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]);
|
|
||||||
GPU_vertbuf_attr_set(vbo, uv_id, i, uv[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return vbo;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fill_tri_fan_from_rctf(float result[4][2], rctf &rect)
|
|
||||||
{
|
{
|
||||||
result[0][0] = rect.xmin;
|
result[0][0] = rect.xmin;
|
||||||
result[0][1] = rect.ymin;
|
result[0][1] = rect.ymin;
|
||||||
|
@ -75,10 +59,27 @@ class BatchUpdater {
|
||||||
result[3][1] = rect.ymax;
|
result[3][1] = rect.ymax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GPUVertBuf *create_vbo()
|
||||||
|
{
|
||||||
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
||||||
|
GPU_vertbuf_data_alloc(vbo, 4);
|
||||||
|
int pos[4][2];
|
||||||
|
fill_tri_fan_from_rect<int, rcti>(pos, info.clipping_bounds);
|
||||||
|
float uv[4][2];
|
||||||
|
fill_tri_fan_from_rect<float, rctf>(uv, info.clipping_uv_bounds);
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
GPU_vertbuf_attr_set(vbo, pos_id, i, pos[i]);
|
||||||
|
GPU_vertbuf_attr_set(vbo, uv_id, i, uv[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return vbo;
|
||||||
|
}
|
||||||
|
|
||||||
void ensure_format()
|
void ensure_format()
|
||||||
{
|
{
|
||||||
if (format.attr_len == 0) {
|
if (format.attr_len == 0) {
|
||||||
GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
GPU_vertformat_attr_add(&format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT);
|
||||||
GPU_vertformat_attr_add(&format, "uv", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
GPU_vertformat_attr_add(&format, "uv", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||||
|
|
||||||
pos_id = GPU_vertformat_attr_id_get(&format, "pos");
|
pos_id = GPU_vertformat_attr_id_get(&format, "pos");
|
||||||
|
|
|
@ -21,11 +21,88 @@ namespace blender::draw::image_engine {
|
||||||
|
|
||||||
constexpr float EPSILON_UV_BOUNDS = 0.00001f;
|
constexpr float EPSILON_UV_BOUNDS = 0.00001f;
|
||||||
|
|
||||||
|
class BaseTextureMethod {
|
||||||
|
protected:
|
||||||
|
IMAGE_InstanceData *instance_data;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BaseTextureMethod(IMAGE_InstanceData *instance_data) : instance_data(instance_data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* \brief Ensure enough texture infos are allocated in `instance_data`.
|
||||||
|
*/
|
||||||
|
virtual void ensure_texture_infos() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Update the uv and region bounds of all texture_infos of instance_data.
|
||||||
|
*/
|
||||||
|
virtual void update_bounds(const ARegion *region) = 0;
|
||||||
|
|
||||||
|
virtual void ensure_gpu_textures_allocation() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses a single texture that covers the area. Every zoom/pan change requires a full
|
||||||
|
* update of the texture.
|
||||||
|
*/
|
||||||
|
class OneTexture : public BaseTextureMethod {
|
||||||
|
public:
|
||||||
|
OneTexture(IMAGE_InstanceData *instance_data) : BaseTextureMethod(instance_data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void ensure_texture_infos() override
|
||||||
|
{
|
||||||
|
instance_data->texture_infos.resize(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_bounds(const ARegion *region) override
|
||||||
|
{
|
||||||
|
float4x4 mat = math::invert(float4x4(instance_data->ss_to_texture));
|
||||||
|
float2 region_uv_min = math::transform_point(mat, float3(0.0f, 0.0f, 0.0f)).xy();
|
||||||
|
float2 region_uv_max = math::transform_point(mat, float3(1.0f, 1.0f, 0.0f)).xy();
|
||||||
|
|
||||||
|
TextureInfo &texture_info = instance_data->texture_infos[0];
|
||||||
|
texture_info.tile_id = int2(0);
|
||||||
|
texture_info.need_full_update = false;
|
||||||
|
rctf new_clipping_uv_bounds;
|
||||||
|
BLI_rctf_init(&new_clipping_uv_bounds,
|
||||||
|
region_uv_min.x,
|
||||||
|
region_uv_max.x,
|
||||||
|
region_uv_min.y,
|
||||||
|
region_uv_max.y);
|
||||||
|
|
||||||
|
if (memcmp(&new_clipping_uv_bounds, &texture_info.clipping_uv_bounds, sizeof(rctf))) {
|
||||||
|
texture_info.clipping_uv_bounds = new_clipping_uv_bounds;
|
||||||
|
texture_info.need_full_update = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
rcti new_clipping_bounds;
|
||||||
|
BLI_rcti_init(&new_clipping_bounds, 0, region->winx, 0, region->winy);
|
||||||
|
if (memcmp(&new_clipping_bounds, &texture_info.clipping_bounds, sizeof(rcti))) {
|
||||||
|
texture_info.clipping_bounds = new_clipping_bounds;
|
||||||
|
texture_info.need_full_update = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ensure_gpu_textures_allocation() override
|
||||||
|
{
|
||||||
|
TextureInfo &texture_info = instance_data->texture_infos[0];
|
||||||
|
int2 texture_size = int2(BLI_rcti_size_x(&texture_info.clipping_bounds),
|
||||||
|
BLI_rcti_size_y(&texture_info.clipping_bounds));
|
||||||
|
texture_info.ensure_gpu_texture(texture_size);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Screen space method using a multiple textures covering the region.
|
* \brief Screen space method using a multiple textures covering the region.
|
||||||
*
|
*
|
||||||
|
* This method improves panning speed, but has some drawing artifacts and
|
||||||
|
* therefore isn't selected.
|
||||||
*/
|
*/
|
||||||
template<size_t Divisions> class ScreenTileTextures {
|
template<size_t Divisions> class ScreenTileTextures : public BaseTextureMethod {
|
||||||
public:
|
public:
|
||||||
static const size_t TexturesPerDimension = Divisions + 1;
|
static const size_t TexturesPerDimension = Divisions + 1;
|
||||||
static const size_t TexturesRequired = TexturesPerDimension * TexturesPerDimension;
|
static const size_t TexturesRequired = TexturesPerDimension * TexturesPerDimension;
|
||||||
|
@ -38,19 +115,19 @@ template<size_t Divisions> class ScreenTileTextures {
|
||||||
struct TextureInfoBounds {
|
struct TextureInfoBounds {
|
||||||
TextureInfo *info = nullptr;
|
TextureInfo *info = nullptr;
|
||||||
rctf uv_bounds;
|
rctf uv_bounds;
|
||||||
|
/* Offset of this tile to be drawn on the screen (number of tiles from bottom left corner). */
|
||||||
|
int2 tile_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
IMAGE_InstanceData *instance_data;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ScreenTileTextures(IMAGE_InstanceData *instance_data) : instance_data(instance_data)
|
ScreenTileTextures(IMAGE_InstanceData *instance_data) : BaseTextureMethod(instance_data)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Ensure enough texture infos are allocated in `instance_data`.
|
* \brief Ensure enough texture infos are allocated in `instance_data`.
|
||||||
*/
|
*/
|
||||||
void ensure_texture_infos()
|
void ensure_texture_infos() override
|
||||||
{
|
{
|
||||||
instance_data->texture_infos.resize(TexturesRequired);
|
instance_data->texture_infos.resize(TexturesRequired);
|
||||||
}
|
}
|
||||||
|
@ -58,7 +135,7 @@ template<size_t Divisions> class ScreenTileTextures {
|
||||||
/**
|
/**
|
||||||
* \brief Update the uv and region bounds of all texture_infos of instance_data.
|
* \brief Update the uv and region bounds of all texture_infos of instance_data.
|
||||||
*/
|
*/
|
||||||
void update_bounds(const ARegion *region)
|
void update_bounds(const ARegion *region) override
|
||||||
{
|
{
|
||||||
/* determine uv_area of the region. */
|
/* determine uv_area of the region. */
|
||||||
Vector<TextureInfo *> unassigned_textures;
|
Vector<TextureInfo *> unassigned_textures;
|
||||||
|
@ -78,13 +155,22 @@ template<size_t Divisions> class ScreenTileTextures {
|
||||||
rctf region_uv_bounds;
|
rctf region_uv_bounds;
|
||||||
BLI_rctf_init(
|
BLI_rctf_init(
|
||||||
®ion_uv_bounds, region_uv_min.x, region_uv_max.x, region_uv_min.y, region_uv_max.y);
|
®ion_uv_bounds, region_uv_min.x, region_uv_max.x, region_uv_min.y, region_uv_max.y);
|
||||||
update_region_bounds_from_uv_bounds(region_uv_bounds, float2(region->winx, region->winy));
|
update_region_bounds_from_uv_bounds(region_uv_bounds, int2(region->winx, region->winy));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ensure_gpu_textures_allocation()
|
/**
|
||||||
|
* Get the texture size of a single texture for the current settings.
|
||||||
|
*/
|
||||||
|
int2 gpu_texture_size() const
|
||||||
{
|
{
|
||||||
float2 viewport_size = DRW_viewport_size_get();
|
float2 viewport_size = DRW_viewport_size_get();
|
||||||
int2 texture_size(ceil(viewport_size.x / Divisions), ceil(viewport_size.y / Divisions));
|
int2 texture_size(ceil(viewport_size.x / Divisions), ceil(viewport_size.y / Divisions));
|
||||||
|
return texture_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ensure_gpu_textures_allocation() override
|
||||||
|
{
|
||||||
|
int2 texture_size = gpu_texture_size();
|
||||||
for (TextureInfo &info : instance_data->texture_infos) {
|
for (TextureInfo &info : instance_data->texture_infos) {
|
||||||
info.ensure_gpu_texture(texture_size);
|
info.ensure_gpu_texture(texture_size);
|
||||||
}
|
}
|
||||||
|
@ -109,6 +195,7 @@ template<size_t Divisions> class ScreenTileTextures {
|
||||||
for (int x = 0; x < TexturesPerDimension; x++) {
|
for (int x = 0; x < TexturesPerDimension; x++) {
|
||||||
for (int y = 0; y < TexturesPerDimension; y++) {
|
for (int y = 0; y < TexturesPerDimension; y++) {
|
||||||
TextureInfoBounds texture_info_bounds;
|
TextureInfoBounds texture_info_bounds;
|
||||||
|
texture_info_bounds.tile_id = int2(x, y);
|
||||||
BLI_rctf_init(&texture_info_bounds.uv_bounds,
|
BLI_rctf_init(&texture_info_bounds.uv_bounds,
|
||||||
uv_coords[x][y].x,
|
uv_coords[x][y].x,
|
||||||
uv_coords[x + 1][y + 1].x,
|
uv_coords[x + 1][y + 1].x,
|
||||||
|
@ -129,6 +216,7 @@ template<size_t Divisions> class ScreenTileTextures {
|
||||||
if (info_bound.info == nullptr &&
|
if (info_bound.info == nullptr &&
|
||||||
BLI_rctf_compare(&info_bound.uv_bounds, &info.clipping_uv_bounds, 0.001)) {
|
BLI_rctf_compare(&info_bound.uv_bounds, &info.clipping_uv_bounds, 0.001)) {
|
||||||
info_bound.info = &info;
|
info_bound.info = &info;
|
||||||
|
info.tile_id = info_bound.tile_id;
|
||||||
assigned = true;
|
assigned = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -145,20 +233,34 @@ template<size_t Divisions> class ScreenTileTextures {
|
||||||
for (TextureInfoBounds &info_bound : info_bounds) {
|
for (TextureInfoBounds &info_bound : info_bounds) {
|
||||||
if (info_bound.info == nullptr) {
|
if (info_bound.info == nullptr) {
|
||||||
info_bound.info = unassigned_textures.pop_last();
|
info_bound.info = unassigned_textures.pop_last();
|
||||||
|
info_bound.info->tile_id = info_bound.tile_id;
|
||||||
info_bound.info->need_full_update = true;
|
info_bound.info->need_full_update = true;
|
||||||
info_bound.info->clipping_uv_bounds = info_bound.uv_bounds;
|
info_bound.info->clipping_uv_bounds = info_bound.uv_bounds;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_region_bounds_from_uv_bounds(const rctf ®ion_uv_bounds, const float2 region_size)
|
void update_region_bounds_from_uv_bounds(const rctf ®ion_uv_bounds, const int2 region_size)
|
||||||
{
|
{
|
||||||
rctf region_bounds;
|
rctf region_bounds;
|
||||||
BLI_rctf_init(®ion_bounds, 0.0, region_size.x, 0.0, region_size.y);
|
BLI_rctf_init(®ion_bounds, 0.0, region_size.x, 0.0, region_size.y);
|
||||||
float4x4 uv_to_screen;
|
float4x4 uv_to_screen;
|
||||||
BLI_rctf_transform_calc_m4_pivot_min(®ion_uv_bounds, ®ion_bounds, uv_to_screen.ptr());
|
BLI_rctf_transform_calc_m4_pivot_min(®ion_uv_bounds, ®ion_bounds, uv_to_screen.ptr());
|
||||||
|
int2 tile_origin(0);
|
||||||
|
for (const TextureInfo &info : instance_data->texture_infos) {
|
||||||
|
if (info.tile_id == int2(0)) {
|
||||||
|
tile_origin = int2(math::transform_point(
|
||||||
|
uv_to_screen,
|
||||||
|
float3(info.clipping_uv_bounds.xmin, info.clipping_uv_bounds.ymin, 0.0)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const int2 texture_size = gpu_texture_size();
|
||||||
for (TextureInfo &info : instance_data->texture_infos) {
|
for (TextureInfo &info : instance_data->texture_infos) {
|
||||||
info.update_region_bounds_from_uv_bounds(uv_to_screen);
|
int2 bottom_left = tile_origin + texture_size * info.tile_id;
|
||||||
|
int2 top_right = bottom_left + texture_size;
|
||||||
|
BLI_rcti_init(&info.clipping_bounds, bottom_left.x, top_right.x, bottom_left.y, top_right.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -498,7 +600,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
|
||||||
tile_buffer.y * (texture_info.clipping_uv_bounds.ymin - image_tile.get_tile_y_offset()),
|
tile_buffer.y * (texture_info.clipping_uv_bounds.ymin - image_tile.get_tile_y_offset()),
|
||||||
tile_buffer.y * (texture_info.clipping_uv_bounds.ymax - image_tile.get_tile_y_offset()));
|
tile_buffer.y * (texture_info.clipping_uv_bounds.ymax - image_tile.get_tile_y_offset()));
|
||||||
BLI_rctf_transform_calc_m4_pivot_min(&tile_area, &texture_area, uv_to_texel.ptr());
|
BLI_rctf_transform_calc_m4_pivot_min(&tile_area, &texture_area, uv_to_texel.ptr());
|
||||||
invert_m4(uv_to_texel.ptr());
|
uv_to_texel = math::invert(uv_to_texel);
|
||||||
|
|
||||||
rctf crop_rect;
|
rctf crop_rect;
|
||||||
rctf *crop_rect_ptr = nullptr;
|
rctf *crop_rect_ptr = nullptr;
|
||||||
|
@ -585,6 +687,6 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
|
||||||
DRW_view_set_active(nullptr);
|
DRW_view_set_active(nullptr);
|
||||||
GPU_framebuffer_bind(dfbl->default_fb);
|
GPU_framebuffer_bind(dfbl->default_fb);
|
||||||
}
|
}
|
||||||
}; // namespace clipping
|
};
|
||||||
|
|
||||||
} // namespace blender::draw::image_engine
|
} // namespace blender::draw::image_engine
|
||||||
|
|
|
@ -53,7 +53,7 @@ template<
|
||||||
*
|
*
|
||||||
* Useful during development to switch between drawing implementations.
|
* Useful during development to switch between drawing implementations.
|
||||||
*/
|
*/
|
||||||
typename DrawingMode = ScreenSpaceDrawingMode<ScreenTileTextures<1>>>
|
typename DrawingMode = ScreenSpaceDrawingMode<OneTexture>>
|
||||||
class ImageEngine {
|
class ImageEngine {
|
||||||
private:
|
private:
|
||||||
const DRWContextState *draw_ctx;
|
const DRWContextState *draw_ctx;
|
||||||
|
|
|
@ -24,15 +24,19 @@ struct TextureInfo {
|
||||||
bool need_full_update : 1;
|
bool need_full_update : 1;
|
||||||
|
|
||||||
/** \brief area of the texture in screen space. */
|
/** \brief area of the texture in screen space. */
|
||||||
rctf clipping_bounds;
|
rcti clipping_bounds;
|
||||||
/** \brief uv area of the texture in screen space. */
|
/** \brief uv area of the texture in screen space. */
|
||||||
rctf clipping_uv_bounds;
|
rctf clipping_uv_bounds;
|
||||||
|
|
||||||
|
/* Which tile of the screen is used with this texture. Used to safely calculate the correct
|
||||||
|
* offset of the textures. */
|
||||||
|
int2 tile_id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Batch to draw the associated text on the screen.
|
* \brief Batch to draw the associated text on the screen.
|
||||||
*
|
*
|
||||||
* Contains a VBO with `pos` and `uv`.
|
* Contains a VBO with `pos` and `uv`.
|
||||||
* `pos` (2xF32) is relative to the origin of the space.
|
* `pos` (2xI32) is relative to the origin of the space.
|
||||||
* `uv` (2xF32) reflect the uv bounds.
|
* `uv` (2xF32) reflect the uv bounds.
|
||||||
*/
|
*/
|
||||||
GPUBatch *batch = nullptr;
|
GPUBatch *batch = nullptr;
|
||||||
|
@ -68,22 +72,6 @@ struct TextureInfo {
|
||||||
return int2(clipping_bounds.xmin, clipping_bounds.ymin);
|
return int2(clipping_bounds.xmin, clipping_bounds.ymin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Update the region bounds from the uv bounds by applying the given transform matrix.
|
|
||||||
*/
|
|
||||||
void update_region_bounds_from_uv_bounds(const float4x4 &uv_to_region)
|
|
||||||
{
|
|
||||||
float3 bottom_left_uv = float3(clipping_uv_bounds.xmin, clipping_uv_bounds.ymin, 0.0f);
|
|
||||||
float3 top_right_uv = float3(clipping_uv_bounds.xmax, clipping_uv_bounds.ymax, 0.0f);
|
|
||||||
float3 bottom_left_region = math::transform_point(uv_to_region, bottom_left_uv);
|
|
||||||
float3 top_right_region = math::transform_point(uv_to_region, top_right_uv);
|
|
||||||
BLI_rctf_init(&clipping_bounds,
|
|
||||||
bottom_left_region.x,
|
|
||||||
top_right_region.x,
|
|
||||||
bottom_left_region.y,
|
|
||||||
top_right_region.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ensure_gpu_texture(int2 texture_size)
|
void ensure_gpu_texture(int2 texture_size)
|
||||||
{
|
{
|
||||||
const bool is_allocated = texture != nullptr;
|
const bool is_allocated = texture != nullptr;
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec3 image_pos = vec3(pos, 0.0);
|
vec3 image_pos = vec3(pos.x, pos.y, 0.0);
|
||||||
uv_screen = image_pos.xy;
|
uv_screen = image_pos.xy;
|
||||||
|
|
||||||
vec3 world_pos = point_object_to_world(image_pos);
|
vec4 position = point_world_to_ndc(image_pos);
|
||||||
vec4 position = point_world_to_ndc(world_pos);
|
|
||||||
gl_Position = position;
|
gl_Position = position;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec3 image_pos = vec3(pos, 0.0);
|
vec3 image_pos = vec3(pos.x, pos.y, 0.0);
|
||||||
uv_image = uv;
|
uv_image = uv;
|
||||||
|
|
||||||
vec3 world_pos = point_object_to_world(image_pos);
|
vec4 position = point_world_to_ndc(image_pos);
|
||||||
vec4 position = point_world_to_ndc(world_pos);
|
|
||||||
gl_Position = position;
|
gl_Position = position;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
GPU_SHADER_INTERFACE_INFO(image_engine_color_iface, "").smooth(Type::VEC2, "uv_screen");
|
GPU_SHADER_INTERFACE_INFO(image_engine_color_iface, "").smooth(Type::VEC2, "uv_screen");
|
||||||
|
|
||||||
GPU_SHADER_CREATE_INFO(image_engine_color_shader)
|
GPU_SHADER_CREATE_INFO(image_engine_color_shader)
|
||||||
.vertex_in(0, Type::VEC2, "pos")
|
.vertex_in(0, Type::IVEC2, "pos")
|
||||||
.vertex_out(image_engine_color_iface)
|
.vertex_out(image_engine_color_iface)
|
||||||
.fragment_out(0, Type::VEC4, "fragColor")
|
.fragment_out(0, Type::VEC4, "fragColor")
|
||||||
.push_constant(Type::VEC4, "shuffle")
|
.push_constant(Type::VEC4, "shuffle")
|
||||||
|
@ -23,7 +23,7 @@ GPU_SHADER_CREATE_INFO(image_engine_color_shader)
|
||||||
GPU_SHADER_INTERFACE_INFO(image_engine_depth_iface, "").smooth(Type::VEC2, "uv_image");
|
GPU_SHADER_INTERFACE_INFO(image_engine_depth_iface, "").smooth(Type::VEC2, "uv_image");
|
||||||
|
|
||||||
GPU_SHADER_CREATE_INFO(image_engine_depth_shader)
|
GPU_SHADER_CREATE_INFO(image_engine_depth_shader)
|
||||||
.vertex_in(0, Type::VEC2, "pos")
|
.vertex_in(0, Type::IVEC2, "pos")
|
||||||
.vertex_in(1, Type::VEC2, "uv")
|
.vertex_in(1, Type::VEC2, "uv")
|
||||||
.vertex_out(image_engine_depth_iface)
|
.vertex_out(image_engine_depth_iface)
|
||||||
.push_constant(Type::VEC4, "min_max_uv")
|
.push_constant(Type::VEC4, "min_max_uv")
|
||||||
|
|
Loading…
Reference in New Issue