Skip to content

Commit

Permalink
WIP - bring back item shadow mask to 2D lights
Browse files Browse the repository at this point in the history
  • Loading branch information
clayjohn committed Nov 4, 2024
1 parent 1bffd6c commit c9c3541
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 95 deletions.
54 changes: 31 additions & 23 deletions servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,8 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
RD::get_singleton()->buffer_update(state.lights_uniform_buffer, 0, sizeof(LightUniform) * light_count, &state.light_uniforms[0]);
}

bool use_linear_colors = texture_storage->render_target_is_using_hdr(p_to_render_target);

{
//update canvas state uniform buffer
State::Buffer state_buffer;
Expand Down Expand Up @@ -722,6 +724,8 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
//print_line("w: " + itos(ssize.width) + " s: " + rtos(canvas_scale));
state_buffer.tex_to_sdf = 1.0 / ((canvas_scale.x + canvas_scale.y) * 0.5);

state_buffer.flags = use_linear_colors ? CANVAS_FLAGS_CONVERT_ATTRIBUTES_TO_LINEAR : 0;

RD::get_singleton()->buffer_update(state.canvas_state_buffer, 0, sizeof(State::Buffer), &state_buffer);
}

Expand Down Expand Up @@ -752,8 +756,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p

RenderTarget to_render_target;
to_render_target.render_target = p_to_render_target;
bool use_linear_colors = texture_storage->render_target_is_using_hdr(p_to_render_target);
to_render_target.base_flags = use_linear_colors ? FLAGS_CONVERT_ATTRIBUTES_TO_LINEAR : 0;
to_render_target.use_linear_colors = use_linear_colors;

while (ci) {
if (ci->copy_back_buffer && canvas_group_owner == nullptr) {
Expand Down Expand Up @@ -2237,7 +2240,7 @@ RendererCanvasRenderRD::InstanceData *RendererCanvasRenderRD::new_instance_data(
instance_data->world[i] = p_world[i];
}

instance_data->flags = p_base_flags | p_info->flags; // Reset on each command for safety, keep canvas texture binding config.
instance_data->flags = p_base_flags; // Reset on each command for safety.

instance_data->color_texture_pixel_size[0] = p_info->texpixel_size.width;
instance_data->color_texture_pixel_size[1] = p_info->texpixel_size.height;
Expand All @@ -2258,8 +2261,8 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
_update_transform_2d_to_mat2x3(base_transform, world);

Color base_color = p_item->final_modulate;
bool use_linear_colors = bool(p_render_target.base_flags & FLAGS_CONVERT_ATTRIBUTES_TO_LINEAR);
uint32_t base_flags = p_render_target.base_flags;
bool use_linear_colors = p_render_target.use_linear_colors;
uint32_t base_flags = 0;

bool reclip = false;

Expand All @@ -2269,6 +2272,7 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
uint32_t lights[4] = { 0, 0, 0, 0 };

uint16_t light_count = 0;
uint16_t shadow_mask = 0;

{
Light *light = p_lights;
Expand All @@ -2278,6 +2282,10 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
uint32_t light_index = light->render_index_cache;
lights[light_count >> 2] |= light_index << ((light_count & 3) * 8);

if (p_item->light_mask & light->item_shadow_mask) {
shadow_mask |= 1 << light_count;
}

light_count++;

if (light_count == MAX_LIGHTS_PER_ITEM - 1) {
Expand All @@ -2287,7 +2295,8 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
light = light->next_ptr;
}

base_flags |= light_count << FLAGS_LIGHT_COUNT_SHIFT;
base_flags |= light_count << INSTANCE_FLAGS_LIGHT_COUNT_SHIFT;
base_flags |= shadow_mask << INSTANCE_FLAGS_SHADOW_MASKED_SHIFT;
}

bool use_lighting = (light_count > 0 || using_directional_lights);
Expand Down Expand Up @@ -2371,20 +2380,18 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar

if (rect->flags & CANVAS_RECT_FLIP_H) {
src_rect.size.x *= -1;
instance_data->flags |= FLAGS_FLIP_H;
}

if (rect->flags & CANVAS_RECT_FLIP_V) {
src_rect.size.y *= -1;
instance_data->flags |= FLAGS_FLIP_V;
}

if (rect->flags & CANVAS_RECT_TRANSPOSE) {
instance_data->flags |= FLAGS_TRANSPOSE_RECT;
instance_data->flags |= INSTANCE_FLAGS_TRANSPOSE_RECT;
}

if (rect->flags & CANVAS_RECT_CLIP_UV) {
instance_data->flags |= FLAGS_CLIP_RECT_UV;
instance_data->flags |= INSTANCE_FLAGS_CLIP_RECT_UV;
}

} else {
Expand All @@ -2403,13 +2410,13 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
}

if (has_msdf) {
instance_data->flags |= FLAGS_USE_MSDF;
instance_data->flags |= INSTANCE_FLAGS_USE_MSDF;
instance_data->msdf[0] = rect->px_range; // Pixel range.
instance_data->msdf[1] = rect->outline; // Outline size.
instance_data->msdf[2] = 0.f; // Reserved.
instance_data->msdf[3] = 0.f; // Reserved.
} else if (rect->flags & CANVAS_RECT_LCD) {
instance_data->flags |= FLAGS_USE_LCD;
instance_data->flags |= INSTANCE_FLAGS_USE_LCD;
}

instance_data->modulation[0] = modulated.r;
Expand Down Expand Up @@ -2491,11 +2498,11 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
instance_data->dst_rect[2] = dst_rect.size.width;
instance_data->dst_rect[3] = dst_rect.size.height;

instance_data->flags |= int(np->axis_x) << FLAGS_NINEPATCH_H_MODE_SHIFT;
instance_data->flags |= int(np->axis_y) << FLAGS_NINEPATCH_V_MODE_SHIFT;
instance_data->flags |= int(np->axis_x) << INSTANCE_FLAGS_NINEPATCH_H_MODE_SHIFT;
instance_data->flags |= int(np->axis_y) << INSTANCE_FLAGS_NINEPATCH_V_MODE_SHIFT;

if (np->draw_center) {
instance_data->flags |= FLAGS_NINEPACH_DRAW_CENTER;
instance_data->flags |= INSTANCE_FLAGS_NINEPACH_DRAW_CENTER;
}

instance_data->ninepatch_margins[0] = np->margin[SIDE_LEFT];
Expand Down Expand Up @@ -2683,13 +2690,13 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar
r_current_batch->tex_info = tex_info;
instance_data = new_instance_data(world, lights, base_flags, r_index, tex_info);

instance_data->flags |= 1; // multimesh, trails disabled
r_current_batch->flags |= 1; // multimesh, trails disabled

if (mesh_storage->multimesh_uses_colors(mm->multimesh)) {
instance_data->flags |= FLAGS_INSTANCING_HAS_COLORS;
r_current_batch->flags |= BATCH_FLAGS_INSTANCING_HAS_COLORS;
}
if (mesh_storage->multimesh_uses_custom_data(mm->multimesh)) {
instance_data->flags |= FLAGS_INSTANCING_HAS_CUSTOM_DATA;
r_current_batch->flags |= BATCH_FLAGS_INSTANCING_HAS_CUSTOM_DATA;
}
} else if (c->type == Item::Command::TYPE_PARTICLES) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
Expand All @@ -2707,13 +2714,13 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar

uint32_t divisor = 1;
r_current_batch->mesh_instance_count = particles_storage->particles_get_amount(pt->particles, divisor);
instance_data->flags |= (divisor & FLAGS_INSTANCING_MASK);
r_current_batch->flags |= (divisor & BATCH_FLAGS_INSTANCING_MASK);
r_current_batch->mesh_instance_count /= divisor;

RID particles = pt->particles;

instance_data->flags |= FLAGS_INSTANCING_HAS_COLORS;
instance_data->flags |= FLAGS_INSTANCING_HAS_CUSTOM_DATA;
r_current_batch->flags |= BATCH_FLAGS_INSTANCING_HAS_COLORS;
r_current_batch->flags |= BATCH_FLAGS_INSTANCING_HAS_CUSTOM_DATA;

if (particles_storage->particles_has_collision(particles) && texture_storage->render_target_is_sdf_enabled(p_render_target.render_target)) {
// Pass collision information.
Expand Down Expand Up @@ -2913,6 +2920,7 @@ void RendererCanvasRenderRD::_render_batch(RD::DrawListID p_draw_list, CanvasSha
PushConstant push_constant;
push_constant.base_instance_index = p_batch->start;
push_constant.specular_shininess = p_batch->tex_info->specular_shininess;
push_constant.batch_flags = p_batch->tex_info->flags | p_batch->flags;

RID pipeline;
PipelineKey pipeline_key;
Expand Down Expand Up @@ -3161,11 +3169,11 @@ void RendererCanvasRenderRD::_prepare_batch_texture_info(RID p_texture, TextureS

// cache values to be copied to instance data
if (info.specular_color.a < 0.999) {
p_info->flags |= FLAGS_DEFAULT_SPECULAR_MAP_USED;
p_info->flags |= BATCH_FLAGS_DEFAULT_SPECULAR_MAP_USED;
}

if (info.use_normal) {
p_info->flags |= FLAGS_DEFAULT_NORMAL_MAP_USED;
p_info->flags |= BATCH_FLAGS_DEFAULT_NORMAL_MAP_USED;
}

uint8_t a = uint8_t(CLAMP(info.specular_color.a * 255.0, 0.0, 255.0));
Expand Down
47 changes: 23 additions & 24 deletions servers/rendering/renderer_rd/renderer_canvas_render_rd.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,31 +65,31 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
};

enum {
INSTANCE_FLAGS_LIGHT_COUNT_SHIFT = 0, // 4 bits for light count.

FLAGS_INSTANCING_MASK = 0x7F,
FLAGS_INSTANCING_HAS_COLORS = (1 << 7),
FLAGS_INSTANCING_HAS_CUSTOM_DATA = (1 << 8),
INSTANCE_FLAGS_CLIP_RECT_UV = (1 << 4),
INSTANCE_FLAGS_TRANSPOSE_RECT = (1 << 5),
INSTANCE_FLAGS_USE_MSDF = (1 << 6),
INSTANCE_FLAGS_USE_LCD = (1 << 7),

FLAGS_CLIP_RECT_UV = (1 << 9),
FLAGS_TRANSPOSE_RECT = (1 << 10),
INSTANCE_FLAGS_NINEPACH_DRAW_CENTER = (1 << 8),
INSTANCE_FLAGS_NINEPATCH_H_MODE_SHIFT = 9,
INSTANCE_FLAGS_NINEPATCH_V_MODE_SHIFT = 11,

FLAGS_CONVERT_ATTRIBUTES_TO_LINEAR = (1 << 11),

FLAGS_NINEPACH_DRAW_CENTER = (1 << 12),

FLAGS_USE_SKELETON = (1 << 15),
FLAGS_NINEPATCH_H_MODE_SHIFT = 16,
FLAGS_NINEPATCH_V_MODE_SHIFT = 18,
FLAGS_LIGHT_COUNT_SHIFT = 20,
INSTANCE_FLAGS_SHADOW_MASKED_SHIFT = 13, // 16 bits.
};

FLAGS_DEFAULT_NORMAL_MAP_USED = (1 << 24),
FLAGS_DEFAULT_SPECULAR_MAP_USED = (1 << 25),
enum {
BATCH_FLAGS_INSTANCING_MASK = 0x7F,
BATCH_FLAGS_INSTANCING_HAS_COLORS = (1 << 7),
BATCH_FLAGS_INSTANCING_HAS_CUSTOM_DATA = (1 << 8),

FLAGS_USE_MSDF = (1 << 26),
FLAGS_USE_LCD = (1 << 27),
BATCH_FLAGS_DEFAULT_NORMAL_MAP_USED = (1 << 9),
BATCH_FLAGS_DEFAULT_SPECULAR_MAP_USED = (1 << 10),
};

FLAGS_FLIP_H = (1 << 28),
FLAGS_FLIP_V = (1 << 29),
enum {
CANVAS_FLAGS_CONVERT_ATTRIBUTES_TO_LINEAR = (1 << 0),
};

enum {
Expand Down Expand Up @@ -370,7 +370,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
uint32_t base_instance_index;
ShaderSpecialization shader_specialization;
uint32_t specular_shininess;
uint32_t pad;
uint32_t batch_flags;
};

// TextureState is used to determine when a new batch is required due to a change of texture state.
Expand Down Expand Up @@ -508,6 +508,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
uint32_t mesh_instance_count;
};
bool has_blend = false;
uint32_t flags = 0;
};

HashMap<TextureState, TextureInfo, HashableHasher<TextureState>> texture_info_map;
Expand Down Expand Up @@ -535,7 +536,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender {

uint32_t directional_light_count;
float tex_to_sdf;
uint32_t pad1;
uint32_t flags;
uint32_t pad2;
};

Expand Down Expand Up @@ -596,9 +597,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
struct RenderTarget {
// Current render target for the canvas.
RID render_target;
// The base flags for each InstanceData, derived from the render target.
// Either FLAGS_CONVERT_ATTRIBUTES_TO_LINEAR or 0
uint32_t base_flags = 0;
bool use_linear_colors = false;
};

inline RID _get_pipeline_specialization_or_ubershader(CanvasShaderData *p_shader_data, PipelineKey &r_pipeline_key, PushConstant &r_push_constant, RID p_mesh_instance = RID(), void *p_surface = nullptr, uint32_t p_surface_index = 0, RID *r_vertex_array = nullptr);
Expand Down
Loading

0 comments on commit c9c3541

Please sign in to comment.