summaryrefslogtreecommitdiff
path: root/servers/visual/rasterizer
diff options
context:
space:
mode:
Diffstat (limited to 'servers/visual/rasterizer')
-rw-r--r--servers/visual/rasterizer/rasterizer.h15
-rw-r--r--servers/visual/rasterizer/rasterizer_canvas_rd.cpp562
-rw-r--r--servers/visual/rasterizer/rasterizer_canvas_rd.h79
-rw-r--r--servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.cpp50
-rw-r--r--servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.h22
-rw-r--r--servers/visual/rasterizer/shader_rd.cpp6
-rw-r--r--servers/visual/rasterizer/shader_rd.h3
-rw-r--r--servers/visual/rasterizer/shaders/SCsub1
-rw-r--r--servers/visual/rasterizer/shaders/canvas.glsl58
-rw-r--r--servers/visual/rasterizer/shaders/canvas_occlusion_fix.glsl99
-rw-r--r--servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl47
11 files changed, 493 insertions, 449 deletions
diff --git a/servers/visual/rasterizer/rasterizer.h b/servers/visual/rasterizer/rasterizer.h
index 88520a6a79..46695f5647 100644
--- a/servers/visual/rasterizer/rasterizer.h
+++ b/servers/visual/rasterizer/rasterizer.h
@@ -618,7 +618,6 @@ public:
RID canvas;
bool use_shadow;
int shadow_buffer_size;
- float shadow_gradient_length;
VS::CanvasLightShadowFilter shadow_filter;
Color shadow_color;
float shadow_smooth;
@@ -638,10 +637,12 @@ public:
Light *mask_next_ptr;
RID light_internal;
+ uint64_t version;
int32_t render_index_cache;
Light() {
+ version = 0;
enabled = true;
color = Color(1, 1, 1);
shadow_color = Color(0, 0, 0, 0);
@@ -661,7 +662,6 @@ public:
filter_next_ptr = NULL;
use_shadow = false;
shadow_buffer_size = 2048;
- shadow_gradient_length = 0;
shadow_filter = VS::CANVAS_LIGHT_FILTER_NONE;
shadow_smooth = 0.0;
render_index_cache = -1;
@@ -1064,6 +1064,13 @@ public:
return command;
}
+ struct CustomData {
+
+ virtual ~CustomData() {}
+ };
+
+ mutable CustomData *custom_data; //implementation dependent
+
void clear() {
Command *c = commands;
while (c) {
@@ -1112,6 +1119,7 @@ public:
light_masked = false;
update_when_visible = false;
z_final = 0;
+ custom_data = NULL;
}
virtual ~Item() {
clear();
@@ -1119,6 +1127,9 @@ public:
memfree(blocks[i].memory);
}
if (copy_back_buffer) memdelete(copy_back_buffer);
+ if (custom_data) {
+ memdelete(custom_data);
+ }
}
};
diff --git a/servers/visual/rasterizer/rasterizer_canvas_rd.cpp b/servers/visual/rasterizer/rasterizer_canvas_rd.cpp
index d09b353007..93f905b72b 100644
--- a/servers/visual/rasterizer/rasterizer_canvas_rd.cpp
+++ b/servers/visual/rasterizer/rasterizer_canvas_rd.cpp
@@ -225,42 +225,34 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
// that need to be created for these formats.
uint32_t vertex_count = p_points.size();
- uint32_t base_offset = 0;
uint32_t stride = 2; //vertices always repeat
- if ((uint32_t)p_colors.size() == vertex_count) {
+ if ((uint32_t)p_colors.size() == vertex_count || p_colors.size() == 1) {
stride += 4;
- } else {
- base_offset += 4;
}
if ((uint32_t)p_uvs.size() == vertex_count) {
stride += 2;
- } else {
- base_offset += 2;
}
if ((uint32_t)p_bones.size() == vertex_count * 4) {
stride += 4;
- } else {
- base_offset += 4;
}
if ((uint32_t)p_weights.size() == vertex_count * 4) {
stride += 4;
- } else {
- base_offset += 4;
}
- uint32_t buffer_size = base_offset + stride * p_points.size();
+ uint32_t buffer_size = stride * p_points.size();
PoolVector<uint8_t> polygon_buffer;
polygon_buffer.resize(buffer_size * sizeof(float));
Vector<RD::VertexDescription> descriptions;
descriptions.resize(5);
+ Vector<RID> buffers;
+ buffers.resize(5);
{
PoolVector<uint8_t>::Read r = polygon_buffer.read();
float *fptr = (float *)r.ptr();
uint32_t *uptr = (uint32_t *)r.ptr();
- uint32_t single_offset = 0;
-
+ uint32_t base_offset = 0;
{ //vertices
RD::VertexDescription vd;
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
@@ -281,7 +273,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
}
//colors
- if ((uint32_t)p_colors.size() == vertex_count) {
+ if ((uint32_t)p_colors.size() == vertex_count || p_colors.size() == 1) {
RD::VertexDescription vd;
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
vd.offset = base_offset * sizeof(float);
@@ -290,31 +282,34 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
descriptions.write[1] = vd;
- const Color *color_ptr = p_colors.ptr();
+ if (p_colors.size() == 1) {
+ Color color = p_colors[0];
+ for (uint32_t i = 0; i < vertex_count; i++) {
+ fptr[base_offset + i * stride + 0] = color.r;
+ fptr[base_offset + i * stride + 1] = color.g;
+ fptr[base_offset + i * stride + 2] = color.b;
+ fptr[base_offset + i * stride + 3] = color.a;
+ }
+ } else {
+ const Color *color_ptr = p_colors.ptr();
- for (uint32_t i = 0; i < vertex_count; i++) {
- fptr[base_offset + i * stride + 0] = color_ptr[i].r;
- fptr[base_offset + i * stride + 1] = color_ptr[i].g;
- fptr[base_offset + i * stride + 2] = color_ptr[i].b;
- fptr[base_offset + i * stride + 3] = color_ptr[i].a;
+ for (uint32_t i = 0; i < vertex_count; i++) {
+ fptr[base_offset + i * stride + 0] = color_ptr[i].r;
+ fptr[base_offset + i * stride + 1] = color_ptr[i].g;
+ fptr[base_offset + i * stride + 2] = color_ptr[i].b;
+ fptr[base_offset + i * stride + 3] = color_ptr[i].a;
+ }
}
base_offset += 4;
} else {
RD::VertexDescription vd;
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
- vd.offset = single_offset * sizeof(float);
+ vd.offset = 0;
vd.location = VS::ARRAY_COLOR;
vd.stride = 0;
descriptions.write[1] = vd;
-
- Color color = p_colors.size() ? p_colors[0] : Color(1, 1, 1, 1);
- fptr[single_offset + 0] = color.r;
- fptr[single_offset + 1] = color.g;
- fptr[single_offset + 2] = color.b;
- fptr[single_offset + 3] = color.a;
-
- single_offset += 4;
+ buffers.write[1] = polygon_buffers.default_color_buffer;
}
//uvs
@@ -337,17 +332,12 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
} else {
RD::VertexDescription vd;
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
- vd.offset = single_offset * sizeof(float);
+ vd.offset = 0;
vd.location = VS::ARRAY_TEX_UV;
vd.stride = 0;
descriptions.write[2] = vd;
-
- Vector2 uv;
- fptr[single_offset + 0] = uv.x;
- fptr[single_offset + 1] = uv.y;
-
- single_offset += 2;
+ buffers.write[2] = polygon_buffers.default_uv_buffer;
}
//bones
@@ -373,17 +363,12 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
} else {
RD::VertexDescription vd;
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
- vd.offset = single_offset * sizeof(float);
+ vd.offset = 0;
vd.location = VS::ARRAY_BONES;
vd.stride = 0;
descriptions.write[3] = vd;
-
- uptr[single_offset + 0] = 0;
- uptr[single_offset + 1] = 0;
- uptr[single_offset + 2] = 0;
- uptr[single_offset + 3] = 0;
- single_offset += 4;
+ buffers.write[3] = polygon_buffers.default_bone_buffer;
}
//bones
@@ -409,22 +394,16 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
} else {
RD::VertexDescription vd;
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
- vd.offset = single_offset * sizeof(float);
+ vd.offset = 0;
vd.location = VS::ARRAY_WEIGHTS;
vd.stride = 0;
descriptions.write[4] = vd;
-
- fptr[single_offset + 0] = 0.0;
- fptr[single_offset + 1] = 0.0;
- fptr[single_offset + 2] = 0.0;
- fptr[single_offset + 3] = 0.0;
- single_offset += 4;
+ buffers.write[4] = polygon_buffers.default_weight_buffer;
}
//check that everything is as it should be
- ERR_FAIL_COND_V(single_offset != (base_offset - stride), 0);
- ERR_FAIL_COND_V(((base_offset - stride) + stride * vertex_count) != buffer_size, 0);
+ ERR_FAIL_COND_V(base_offset != stride, 0); //bug
}
RD::VertexFormatID vertex_id = RD::get_singleton()->vertex_format_create(descriptions);
@@ -432,11 +411,12 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
PolygonBuffers pb;
pb.vertex_buffer = RD::get_singleton()->vertex_buffer_create(polygon_buffer.size(), polygon_buffer);
- Vector<RID> buffers;
- buffers.resize(descriptions.size());
for (int i = 0; i < descriptions.size(); i++) {
- buffers.write[i] = pb.vertex_buffer;
+ if (buffers[i] == RID()) { //if put in vertex, use as vertex
+ buffers.write[i] = pb.vertex_buffer;
+ }
}
+
pb.vertex_array = RD::get_singleton()->vertex_array_create(p_points.size(), vertex_id, buffers);
if (p_indices.size()) {
@@ -508,9 +488,10 @@ Size2i RasterizerCanvasRD::_bind_texture_binding(TextureBindingID p_binding, RD:
}
////////////////////
-void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_item, RenderTargetFormat p_render_target_format, RD::TextureSamples p_samples, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights) {
+void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_item, RD::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights) {
//create an empty push constant
+
PushConstant push_constant;
Transform2D base_transform = p_canvas_transform_inverse * p_item->final_transform;
_update_transform_2d_to_mat2x3(base_transform, push_constant.world);
@@ -538,30 +519,190 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
uint32_t base_flags = 0;
+ bool light_uniform_set_dirty = false;
+
+ if (!p_item->custom_data) {
+ p_item->custom_data = memnew(ItemStateData);
+ light_uniform_set_dirty = true;
+ }
+
+ ItemStateData *state_data = (ItemStateData *)p_item->custom_data;
+
+ Light *light_cache[DEFAULT_MAX_LIGHTS_PER_ITEM];
+ uint16_t light_count = 0;
+ PipelineLightMode light_mode;
+
{
+
Light *light = p_lights;
- uint16_t light_count = 0;
while (light) {
if (light->render_index_cache >= 0 && p_item->light_mask & light->item_mask && p_item->z_final >= light->z_min && p_item->z_final <= light->z_max && p_item->global_rect_cache.intersects_transformed(light->xform_cache, light->rect_cache)) {
uint32_t light_index = light->render_index_cache;
push_constant.lights[light_count >> 2] |= light_index << ((light_count & 3) * 8);
+
+ if (!light_uniform_set_dirty && (state_data->light_cache[light_count].light != light || state_data->light_cache[light_count].light_version != light->version)) {
+ light_uniform_set_dirty = true;
+ }
+
+ light_cache[light_count] = light;
+
light_count++;
if (light->mode == VS::CANVAS_LIGHT_MODE_MASK) {
base_flags |= FLAGS_USING_LIGHT_MASK;
}
- if (light_count == MAX_LIGHTS_PER_ITEM) {
+ if (light_count == state.max_lights_per_item) {
break;
}
}
light = light->next_ptr;
}
+ if (light_count != state_data->light_cache_count) {
+ light_uniform_set_dirty = true;
+ }
base_flags |= light_count << FLAGS_LIGHT_COUNT_SHIFT;
}
+ if (light_count) {
+
+ //validate and update lighs if they are being used
+ bool invalid_uniform = state_data->light_uniform_set.is_valid() && !RD::get_singleton()->uniform_set_is_valid(state_data->light_uniform_set);
+
+ if (state_data->light_uniform_set.is_null() || invalid_uniform || light_uniform_set_dirty) {
+ //recreate uniform set
+ if (state_data->light_uniform_set.is_valid() && !invalid_uniform) {
+ RD::get_singleton()->free(state_data->light_uniform_set);
+ }
+
+ state_data->light_uniform_set = RID();
+
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 0;
+ u.ids.push_back(state.lights_uniform_buffer);
+ uniforms.push_back(u);
+ }
+
+ {
+
+ RD::Uniform u_lights;
+ u_lights.type = RD::UNIFORM_TYPE_TEXTURE;
+ u_lights.binding = 1;
+
+ RD::Uniform u_shadows;
+ u_shadows.type = RD::UNIFORM_TYPE_TEXTURE;
+ u_shadows.binding = 2;
+
+ //lights
+ for (uint32_t i = 0; i < state.max_lights_per_item; i++) {
+ if (i < light_count) {
+
+ CanvasLight *cl = canvas_light_owner.getornull(light_cache[i]->light_internal);
+ ERR_CONTINUE(!cl);
+
+ RID rd_texture;
+
+ if (cl->texture.is_valid()) {
+ rd_texture = storage->texture_get_rd_texture(cl->texture);
+ }
+ if (rd_texture.is_valid()) {
+ u_lights.ids.push_back(rd_texture);
+ } else {
+ u_lights.ids.push_back(default_textures.white_texture);
+ }
+ if (cl->shadow.texture.is_valid()) {
+ u_shadows.ids.push_back(cl->shadow.texture);
+ } else {
+ u_shadows.ids.push_back(default_textures.black_texture);
+ }
+ } else {
+ u_lights.ids.push_back(default_textures.white_texture);
+ u_shadows.ids.push_back(default_textures.black_texture);
+ }
+ }
+
+ uniforms.push_back(u_lights);
+ uniforms.push_back(u_shadows);
+ }
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 3;
+ u.ids.push_back(state.shadow_sampler);
+ uniforms.push_back(u);
+ }
+
+ state_data->light_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader_light, 3);
+ }
+
+ RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, state_data->light_uniform_set, 3);
+ light_mode = PIPELINE_LIGHT_MODE_ENABLED;
+ } else {
+ light_mode = PIPELINE_LIGHT_MODE_DISABLED;
+ }
+
+ {
+ //state uniform
+ bool invalid_uniform = state_data->state_uniform_set.is_valid() && !RD::get_singleton()->uniform_set_is_valid(state_data->state_uniform_set);
+
+ if (state_data->state_uniform_set.is_null() || invalid_uniform) {
+ if (state_data->state_uniform_set.is_valid() && !invalid_uniform) {
+ RD::get_singleton()->free(state_data->state_uniform_set);
+ }
+ state_data->state_uniform_set = RID();
+
+ Vector<RD::Uniform> uniforms;
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 0;
+ u.ids.push_back(state.canvas_state_buffer);
+ uniforms.push_back(u);
+ }
+
+ if (false && p_item->skeleton.is_valid()) {
+ //bind skeleton stuff
+ } else {
+ //bind default
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 0;
+ u.ids.push_back(state.canvas_state_buffer);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE_BUFFER;
+ u.binding = 1;
+ u.ids.push_back(shader.default_skeleton_texture_buffer);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 2;
+ u.ids.push_back(shader.default_skeleton_uniform_buffer);
+ uniforms.push_back(u);
+ }
+ }
+
+ state_data->state_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader, 2);
+ }
+
+ RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, state_data->state_uniform_set, 2);
+ }
+
PipelineVariants *pipeline_variants = &shader.pipeline_variants;
bool reclip = false;
@@ -579,7 +720,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
//bind pipeline
{
- RID pipeline = pipeline_variants->variants[p_render_target_format][PIPELINE_VARIANT_QUAD].get_render_pipeline(RD::INVALID_ID, p_samples);
+ RID pipeline = pipeline_variants->variants[light_mode][PIPELINE_VARIANT_QUAD].get_render_pipeline(RD::INVALID_ID, p_framebuffer_format);
RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline);
}
@@ -679,7 +820,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
//bind pipeline
{
- RID pipeline = pipeline_variants->variants[p_render_target_format][PIPELINE_VARIANT_NINEPATCH].get_render_pipeline(RD::INVALID_ID, p_samples);
+ RID pipeline = pipeline_variants->variants[light_mode][PIPELINE_VARIANT_NINEPATCH].get_render_pipeline(RD::INVALID_ID, p_framebuffer_format);
RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline);
}
@@ -761,7 +902,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
{
static const PipelineVariant variant[VS::PRIMITIVE_MAX] = { PIPELINE_VARIANT_ATTRIBUTE_POINTS, PIPELINE_VARIANT_ATTRIBUTE_LINES, PIPELINE_VARIANT_ATTRIBUTE_TRIANGLES };
ERR_CONTINUE(polygon->primitive < 0 || polygon->primitive >= VS::PRIMITIVE_MAX);
- RID pipeline = pipeline_variants->variants[p_render_target_format][variant[polygon->primitive]].get_render_pipeline(pb->vertex_format_id, p_samples);
+ RID pipeline = pipeline_variants->variants[light_mode][variant[polygon->primitive]].get_render_pipeline(pb->vertex_format_id, p_framebuffer_format);
RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline);
}
@@ -815,7 +956,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
{
static const PipelineVariant variant[4] = { PIPELINE_VARIANT_PRIMITIVE_POINTS, PIPELINE_VARIANT_PRIMITIVE_LINES, PIPELINE_VARIANT_PRIMITIVE_TRIANGLES, PIPELINE_VARIANT_PRIMITIVE_TRIANGLES };
ERR_CONTINUE(primitive->point_count == 0 || primitive->point_count > 4);
- RID pipeline = pipeline_variants->variants[p_render_target_format][variant[primitive->point_count - 1]].get_render_pipeline(RD::INVALID_ID, p_samples);
+ RID pipeline = pipeline_variants->variants[light_mode][variant[primitive->point_count - 1]].get_render_pipeline(RD::INVALID_ID, p_framebuffer_format);
RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline);
}
@@ -1184,7 +1325,6 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count,
Item *current_clip = NULL;
- RenderTargetFormat render_target_format = RENDER_TARGET_FORMAT_8_BIT_INT;
Transform2D canvas_transform_inverse = p_canvas_transform_inverse;
RID framebuffer = storage->render_target_get_rd_framebuffer(p_to_render_target);
@@ -1197,10 +1337,9 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count,
storage->render_target_disable_clear_request(p_to_render_target);
}
#warning TODO obtain from framebuffer format eventually when this is implemented
- RD::TextureSamples texture_samples = RD::TEXTURE_SAMPLES_1;
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, clear ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_KEEP_COLOR, RD::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH, clear_colors);
+ RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer);
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, state.canvas_state_uniform_set, 3);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, clear ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_KEEP_COLOR, RD::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH, clear_colors);
for (int i = 0; i < p_item_count; i++) {
@@ -1221,104 +1360,18 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count,
}
}
- if (false) { //not skeleton
-
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, shader.default_skeleton_uniform_set, 1);
- }
-
- _render_item(draw_list, ci, render_target_format, texture_samples, canvas_transform_inverse, current_clip, p_lights);
+ _render_item(draw_list, ci, fb_format, canvas_transform_inverse, current_clip, p_lights);
}
RD::get_singleton()->draw_list_end();
}
-void RasterizerCanvasRD::_update_canvas_state_uniform_set() {
-
- if (state.canvas_state_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(state.canvas_state_uniform_set)) {
- return; //nothing to update
- }
-
- Vector<RD::Uniform> uniforms;
-
- {
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 0;
- u.ids.push_back(state.canvas_state_buffer);
- uniforms.push_back(u);
- }
-
- {
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 1;
- u.ids.push_back(state.lights_uniform_buffer);
- uniforms.push_back(u);
- }
-
- {
-
- RD::Uniform u_lights;
- u_lights.type = RD::UNIFORM_TYPE_TEXTURE;
- u_lights.binding = 2;
-
- RD::Uniform u_shadows;
- u_shadows.type = RD::UNIFORM_TYPE_TEXTURE;
- u_shadows.binding = 3;
-
- //lights
- for (uint32_t i = 0; i < MAX_LIGHT_TEXTURES; i++) {
- if (i < canvas_light_owner.get_rid_count()) {
- CanvasLight *cl = canvas_light_owner.get_rid_by_index(i);
- cl->texture_index = i;
- RID rd_texture;
-
- if (cl->texture.is_valid()) {
- rd_texture = storage->texture_get_rd_texture(cl->texture);
- }
- if (rd_texture.is_valid()) {
- u_lights.ids.push_back(rd_texture);
- } else {
- u_lights.ids.push_back(default_textures.white_texture);
- }
- if (cl->shadow.texture.is_valid()) {
- u_shadows.ids.push_back(cl->shadow.texture);
- } else {
- u_shadows.ids.push_back(default_textures.black_texture);
- }
- } else {
- u_lights.ids.push_back(default_textures.white_texture);
- u_shadows.ids.push_back(default_textures.black_texture);
- }
- }
-
- //in case there are more
- for (uint32_t i = MAX_LIGHT_TEXTURES; i < canvas_light_owner.get_rid_count(); i++) {
- CanvasLight *cl = canvas_light_owner.get_rid_by_index(i);
- cl->texture_index = -1; //make invalid (no texture)
- }
-
- uniforms.push_back(u_lights);
- uniforms.push_back(u_shadows);
- }
-
- {
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 4;
- u.ids.push_back(state.shadow_sampler);
- uniforms.push_back(u);
- }
-
- state.canvas_state_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader, 3); // uses index 3
-}
-
void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform) {
int item_count = 0;
//setup canvas state uniforms if needed
- _update_canvas_state_uniform_set();
+
Transform2D canvas_transform_inverse = p_canvas_transform.affine_inverse();
{
@@ -1356,14 +1409,14 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
while (l) {
- if (index == MAX_RENDER_LIGHTS) {
+ if (index == state.max_lights_per_render) {
l->render_index_cache = -1;
l = l->next_ptr;
continue;
}
CanvasLight *clight = canvas_light_owner.getornull(l->light_internal);
- if (!clight || clight->texture_index < 0) { //unused or invalid texture
+ if (!clight) { //unused or invalid texture
l->render_index_cache = -1;
l = l->next_ptr;
ERR_CONTINUE(!clight);
@@ -1390,7 +1443,7 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
} else {
state.light_uniforms[index].shadow_pixel_size = 1.0;
}
- state.light_uniforms[index].flags = clight->texture_index;
+
state.light_uniforms[index].flags |= l->mode << LIGHT_FLAGS_BLEND_SHIFT;
state.light_uniforms[index].flags |= l->shadow_filter << LIGHT_FLAGS_FILTER_SHIFT;
if (clight->shadow.texture.is_valid()) {
@@ -1439,7 +1492,6 @@ RID RasterizerCanvasRD::light_create() {
CanvasLight canvas_light;
canvas_light.shadow.size = 0;
- canvas_light.texture_index = -1;
return canvas_light_owner.make_rid(canvas_light);
}
@@ -1451,11 +1503,6 @@ void RasterizerCanvasRD::light_set_texture(RID p_rid, RID p_texture) {
}
cl->texture = p_texture;
-
- //canvas state uniform set needs updating
- if (state.canvas_state_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(state.canvas_state_uniform_set)) {
- RD::get_singleton()->free(state.canvas_state_uniform_set);
- }
}
void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable, int p_resolution) {
CanvasLight *cl = canvas_light_owner.getornull(p_rid);
@@ -1506,11 +1553,6 @@ void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable, int p_re
}
cl->shadow.size = p_resolution;
-
- //canvas state uniform set needs updating
- if (state.canvas_state_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(state.canvas_state_uniform_set)) {
- RD::get_singleton()->free(state.canvas_state_uniform_set);
- }
}
void RasterizerCanvasRD::light_update_shadow(RID p_rid, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) {
@@ -1831,35 +1873,58 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
}
{ //shader variants
+
+ uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
+
+ String global_defines;
+ if (textures_per_stage <= 16) {
+ //ARM pretty much, and very old Intel GPUs under Linux
+ state.max_lights_per_item = 4; //sad
+ global_defines += "#define MAX_LIGHT_TEXTURES 4\n";
+ } else if (textures_per_stage <= 32) {
+ //Apple (Metal)
+ state.max_lights_per_item = 8; //sad
+ global_defines += "#define MAX_LIGHT_TEXTURES 8\n";
+ } else {
+ //Anything else (16 lights per item)
+ state.max_lights_per_item = DEFAULT_MAX_LIGHTS_PER_ITEM;
+ global_defines += "#define MAX_LIGHT_TEXTURES " + itos(DEFAULT_MAX_LIGHTS_PER_ITEM) + "\n";
+ }
+
+ uint32_t uniform_max_size = RD::get_singleton()->limit_get(RD::LIMIT_MAX_UNIFORM_BUFFER_SIZE);
+ if (uniform_max_size < 65536) {
+ //Yes, you guessed right, ARM again
+ state.max_lights_per_render = 64;
+ global_defines += "#define MAX_LIGHTS 64\n";
+ } else {
+ state.max_lights_per_render = DEFAULT_MAX_LIGHTS_PER_RENDER;
+ global_defines += "#define MAX_LIGHTS " + itos(DEFAULT_MAX_LIGHTS_PER_RENDER) + "\n";
+ }
+
+ state.light_uniforms = memnew_arr(LightUniform, state.max_lights_per_render);
Vector<String> variants;
+ //non light variants
variants.push_back(""); //none by default is first variant
variants.push_back("#define USE_NINEPATCH\n"); //ninepatch is the second variant
variants.push_back("#define USE_PRIMITIVE\n"); //primitve is the third
variants.push_back("#define USE_PRIMITIVE\n#define USE_POINT_SIZE\n"); //points need point size
variants.push_back("#define USE_ATTRIBUTES\n"); // attributes for vertex arrays
variants.push_back("#define USE_ATTRIBUTES\n#define USE_POINT_SIZE\n"); //attributes with point size
- shader.canvas_shader.initialize(variants);
+ //light variants
+ variants.push_back("#define USE_LIGHTING\n"); //none by default is first variant
+ variants.push_back("#define USE_LIGHTING\n#define USE_NINEPATCH\n"); //ninepatch is the second variant
+ variants.push_back("#define USE_LIGHTING\n#define USE_PRIMITIVE\n"); //primitve is the third
+ variants.push_back("#define USE_LIGHTING\n#define USE_PRIMITIVE\n#define USE_POINT_SIZE\n"); //points need point size
+ variants.push_back("#define USE_LIGHTING\n#define USE_ATTRIBUTES\n"); // attributes for vertex arrays
+ variants.push_back("#define USE_LIGHTING\n#define USE_ATTRIBUTES\n#define USE_POINT_SIZE\n"); //attributes with point size
- shader.default_version = shader.canvas_shader.version_create();
+ shader.canvas_shader.initialize(variants, global_defines);
- {
- //framebuffer formats
- RD::AttachmentFormat af;
- af.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
- af.samples = RD::TEXTURE_SAMPLES_1;
- af.usage_flags = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_RETRIEVE_BIT;
- Vector<RD::AttachmentFormat> formats;
- formats.push_back(af);
- shader.framebuffer_formats[RENDER_TARGET_FORMAT_8_BIT_INT] = RD::get_singleton()->framebuffer_format_create(formats);
-
- formats.clear();
- af.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
- formats.push_back(af);
- shader.framebuffer_formats[RENDER_TARGET_FORMAT_16_BIT_FLOAT] = RD::get_singleton()->framebuffer_format_create(formats);
- }
+ shader.default_version = shader.canvas_shader.version_create();
+ shader.default_version_rd_shader = shader.canvas_shader.version_get_shader(shader.default_version, SHADER_VARIANT_QUAD);
+ shader.default_version_rd_shader_light = shader.canvas_shader.version_get_shader(shader.default_version, SHADER_VARIANT_QUAD_LIGHT);
- for (int i = 0; i < RENDER_TARGET_FORMAT_MAX; i++) {
- RD::FramebufferFormatID fb_format = shader.framebuffer_formats[i];
+ for (int i = 0; i < PIPELINE_LIGHT_MODE_MAX; i++) {
for (int j = 0; j < PIPELINE_VARIANT_MAX; j++) {
RD::RenderPrimitive primitive[PIPELINE_VARIANT_MAX] = {
RD::RENDER_PRIMITIVE_TRIANGLES,
@@ -1871,23 +1936,31 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
RD::RENDER_PRIMITIVE_LINES,
RD::RENDER_PRIMITIVE_POINTS,
};
- ShaderVariant shader_variants[PIPELINE_VARIANT_MAX] = {
- SHADER_VARIANT_QUAD,
- SHADER_VARIANT_NINEPATCH,
- SHADER_VARIANT_PRIMITIVE,
- SHADER_VARIANT_PRIMITIVE,
- SHADER_VARIANT_PRIMITIVE_POINTS,
- SHADER_VARIANT_ATTRIBUTES,
- SHADER_VARIANT_ATTRIBUTES,
- SHADER_VARIANT_ATTRIBUTES_POINTS
+ ShaderVariant shader_variants[PIPELINE_LIGHT_MODE_MAX][PIPELINE_VARIANT_MAX] = {
+ { //non lit
+ SHADER_VARIANT_QUAD,
+ SHADER_VARIANT_NINEPATCH,
+ SHADER_VARIANT_PRIMITIVE,
+ SHADER_VARIANT_PRIMITIVE,
+ SHADER_VARIANT_PRIMITIVE_POINTS,
+ SHADER_VARIANT_ATTRIBUTES,
+ SHADER_VARIANT_ATTRIBUTES,
+ SHADER_VARIANT_ATTRIBUTES_POINTS },
+ { //lit
+ SHADER_VARIANT_QUAD_LIGHT,
+ SHADER_VARIANT_NINEPATCH_LIGHT,
+ SHADER_VARIANT_PRIMITIVE_LIGHT,
+ SHADER_VARIANT_PRIMITIVE_LIGHT,
+ SHADER_VARIANT_PRIMITIVE_POINTS_LIGHT,
+ SHADER_VARIANT_ATTRIBUTES_LIGHT,
+ SHADER_VARIANT_ATTRIBUTES_LIGHT,
+ SHADER_VARIANT_ATTRIBUTES_POINTS_LIGHT },
};
- RID shader_variant = shader.canvas_shader.version_get_shader(shader.default_version, shader_variants[j]);
- shader.pipeline_variants.variants[i][j].setup(shader_variant, fb_format, primitive[j], RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_blend(), 0);
+ RID shader_variant = shader.canvas_shader.version_get_shader(shader.default_version, shader_variants[i][j]);
+ shader.pipeline_variants.variants[i][j].setup(shader_variant, primitive[j], RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_blend(), 0);
}
}
-
- shader.default_version_rd_shader = shader.canvas_shader.version_get_shader(shader.default_version, 0);
}
{ //shadow rendering
@@ -1901,6 +1974,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
RD::AttachmentFormat af_color;
af_color.format = RD::DATA_FORMAT_R32_SFLOAT;
af_color.usage_flags = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
+ af_color.samples = RenderingDevice::TEXTURE_SAMPLES_64;
attachments.push_back(af_color);
@@ -1908,6 +1982,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
af_depth.format = RD::DATA_FORMAT_D24_UNORM_S8_UINT;
af_depth.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_X8_D24_UNORM_PACK32, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_X8_D24_UNORM_PACK32 : RD::DATA_FORMAT_D32_SFLOAT;
af_depth.usage_flags = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+ af_depth.samples = RenderingDevice::TEXTURE_SAMPLES_64;
attachments.push_back(af_depth);
@@ -1944,7 +2019,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
{ //state allocate
state.canvas_state_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(State::Buffer));
- state.lights_uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(LightUniform) * MAX_RENDER_LIGHTS);
+ state.lights_uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(LightUniform) * state.max_lights_per_render);
RD::SamplerState shadow_sampler_state;
shadow_sampler_state.mag_filter = RD::SAMPLER_FILTER_LINEAR;
@@ -1956,6 +2031,60 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
}
{
+ {
+ PoolVector<uint8_t> colors;
+ colors.resize(sizeof(float) * 4);
+ {
+ PoolVector<uint8_t>::Write w = colors.write();
+ float *fptr = (float *)w.ptr();
+ fptr[0] = 1.0;
+ fptr[1] = 1.0;
+ fptr[2] = 1.0;
+ fptr[3] = 1.0;
+ }
+ polygon_buffers.default_color_buffer = RD::get_singleton()->vertex_buffer_create(colors.size(), colors);
+ }
+
+ {
+ PoolVector<uint8_t> uvs;
+ uvs.resize(sizeof(float) * 2);
+ {
+ PoolVector<uint8_t>::Write w = uvs.write();
+ float *fptr = (float *)w.ptr();
+ fptr[0] = 0.0;
+ fptr[1] = 0.0;
+ }
+ polygon_buffers.default_uv_buffer = RD::get_singleton()->vertex_buffer_create(uvs.size(), uvs);
+ }
+
+ {
+ PoolVector<uint8_t> bones;
+ bones.resize(sizeof(uint32_t) * 4);
+ {
+ PoolVector<uint8_t>::Write w = bones.write();
+ uint32_t *iptr = (uint32_t *)w.ptr();
+ iptr[0] = 0;
+ iptr[1] = 0;
+ iptr[2] = 0;
+ iptr[3] = 0;
+ }
+ polygon_buffers.default_bone_buffer = RD::get_singleton()->vertex_buffer_create(bones.size(), bones);
+ }
+
+ {
+ PoolVector<uint8_t> weights;
+ weights.resize(sizeof(float) * 4);
+ {
+ PoolVector<uint8_t>::Write w = weights.write();
+ float *fptr = (float *)w.ptr();
+ fptr[0] = 0.0;
+ fptr[1] = 0.0;
+ fptr[2] = 0.0;
+ fptr[3] = 0.0;
+ }
+ polygon_buffers.default_weight_buffer = RD::get_singleton()->vertex_buffer_create(weights.size(), weights);
+ }
+
//polygon buffers
polygon_buffers.last_id = 1;
}
@@ -1987,28 +2116,13 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
{ //default skeleton buffer
- shader.default_skeleton_uniform = RD::get_singleton()->uniform_buffer_create(sizeof(SkeletonUniform));
+ shader.default_skeleton_uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SkeletonUniform));
SkeletonUniform su;
_update_transform_2d_to_mat4(Transform2D(), su.skeleton_inverse);
_update_transform_2d_to_mat4(Transform2D(), su.skeleton_transform);
- RD::get_singleton()->buffer_update(shader.default_skeleton_uniform, 0, sizeof(SkeletonUniform), &su);
- }
+ RD::get_singleton()->buffer_update(shader.default_skeleton_uniform_buffer, 0, sizeof(SkeletonUniform), &su);
- { //default material uniform set
- Vector<RD::Uniform> default_material_uniforms;
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 2;
- u.ids.push_back(shader.default_skeleton_uniform);
- default_material_uniforms.push_back(u);
-
- u.ids.clear();
- u.type = RD::UNIFORM_TYPE_TEXTURE_BUFFER;
- u.binding = 1;
- u.ids.push_back(default_textures.default_multimesh_tb);
- default_material_uniforms.push_back(u);
-
- shader.default_skeleton_uniform_set = RD::get_singleton()->uniform_set_create(default_material_uniforms, shader.canvas_shader.version_get_shader(shader.default_version, SHADER_VARIANT_ATTRIBUTES), 2);
+ shader.default_skeleton_texture_buffer = RD::get_singleton()->texture_buffer_create(32, RD::DATA_FORMAT_R32G32B32A32_SFLOAT);
}
ERR_FAIL_COND(sizeof(PushConstant) != 128);
@@ -2021,10 +2135,6 @@ bool RasterizerCanvasRD::free(RID p_rid) {
ERR_FAIL_COND_V(!cl, false);
light_set_use_shadow(p_rid, false, 64);
canvas_light_owner.free(p_rid);
- //canvas state uniform set needs updating
- if (state.canvas_state_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(state.canvas_state_uniform_set)) {
- RD::get_singleton()->free(state.canvas_state_uniform_set);
- }
} else if (occluder_polygon_owner.owns(p_rid)) {
occluder_polygon_set_shape_as_lines(p_rid, PoolVector<Vector2>());
occluder_polygon_owner.free(p_rid);
@@ -2043,10 +2153,6 @@ RasterizerCanvasRD::~RasterizerCanvasRD() {
RD::get_singleton()->free(state.canvas_state_buffer);
}
- if (state.canvas_state_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(state.canvas_state_uniform_set)) {
- RD::get_singleton()->free(state.canvas_state_uniform_set);
- }
-
//bindings
{
@@ -2070,8 +2176,6 @@ RasterizerCanvasRD::~RasterizerCanvasRD() {
//shaders
- RD::get_singleton()->free(shader.default_skeleton_uniform_set);
- RD::get_singleton()->free(shader.default_skeleton_uniform);
shader.canvas_shader.version_free(shader.default_version);
//buffers
diff --git a/servers/visual/rasterizer/rasterizer_canvas_rd.h b/servers/visual/rasterizer/rasterizer_canvas_rd.h
index 81e2815d6f..dfeecddfc1 100644
--- a/servers/visual/rasterizer/rasterizer_canvas_rd.h
+++ b/servers/visual/rasterizer/rasterizer_canvas_rd.h
@@ -6,7 +6,6 @@
#include "servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.h"
#include "servers/visual/rasterizer/shaders/canvas.glsl.gen.h"
#include "servers/visual/rasterizer/shaders/canvas_occlusion.glsl.gen.h"
-#include "servers/visual/rasterizer/shaders/canvas_occlusion_fix.glsl.gen.h"
#include "servers/visual/rendering_device.h"
class RasterizerCanvasRD : public RasterizerCanvas {
@@ -20,15 +19,15 @@ class RasterizerCanvasRD : public RasterizerCanvas {
SHADER_VARIANT_PRIMITIVE_POINTS,
SHADER_VARIANT_ATTRIBUTES,
SHADER_VARIANT_ATTRIBUTES_POINTS,
+ SHADER_VARIANT_QUAD_LIGHT,
+ SHADER_VARIANT_NINEPATCH_LIGHT,
+ SHADER_VARIANT_PRIMITIVE_LIGHT,
+ SHADER_VARIANT_PRIMITIVE_POINTS_LIGHT,
+ SHADER_VARIANT_ATTRIBUTES_LIGHT,
+ SHADER_VARIANT_ATTRIBUTES_POINTS_LIGHT,
SHADER_VARIANT_MAX
};
- enum RenderTargetFormat {
- RENDER_TARGET_FORMAT_8_BIT_INT,
- RENDER_TARGET_FORMAT_16_BIT_FLOAT,
- RENDER_TARGET_FORMAT_MAX
- };
-
enum {
FLAGS_INSTANCING_STRIDE_MASK = 0xF,
FLAGS_INSTANCING_ENABLED = (1 << 4),
@@ -71,8 +70,8 @@ class RasterizerCanvasRD : public RasterizerCanvas {
enum {
MAX_RENDER_ITEMS = 256 * 1024,
MAX_LIGHT_TEXTURES = 1024,
- MAX_LIGHTS_PER_ITEM = 16,
- MAX_RENDER_LIGHTS = 256
+ DEFAULT_MAX_LIGHTS_PER_ITEM = 16,
+ DEFAULT_MAX_LIGHTS_PER_RENDER = 256
};
/****************/
@@ -90,22 +89,28 @@ class RasterizerCanvasRD : public RasterizerCanvas {
PIPELINE_VARIANT_ATTRIBUTE_POINTS,
PIPELINE_VARIANT_MAX
};
+ enum PipelineLightMode {
+ PIPELINE_LIGHT_MODE_DISABLED,
+ PIPELINE_LIGHT_MODE_ENABLED,
+ PIPELINE_LIGHT_MODE_MAX
+ };
+
struct PipelineVariants {
- RenderPipelineVertexFormatCacheRD variants[RENDER_TARGET_FORMAT_MAX][PIPELINE_VARIANT_MAX];
+ RenderPipelineVertexFormatCacheRD variants[PIPELINE_LIGHT_MODE_MAX][PIPELINE_VARIANT_MAX];
};
struct {
CanvasShaderRD canvas_shader;
- RD::FramebufferFormatID framebuffer_formats[RENDER_TARGET_FORMAT_MAX];
RID default_version;
RID default_version_rd_shader;
+ RID default_version_rd_shader_light;
RID quad_index_buffer;
RID quad_index_array;
PipelineVariants pipeline_variants;
// default_skeleton uniform set
- RID default_skeleton_uniform;
- RID default_skeleton_uniform_set;
+ RID default_skeleton_uniform_buffer;
+ RID default_skeleton_texture_buffer;
} shader;
@@ -194,6 +199,10 @@ class RasterizerCanvasRD : public RasterizerCanvas {
struct {
HashMap<PolygonID, PolygonBuffers> polygons;
PolygonID last_id;
+ RID default_color_buffer;
+ RID default_uv_buffer;
+ RID default_bone_buffer;
+ RID default_weight_buffer;
} polygon_buffers;
/********************/
@@ -214,7 +223,6 @@ class RasterizerCanvasRD : public RasterizerCanvas {
struct CanvasLight {
- int32_t texture_index;
RID texture;
struct {
int size;
@@ -256,9 +264,8 @@ class RasterizerCanvasRD : public RasterizerCanvas {
float position[2];
uint32_t flags; //index to light texture
float height;
- float shadow_softness;
float shadow_pixel_size;
- float pad[2];
+ float pad[3];
};
RID_Owner<OccluderPolygon> occluder_polygon_owner;
@@ -277,6 +284,36 @@ class RasterizerCanvasRD : public RasterizerCanvas {
//state that does not vary across rendering all items
+ struct ItemStateData : public Item::CustomData {
+
+ struct LightCache {
+ uint64_t light_version;
+ Light *light;
+ };
+
+ LightCache light_cache[DEFAULT_MAX_LIGHTS_PER_ITEM];
+ uint32_t light_cache_count;
+ RID light_uniform_set;
+ RID state_uniform_set;
+ ItemStateData() {
+
+ for (int i = 0; i < DEFAULT_MAX_LIGHTS_PER_ITEM; i++) {
+ light_cache[i].light_version = 0;
+ light_cache[i].light = NULL;
+ }
+ light_cache_count = 0xFFFFFFFF;
+ }
+
+ ~ItemStateData() {
+ if (light_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(light_uniform_set)) {
+ RD::get_singleton()->free(light_uniform_set);
+ }
+ if (state_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(state_uniform_set)) {
+ RD::get_singleton()->free(state_uniform_set);
+ }
+ }
+ };
+
struct State {
//state buffer
@@ -289,14 +326,14 @@ class RasterizerCanvasRD : public RasterizerCanvas {
//uint32_t pad[3];
};
- LightUniform light_uniforms[MAX_RENDER_LIGHTS];
+ LightUniform *light_uniforms;
RID lights_uniform_buffer;
RID canvas_state_buffer;
RID shadow_sampler;
- //uniform set for all the above
- RID canvas_state_uniform_set;
+ uint32_t max_lights_per_render;
+ uint32_t max_lights_per_item;
} state;
struct PushConstant {
@@ -331,7 +368,7 @@ class RasterizerCanvasRD : public RasterizerCanvas {
Item *items[MAX_RENDER_ITEMS];
Size2i _bind_texture_binding(TextureBindingID p_binding, RenderingDevice::DrawListID p_draw_list, uint32_t &flags);
- void _render_item(RenderingDevice::DrawListID p_draw_list, const Item *p_item, RenderTargetFormat p_render_target_format, RenderingDevice::TextureSamples p_samples, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights);
+ void _render_item(RenderingDevice::DrawListID p_draw_list, const Item *p_item, RenderingDevice::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights);
void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights);
_FORCE_INLINE_ void _update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4);
@@ -342,8 +379,6 @@ class RasterizerCanvasRD : public RasterizerCanvas {
_FORCE_INLINE_ void _update_specular_shininess(const Color &p_transform, uint32_t *r_ss);
- void _update_canvas_state_uniform_set();
-
public:
TextureBindingID request_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, VS::CanvasItemTextureFilter p_filter, VS::CanvasItemTextureRepeat p_repeat, RID p_multimesh);
void free_texture_binding(TextureBindingID p_binding);
diff --git a/servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.cpp b/servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.cpp
index be2aa95c34..2c2d6e9ca0 100644
--- a/servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.cpp
+++ b/servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.cpp
@@ -1,43 +1,39 @@
#include "render_pipeline_vertex_format_cache_rd.h"
#include "core/os/memory.h"
-RID RenderPipelineVertexFormatCacheRD::_generate_version(RD::VertexFormatID p_format_id, RenderingDevice::TextureSamples p_samples) {
+RID RenderPipelineVertexFormatCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id) {
- RD::PipelineMultisampleState multisample_state_version;
- if (p_samples != RD::TEXTURE_SAMPLES_1) {
- multisample_state_version = multisample_state;
- multisample_state_version.sample_count = p_samples;
- }
- RID pipeline = RD::get_singleton()->render_pipeline_create(shader, framebuffer_format, p_format_id, render_primitive, rasterization_state, multisample_state, depth_stencil_state, blend_state, dynamic_state_flags);
+ RD::PipelineMultisampleState multisample_state_version = multisample_state;
+ multisample_state_version.sample_count = RD::get_singleton()->framebuffer_format_get_texture_samples(p_framebuffer_format_id);
+
+ RID pipeline = RD::get_singleton()->render_pipeline_create(shader, p_framebuffer_format_id, p_vertex_format_id, render_primitive, rasterization_state, multisample_state_version, depth_stencil_state, blend_state, dynamic_state_flags);
ERR_FAIL_COND_V(pipeline.is_null(), RID());
- versions[p_samples] = (Version *)memrealloc(versions[p_samples], sizeof(Version) * (version_count[p_samples] + 1));
- versions[p_samples][version_count[p_samples]].format_id = p_format_id;
- versions[p_samples][version_count[p_samples]].pipeline = pipeline;
- version_count[p_samples]++;
+ versions = (Version *)memrealloc(versions, sizeof(Version) * (version_count + 1));
+ versions[version_count].framebuffer_id = p_framebuffer_format_id;
+ versions[version_count].vertex_id= p_vertex_format_id;
+ versions[version_count].pipeline = pipeline;
+ version_count++;
return pipeline;
}
void RenderPipelineVertexFormatCacheRD::_clear() {
- for (int v = 0; v < RD::TEXTURE_SAMPLES_MAX; v++) {
- if (versions[v]) {
- for (uint32_t i = 0; i < version_count[v]; i++) {
- //shader may be gone, so this may not be valid
- if (RD::get_singleton()->render_pipeline_is_valid(versions[v][i].pipeline)) {
- RD::get_singleton()->free(versions[v][i].pipeline);
- }
+ if (versions) {
+ for (uint32_t i = 0; i < version_count; i++) {
+ //shader may be gone, so this may not be valid
+ if (RD::get_singleton()->render_pipeline_is_valid(versions[i].pipeline)) {
+ RD::get_singleton()->free(versions[i].pipeline);
}
- version_count[v] = 0;
- memfree(versions[v]);
- versions[v] = NULL;
}
+ version_count = 0;
+ memfree(versions);
+ versions = NULL;
}
}
-void RenderPipelineVertexFormatCacheRD::setup(RID p_shader, RD::FramebufferFormatID p_framebuffer_format, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags) {
+void RenderPipelineVertexFormatCacheRD::setup(RID p_shader, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags) {
ERR_FAIL_COND(p_shader.is_null());
shader = p_shader;
- framebuffer_format = p_framebuffer_format;
render_primitive = p_primitive;
rasterization_state = p_rasterization_state;
multisample_state = p_multisample;
@@ -49,14 +45,12 @@ void RenderPipelineVertexFormatCacheRD::setup(RID p_shader, RD::FramebufferForma
void RenderPipelineVertexFormatCacheRD::update_shader(RID p_shader) {
ERR_FAIL_COND(p_shader.is_null());
_clear();
- setup(p_shader, framebuffer_format, render_primitive, rasterization_state, multisample_state, depth_stencil_state, blend_state, dynamic_state_flags);
+ setup(p_shader, render_primitive, rasterization_state, multisample_state, depth_stencil_state, blend_state, dynamic_state_flags);
}
RenderPipelineVertexFormatCacheRD::RenderPipelineVertexFormatCacheRD() {
- for (int i = 0; i < RD::TEXTURE_SAMPLES_MAX; i++) {
- version_count[i] = 0;
- versions[i] = NULL;
- }
+ version_count = 0;
+ versions = NULL;
}
RenderPipelineVertexFormatCacheRD::~RenderPipelineVertexFormatCacheRD() {
diff --git a/servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.h b/servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.h
index 02b34c3a1b..cdbfda05f1 100644
--- a/servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.h
+++ b/servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.h
@@ -16,29 +16,29 @@ class RenderPipelineVertexFormatCacheRD {
int dynamic_state_flags;
struct Version {
- RD::VertexFormatID format_id;
+ RD::VertexFormatID vertex_id;
+ RD::FramebufferFormatID framebuffer_id;
RID pipeline;
};
- Version *versions[RD::TEXTURE_SAMPLES_MAX];
- uint32_t version_count[RD::TEXTURE_SAMPLES_MAX];
+ Version *versions;
+ uint32_t version_count;
- RID _generate_version(RD::VertexFormatID p_format_id, RD::TextureSamples p_samples);
+ RID _generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id);
void _clear();
public:
- void setup(RID p_shader, RD::FramebufferFormatID p_framebuffer_format, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0);
+ void setup(RID p_shader, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0);
void update_shader(RID p_shader);
- _FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_format_id, RD::TextureSamples p_samples) {
- ERR_FAIL_INDEX_V(p_samples, RD::TEXTURE_SAMPLES_MAX, RID());
- for (uint32_t i = 0; i < version_count[p_samples]; i++) {
- if (versions[p_samples][i].format_id == p_format_id) {
- return versions[p_samples][i].pipeline;
+ _FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id) {
+ for (uint32_t i = 0; i < version_count; i++) {
+ if (versions[i].vertex_id == p_vertex_format_id && versions[i].framebuffer_id == p_framebuffer_format_id) {
+ return versions[i].pipeline;
}
}
- return _generate_version(p_format_id, p_samples);
+ return _generate_version(p_vertex_format_id, p_framebuffer_format_id);
}
RenderPipelineVertexFormatCacheRD();
diff --git a/servers/visual/rasterizer/shader_rd.cpp b/servers/visual/rasterizer/shader_rd.cpp
index 9bc3442dd2..1a62a32c4d 100644
--- a/servers/visual/rasterizer/shader_rd.cpp
+++ b/servers/visual/rasterizer/shader_rd.cpp
@@ -180,7 +180,9 @@ void ShaderRD::_compile_version(Version *p_version) {
builder.append(vertex_codev.get_data()); // version info (if exists)
builder.append("\n"); //make sure defines begin at newline
+ builder.append(general_defines.get_data());
builder.append(variant_defines[i].get_data());
+
for (int j = 0; j < p_version->custom_defines.size(); j++) {
builder.append(p_version->custom_defines[j].get_data());
}
@@ -214,6 +216,7 @@ void ShaderRD::_compile_version(Version *p_version) {
builder.append(fragment_codev.get_data()); // version info (if exists)
builder.append("\n"); //make sure defines begin at newline
+ builder.append(general_defines.get_data());
builder.append(variant_defines[i].get_data());
for (int j = 0; j < p_version->custom_defines.size(); j++) {
builder.append(p_version->custom_defines[j].get_data());
@@ -307,9 +310,10 @@ bool ShaderRD::version_free(RID p_version) {
return true;
}
-void ShaderRD::initialize(const Vector<String> &p_variant_defines) {
+void ShaderRD::initialize(const Vector<String> &p_variant_defines, const String &p_general_defines) {
ERR_FAIL_COND(variant_defines.size());
ERR_FAIL_COND(p_variant_defines.size() == 0);
+ general_defines = p_general_defines.utf8();
for (int i = 0; i < p_variant_defines.size(); i++) {
variant_defines.push_back(p_variant_defines[i].utf8());
diff --git a/servers/visual/rasterizer/shader_rd.h b/servers/visual/rasterizer/shader_rd.h
index 814c87d281..c7a8cdaa37 100644
--- a/servers/visual/rasterizer/shader_rd.h
+++ b/servers/visual/rasterizer/shader_rd.h
@@ -44,6 +44,7 @@
class ShaderRD {
//versions
+ CharString general_defines;
Vector<CharString> variant_defines;
int vertex_code_start;
@@ -114,7 +115,7 @@ public:
bool version_free(RID p_version);
- void initialize(const Vector<String> &p_variant_defines);
+ void initialize(const Vector<String> &p_variant_defines, const String &p_general_defines = "");
virtual ~ShaderRD();
};
diff --git a/servers/visual/rasterizer/shaders/SCsub b/servers/visual/rasterizer/shaders/SCsub
index ef1df0c203..37290e997f 100644
--- a/servers/visual/rasterizer/shaders/SCsub
+++ b/servers/visual/rasterizer/shaders/SCsub
@@ -5,4 +5,3 @@ Import('env')
if 'RD_GLSL' in env['BUILDERS']:
env.RD_GLSL('canvas.glsl');
env.RD_GLSL('canvas_occlusion.glsl');
- env.RD_GLSL('canvas_occlusion_fix.glsl');
diff --git a/servers/visual/rasterizer/shaders/canvas.glsl b/servers/visual/rasterizer/shaders/canvas.glsl
index defe8630be..8d36a2e3ea 100644
--- a/servers/visual/rasterizer/shaders/canvas.glsl
+++ b/servers/visual/rasterizer/shaders/canvas.glsl
@@ -426,8 +426,11 @@ FRAGMENT_SHADER_CODE
}
color*=canvas_data.canvas_modulation;
-
- for(uint i=0;i<light_count;i++) {
+#ifdef USE_LIGHTING
+ for(uint i=0;i<MAX_LIGHT_TEXTURES;i++) {
+ if (i>=light_count) {
+ break;
+ }
uint light_base;
if (i<8) {
if (i<4) {
@@ -445,16 +448,8 @@ FRAGMENT_SHADER_CODE
light_base>>=(i&3)*8;
light_base&=0xFF;
-#define LIGHT_FLAGS_BLEND_MASK (3<<16)
-#define LIGHT_FLAGS_BLEND_MODE_ADD (0<<16)
-#define LIGHT_FLAGS_BLEND_MODE_SUB (1<<16)
-#define LIGHT_FLAGS_BLEND_MODE_MIX (2<<16)
-#define LIGHT_FLAGS_BLEND_MODE_MASK (3<<16)
-
-
vec2 tex_uv = (vec4(vertex,0.0,1.0) * mat4(light_array.data[light_base].matrix[0],light_array.data[light_base].matrix[1],vec4(0.0,0.0,1.0,0.0),vec4(0.0,0.0,0.0,1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations.
- uint texture_idx = light_array.data[light_base].flags&LIGHT_FLAGS_TEXTURE_MASK;
- vec4 light_color = texture(sampler2D(light_textures[texture_idx],texture_sampler),tex_uv);
+ vec4 light_color = texture(sampler2D(light_textures[i],texture_sampler),tex_uv);
vec4 light_base_color = light_array.data[light_base].color;
light_color.rgb*=light_base_color.rgb*light_base_color.a;
@@ -526,32 +521,32 @@ FRAGMENT_SHADER_CODE
vec4 shadow_uv = vec4(tex_ofs,0.0,distance,1.0);
if (shadow_mode==LIGHT_FLAGS_SHADOW_NEAREST) {
- shadow = textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv).x;
+ shadow = textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv).x;
} else if (shadow_mode==LIGHT_FLAGS_SHADOW_PCF5) {
vec4 shadow_pixel_size = vec4(light_array.data[light_base].shadow_pixel_size,0.0,0.0,0.0);
shadow = 0.0;
- shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*2.0).x;
- shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size).x;
- shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv).x;
- shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size).x;
- shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*2.0).x;
+ shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*2.0).x;
+ shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size).x;
+ shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv).x;
+ shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size).x;
+ shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*2.0).x;
shadow/=5.0;
- } else if (shadow_mode==LIGHT_FLAGS_SHADOW_PCF13) {
+ } else { //PCF13
vec4 shadow_pixel_size = vec4(light_array.data[light_base].shadow_pixel_size,0.0,0.0,0.0);
shadow = 0.0;
- shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*6.0).x;
- shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*5.0).x;
- shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*4.0).x;
- shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*3.0).x;
- shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*2.0).x;
- shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size).x;
- shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv).x;
- shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size).x;
- shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*2.0).x;
- shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*3.0).x;
- shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*4.0).x;
- shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*5.0).x;
- shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*6.0).x;
+ shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*6.0).x;
+ shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*5.0).x;
+ shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*4.0).x;
+ shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*3.0).x;
+ shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*2.0).x;
+ shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size).x;
+ shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv).x;
+ shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size).x;
+ shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*2.0).x;
+ shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*3.0).x;
+ shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*4.0).x;
+ shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*5.0).x;
+ shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*6.0).x;
shadow/=13.0;
}
@@ -577,6 +572,7 @@ FRAGMENT_SHADER_CODE
} break;
}
}
+#endif
frag_color = color;
diff --git a/servers/visual/rasterizer/shaders/canvas_occlusion_fix.glsl b/servers/visual/rasterizer/shaders/canvas_occlusion_fix.glsl
deleted file mode 100644
index 7c9651201e..0000000000
--- a/servers/visual/rasterizer/shaders/canvas_occlusion_fix.glsl
+++ /dev/null
@@ -1,99 +0,0 @@
-/* clang-format off */
-[vertex]
-/* clang-format on */
-
-#version 450
-
-layout(location = 0) out highp float u;
-
-void main() {
-
- if (gl_VertexIndex==0) {
- u=0.0;
- gl_Position=vec4(-1.0,-1.0,0.0,1.0);
- } else if (gl_VertexIndex==1) {
- u=0.0;
- gl_Position=vec4(-1.0,1.0,0.0,1.0);
- } else if (gl_VertexIndex==2) {
- u=1.0;
- gl_Position=vec4(1.0,1.0,0.0,1.0);
- } else {
- u=1.0;
- gl_Position=vec4(1.0,-1.0,0.0,1.0);
- }
-}
-
-/* clang-format off */
-[fragment]
-/* clang-format on */
-
-#version 450
-
-#define PI 3.14159265359
-
-layout(set=0, binding=0) uniform sampler2D textures[4];
-layout(location = 0) in highp float u;
-layout(location = 0) out highp float distance;
-
-layout(push_constant, binding = 0, std430) uniform Constants {
- mat4 projection;
- float far;
- float pad[3];
-} constants;
-
-void main() {
-
- //0-1 in the texture we are writing to represents a circle, 0-2PI)
- //obtain the quarter circle from the source textures
- float angle=fract(u+1.0-0.125);
-
- float depth;
-#if 0
- if (angle<0.25) {
- highp float sub_angle = ((angle/0.25)*2.0-1.0)*(PI/4.0);
- highp float x=tan(sub_angle)*0.5+0.5;
- depth=texture(textures[0],vec2(x,0.0)).x;
- } else if (angle<0.50) {
- highp float sub_angle = (((angle-0.25)/0.25)*2.0-1.0)*(PI/4.0);
- highp float x=tan(sub_angle)*0.5+0.5;
- depth=texture(textures[1],vec2(x,0.0)).x;
- } else if (angle<0.75) {
- highp float sub_angle = (((angle-0.5)/0.25)*2.0-1.0)*(PI/4.0);
- highp float x=tan(sub_angle)*0.5+0.5;
- depth=texture(textures[2],vec2(x,0.0)).x;
- } else {
- highp float sub_angle = (((angle-0.75)/0.25)*2.0-1.0)*(PI/4.0);
- highp float x=tan(sub_angle)*0.5+0.5;
- depth=texture(textures[3],vec2(x,0.0)).x;
- }
-#else
- if (angle<0.25) {
- highp float sub_angle = ((angle/0.25)*2.0-1.0)*(PI/4.0);
- vec2 pos = vec2(cos(sub_angle),sin(sub_angle))*constants.far;
- vec4 proj = constants.projection * vec4(pos,0.0,1.0);
- float coord = (proj.x/proj.w)*0.5+0.5;
- depth=texture(textures[0],vec2(coord,0.0)).x;
- } else if (angle<0.50) {
- highp float sub_angle = (((angle-0.25)/0.25)*2.0-1.0)*(PI/4.0);
- vec2 pos = vec2(cos(sub_angle),sin(sub_angle))*constants.far;
- vec4 proj = constants.projection * vec4(pos,0.0,1.0);
- float coord = (proj.x/proj.w)*0.5+0.5;
- depth=texture(textures[1],vec2(coord,0.0)).x;
- } else if (angle<0.75) {
- highp float sub_angle = (((angle-0.5)/0.25)*2.0-1.0)*(PI/4.0);
- vec2 pos = vec2(cos(sub_angle),sin(sub_angle))*constants.far;
- vec4 proj = constants.projection * vec4(pos,0.0,1.0);
- float coord = (proj.x/proj.w)*0.5+0.5;
- depth=texture(textures[2],vec2(coord,0.0)).x;
- } else {
- highp float sub_angle = (((angle-0.75)/0.25)*2.0-1.0)*(PI/4.0);
- vec2 pos = vec2(cos(sub_angle),sin(sub_angle))*constants.far;
- vec4 proj = constants.projection * vec4(pos,0.0,1.0);
- float coord = (proj.x/proj.w)*0.5+0.5;
- depth=texture(textures[3],vec2(coord,0.0)).x;
- }
-
-
-#endif
- distance=depth;
-}
diff --git a/servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl b/servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl
index 36a86c7f63..7b2ec81fb1 100644
--- a/servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl
+++ b/servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl
@@ -1,11 +1,8 @@
-/* SET0: Per draw primitive settings */
+/* SET0: Draw Primitive */
#define M_PI 3.14159265359
-#define MAX_LIGHT_TEXTURES 1024
-#define MAX_RENDER_LIGHTS 256
-
#define FLAGS_INSTANCING_STRIDE_MASK 0xF
#define FLAGS_INSTANCING_ENABLED (1<<4)
#define FLAGS_INSTANCING_HAS_COLORS (1 << 5)
@@ -64,30 +61,30 @@ layout(set = 0, binding = 5) uniform textureBuffer instancing_buffer;
//
-/* SET2: Is the skeleton */
+/* SET2: Canvas Item State */
-#ifdef USE_ATTRIBUTES
-layout(set = 2, binding = 0) uniform textureBuffer skeleton_buffer;
+layout(set = 2, binding = 0, std140) uniform CanvasData {
+ mat4 canvas_transform;
+ mat4 screen_transform;
+ mat4 canvas_normal_transform;
+ vec4 canvas_modulation;
+ //uint light_count;
+} canvas_data;
-layout(set = 2, binding = 1, std140) uniform SkeletonData {
+layout(set = 2, binding = 1) uniform textureBuffer skeleton_buffer;
+
+layout(set = 2, binding = 2, std140) uniform SkeletonData {
mat4 skeleton_transform; //in world coordinates
mat4 skeleton_transform_inverse;
} skeleton_data;
-#endif
-/* SET3: Per Scene settings */
-layout(set = 3, binding = 0, std140) uniform CanvasData {
- mat4 canvas_transform;
- mat4 screen_transform;
- mat4 canvas_normal_transform;
- vec4 canvas_modulation;
- //uint light_count;
-} canvas_data;
+/* SET3: Lighting */
+
+#ifdef USE_LIGHTING
-#define LIGHT_FLAGS_TEXTURE_MASK 0xFFFF
#define LIGHT_FLAGS_BLEND_MASK (3<<16)
#define LIGHT_FLAGS_BLEND_MODE_ADD (0<<16)
#define LIGHT_FLAGS_BLEND_MODE_SUB (1<<16)
@@ -109,17 +106,19 @@ struct Light {
vec2 position;
uint flags; //index to light texture
float height;
- float shadow_softness;
float shadow_pixel_size;
float pad0;
float pad1;
+ float pad2;
};
-layout(set = 3, binding = 1, std140) uniform LightData {
- Light data[MAX_RENDER_LIGHTS];
+layout(set = 3, binding = 0, std140) uniform LightData {
+ Light data[MAX_LIGHTS];
} light_array;
-layout(set = 3, binding = 2) uniform texture2D light_textures[MAX_LIGHT_TEXTURES];
-layout(set = 3, binding = 3) uniform texture2D shadow_textures[MAX_LIGHT_TEXTURES];
+layout(set = 3, binding = 1) uniform texture2D light_textures[MAX_LIGHT_TEXTURES];
+layout(set = 3, binding = 2) uniform texture2D shadow_textures[MAX_LIGHT_TEXTURES];
-layout(set = 3, binding = 4) uniform sampler shadow_sampler;
+layout(set = 3, binding = 3) uniform sampler shadow_sampler;
+
+#endif