summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/rendering/rasterizer.h98
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp839
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h145
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp4
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp233
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_storage_rd.h49
-rw-r--r--servers/rendering/rasterizer_rd/shaders/canvas.glsl57
-rw-r--r--servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl14
-rw-r--r--servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl93
-rw-r--r--servers/rendering/rendering_server_canvas.cpp151
-rw-r--r--servers/rendering/rendering_server_canvas.h42
-rw-r--r--servers/rendering/rendering_server_raster.h37
-rw-r--r--servers/rendering/rendering_server_viewport.cpp20
-rw-r--r--servers/rendering/rendering_server_viewport.h6
-rw-r--r--servers/rendering/rendering_server_wrap_mt.h37
-rw-r--r--servers/rendering_server.cpp3
-rw-r--r--servers/rendering_server.h83
17 files changed, 982 insertions, 929 deletions
diff --git a/servers/rendering/rasterizer.h b/servers/rendering/rasterizer.h
index cecd313fbd..4ece811a1e 100644
--- a/servers/rendering/rasterizer.h
+++ b/servers/rendering/rasterizer.h
@@ -351,10 +351,6 @@ public:
virtual void texture_replace(RID p_texture, RID p_by_texture) = 0;
virtual void texture_set_size_override(RID p_texture, int p_width, int p_height) = 0;
-// FIXME: Disabled during Vulkan refactoring, should be ported.
-#if 0
- virtual void texture_bind(RID p_texture, uint32_t p_texture_no) = 0;
-#endif
virtual void texture_set_path(RID p_texture, const String &p_path) = 0;
virtual String texture_get_path(RID p_texture) const = 0;
@@ -372,6 +368,15 @@ public:
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
+ /* CANVAS TEXTURE API */
+
+ virtual RID canvas_texture_create() = 0;
+ virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) = 0;
+ virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) = 0;
+
+ virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) = 0;
+ virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) = 0;
+
/* SHADER API */
virtual RID shader_create() = 0;
@@ -882,39 +887,10 @@ public:
}
};
- typedef uint64_t TextureBindingID;
-
- virtual TextureBindingID request_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, RS::CanvasItemTextureFilter p_filter, RS::CanvasItemTextureRepeat p_repeat, RID p_multimesh) = 0;
- virtual void free_texture_binding(TextureBindingID p_binding) = 0;
-
//easier wrap to avoid mistakes
struct Item;
- struct TextureBinding {
- TextureBindingID binding_id;
-
- _FORCE_INLINE_ void create(RS::CanvasItemTextureFilter p_item_filter, RS::CanvasItemTextureRepeat p_item_repeat, RID p_texture, RID p_normalmap, RID p_specular, RS::CanvasItemTextureFilter p_filter, RS::CanvasItemTextureRepeat p_repeat, RID p_multimesh) {
- if (p_filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT) {
- p_filter = p_item_filter;
- }
- if (p_repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) {
- p_repeat = p_item_repeat;
- }
- if (p_texture != RID() || p_normalmap != RID() || p_specular != RID() || p_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT || p_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT || p_multimesh.is_valid()) {
- ERR_FAIL_COND(binding_id != 0);
- binding_id = singleton->request_texture_binding(p_texture, p_normalmap, p_specular, p_filter, p_repeat, p_multimesh);
- }
- }
-
- _FORCE_INLINE_ TextureBinding() { binding_id = 0; }
- _FORCE_INLINE_ ~TextureBinding() {
- if (binding_id) {
- singleton->free_texture_binding(binding_id);
- }
- }
- };
-
typedef uint64_t PolygonID;
virtual PolygonID request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>()) = 0;
virtual void free_polygon(PolygonID p_polygon) = 0;
@@ -984,9 +960,8 @@ public:
Color modulate;
Rect2 source;
uint8_t flags;
- Color specular_shininess;
- TextureBinding texture_binding;
+ RID texture;
CommandRect() {
flags = 0;
@@ -1002,8 +977,9 @@ public:
Color color;
RS::NinePatchAxisMode axis_x;
RS::NinePatchAxisMode axis_y;
- Color specular_shininess;
- TextureBinding texture_binding;
+
+ RID texture;
+
CommandNinePatch() {
draw_center = true;
type = TYPE_NINEPATCH;
@@ -1013,8 +989,9 @@ public:
struct CommandPolygon : public Command {
RS::PrimitiveType primitive;
Polygon polygon;
- Color specular_shininess;
- TextureBinding texture_binding;
+
+ RID texture;
+
CommandPolygon() {
type = TYPE_POLYGON;
}
@@ -1025,8 +1002,9 @@ public:
Vector2 points[4];
Vector2 uvs[4];
Color colors[4];
- Color specular_shininess;
- TextureBinding texture_binding;
+
+ RID texture;
+
CommandPrimitive() {
type = TYPE_PRIMITIVE;
}
@@ -1036,22 +1014,25 @@ public:
RID mesh;
Transform2D transform;
Color modulate;
- Color specular_shininess;
- TextureBinding texture_binding;
+
+ RID texture;
+
CommandMesh() { type = TYPE_MESH; }
};
struct CommandMultiMesh : public Command {
RID multimesh;
- Color specular_shininess;
- TextureBinding texture_binding;
+
+ RID texture;
+
CommandMultiMesh() { type = TYPE_MULTIMESH; }
};
struct CommandParticles : public Command {
RID particles;
- Color specular_shininess;
- TextureBinding texture_binding;
+
+ RID texture;
+
CommandParticles() { type = TYPE_PARTICLES; }
};
@@ -1260,12 +1241,6 @@ public:
return command;
}
- struct CustomData {
- virtual ~CustomData() {}
- };
-
- mutable CustomData *custom_data; //implementation dependent
-
void clear() {
Command *c = commands;
while (c) {
@@ -1295,6 +1270,10 @@ public:
material_owner = nullptr;
light_masked = false;
}
+
+ RS::CanvasItemTextureFilter texture_filter;
+ RS::CanvasItemTextureRepeat texture_repeat;
+
Item() {
commands = nullptr;
last_command = nullptr;
@@ -1315,7 +1294,8 @@ public:
light_masked = false;
update_when_visible = false;
z_final = 0;
- custom_data = nullptr;
+ texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT;
+ texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT;
}
virtual ~Item() {
clear();
@@ -1325,13 +1305,10 @@ public:
if (copy_back_buffer) {
memdelete(copy_back_buffer);
}
- if (custom_data) {
- memdelete(custom_data);
- }
}
};
- virtual void 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) = 0;
+ virtual void 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, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat) = 0;
virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) = 0;
struct LightOccluderInstance {
@@ -1357,12 +1334,13 @@ public:
virtual RID light_create() = 0;
virtual void light_set_texture(RID p_rid, RID p_texture) = 0;
- virtual void light_set_use_shadow(RID p_rid, bool p_enable, int p_resolution) = 0;
- virtual void light_update_shadow(RID p_rid, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) = 0;
+ virtual void light_set_use_shadow(RID p_rid, bool p_enable) = 0;
+ virtual void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) = 0;
virtual RID occluder_polygon_create() = 0;
virtual void occluder_polygon_set_shape_as_lines(RID p_occluder, const Vector<Vector2> &p_lines) = 0;
virtual void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) = 0;
+ virtual void set_shadow_texture_size(int p_size) = 0;
virtual void draw_window_margins(int *p_margins, RID *p_margin_textures) = 0;
diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp
index aad2be45c6..28674b118c 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp
@@ -92,152 +92,6 @@ void RasterizerCanvasRD::_update_transform_to_mat4(const Transform &p_transform,
p_mat4[15] = 1;
}
-void RasterizerCanvasRD::_update_specular_shininess(const Color &p_transform, uint32_t *r_ss) {
- *r_ss = uint32_t(CLAMP(p_transform.a * 255.0, 0, 255)) << 24;
- *r_ss |= uint32_t(CLAMP(p_transform.b * 255.0, 0, 255)) << 16;
- *r_ss |= uint32_t(CLAMP(p_transform.g * 255.0, 0, 255)) << 8;
- *r_ss |= uint32_t(CLAMP(p_transform.r * 255.0, 0, 255));
-}
-
-RID RasterizerCanvasRD::_create_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat, RID p_multimesh) {
- Vector<RD::Uniform> uniform_set;
-
- { // COLOR TEXTURE
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 1;
- RID texture = storage->texture_get_rd_texture(p_texture);
- if (!texture.is_valid()) {
- //use default white texture
- texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE);
- }
- u.ids.push_back(texture);
- uniform_set.push_back(u);
- }
-
- { // NORMAL TEXTURE
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 2;
- RID texture = storage->texture_get_rd_texture(p_normalmap);
- if (!texture.is_valid()) {
- //use default normal texture
- texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_NORMAL);
- }
- u.ids.push_back(texture);
- uniform_set.push_back(u);
- }
-
- { // SPECULAR TEXTURE
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 3;
- RID texture = storage->texture_get_rd_texture(p_specular);
- if (!texture.is_valid()) {
- //use default white texture
- texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE);
- }
- u.ids.push_back(texture);
- uniform_set.push_back(u);
- }
-
- { // SAMPLER
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 4;
- RID sampler = storage->sampler_rd_get_default(p_filter, p_repeat);
- ERR_FAIL_COND_V(sampler.is_null(), RID());
- u.ids.push_back(sampler);
- uniform_set.push_back(u);
- }
-
- { // MULTIMESH TEXTURE BUFFER
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE_BUFFER;
- u.binding = 5;
- u.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_MULTIMESH_BUFFER));
- uniform_set.push_back(u);
- }
-
- return RD::get_singleton()->uniform_set_create(uniform_set, shader.default_version_rd_shader, 0);
-}
-
-RasterizerCanvas::TextureBindingID RasterizerCanvasRD::request_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat, RID p_multimesh) {
- if (p_filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT) {
- p_filter = default_samplers.default_filter;
- }
-
- if (p_repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) {
- p_repeat = default_samplers.default_repeat;
- }
-
- TextureBindingKey key;
- key.texture = p_texture;
- key.normalmap = p_normalmap;
- key.specular = p_specular;
- key.multimesh = p_multimesh;
- key.texture_filter = p_filter;
- key.texture_repeat = p_repeat;
-
- TextureBinding *binding;
- TextureBindingID id;
- {
- TextureBindingID *idptr = bindings.texture_key_bindings.getptr(key);
-
- if (!idptr) {
- id = bindings.id_generator++;
- bindings.texture_key_bindings[key] = id;
- binding = memnew(TextureBinding);
- binding->key = key;
- binding->id = id;
-
- bindings.texture_bindings[id] = binding;
-
- } else {
- id = *idptr;
- binding = bindings.texture_bindings[id];
- }
- }
-
- binding->reference_count++;
-
- if (binding->to_dispose.in_list()) {
- //was queued for disposal previously, but ended up reused.
- bindings.to_dispose_list.remove(&binding->to_dispose);
- }
-
- if (binding->uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(binding->uniform_set)) {
- binding->uniform_set = _create_texture_binding(p_texture, p_normalmap, p_specular, p_filter, p_repeat, p_multimesh);
- }
-
- return id;
-}
-
-void RasterizerCanvasRD::free_texture_binding(TextureBindingID p_binding) {
- TextureBinding **binding_ptr = bindings.texture_bindings.getptr(p_binding);
- ERR_FAIL_COND(!binding_ptr);
- TextureBinding *binding = *binding_ptr;
- ERR_FAIL_COND(binding->reference_count == 0);
- binding->reference_count--;
- if (binding->reference_count == 0) {
- bindings.to_dispose_list.add(&binding->to_dispose);
- }
-}
-
-void RasterizerCanvasRD::_dispose_bindings() {
- while (bindings.to_dispose_list.first()) {
- TextureBinding *binding = bindings.to_dispose_list.first()->self();
- if (binding->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(binding->uniform_set)) {
- RD::get_singleton()->free(binding->uniform_set);
- }
-
- bindings.texture_key_bindings.erase(binding->key);
- bindings.texture_bindings.erase(binding->id);
- bindings.to_dispose_list.remove(&binding->to_dispose);
- memdelete(binding);
- }
-}
-
RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights) {
// Care must be taken to generate array formats
// in ways where they could be reused, so we will
@@ -457,36 +311,72 @@ void RasterizerCanvasRD::free_polygon(PolygonID p_polygon) {
polygon_buffers.polygons.erase(p_polygon);
}
-Size2i RasterizerCanvasRD::_bind_texture_binding(TextureBindingID p_binding, RD::DrawListID p_draw_list, uint32_t &flags) {
- TextureBinding **texture_binding_ptr = bindings.texture_bindings.getptr(p_binding);
- ERR_FAIL_COND_V(!texture_binding_ptr, Size2i());
- TextureBinding *texture_binding = *texture_binding_ptr;
+////////////////////
+
+void RasterizerCanvasRD::_bind_canvas_texture(RD::DrawListID p_draw_list, RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID &r_last_texture, PushConstant &push_constant, Size2 &r_texpixel_size) {
+ if (p_texture == RID()) {
+ p_texture = default_canvas_texture;
+ }
- if (texture_binding->key.normalmap.is_valid()) {
- flags |= FLAGS_DEFAULT_NORMAL_MAP_USED;
+ if (r_last_texture == p_texture) {
+ return; //nothing to do, its the same
}
- if (texture_binding->key.specular.is_valid()) {
- flags |= FLAGS_DEFAULT_SPECULAR_MAP_USED;
+
+ RID uniform_set;
+ Color specular_shininess;
+ Size2i size;
+ bool use_normal;
+ bool use_specular;
+
+ bool success = storage->canvas_texture_get_unifom_set(p_texture, p_base_filter, p_base_repeat, shader.default_version_rd_shader, CANVAS_TEXTURE_UNIFORM_SET, uniform_set, size, specular_shininess, use_normal, use_specular);
+ //something odd happened
+ if (!success) {
+ _bind_canvas_texture(p_draw_list, default_canvas_texture, p_base_filter, p_base_repeat, r_last_texture, push_constant, r_texpixel_size);
+ return;
}
- if (!RD::get_singleton()->uniform_set_is_valid(texture_binding->uniform_set)) {
- //texture may have changed (erased or replaced, see if we can fix)
- texture_binding->uniform_set = _create_texture_binding(texture_binding->key.texture, texture_binding->key.normalmap, texture_binding->key.specular, texture_binding->key.texture_filter, texture_binding->key.texture_repeat, texture_binding->key.multimesh);
- ERR_FAIL_COND_V(!texture_binding->uniform_set.is_valid(), Size2i(1, 1));
+ RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, uniform_set, CANVAS_TEXTURE_UNIFORM_SET);
+
+ if (specular_shininess.a < 0.999) {
+ push_constant.flags |= FLAGS_DEFAULT_SPECULAR_MAP_USED;
+ } else {
+ push_constant.flags &= ~FLAGS_DEFAULT_SPECULAR_MAP_USED;
}
- RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, texture_binding->uniform_set, 0);
- if (texture_binding->key.texture.is_valid()) {
- return storage->texture_2d_get_size(texture_binding->key.texture);
+ if (use_normal) {
+ push_constant.flags |= FLAGS_DEFAULT_NORMAL_MAP_USED;
} else {
- return Size2i(1, 1);
+ push_constant.flags &= ~FLAGS_DEFAULT_NORMAL_MAP_USED;
}
+
+ push_constant.specular_shininess = uint32_t(CLAMP(specular_shininess.a * 255.0, 0, 255)) << 24;
+ push_constant.specular_shininess |= uint32_t(CLAMP(specular_shininess.b * 255.0, 0, 255)) << 16;
+ push_constant.specular_shininess |= uint32_t(CLAMP(specular_shininess.g * 255.0, 0, 255)) << 8;
+ push_constant.specular_shininess |= uint32_t(CLAMP(specular_shininess.r * 255.0, 0, 255));
+
+ r_texpixel_size.x = 1.0 / float(size.x);
+ r_texpixel_size.y = 1.0 / float(size.y);
+
+ push_constant.color_texture_pixel_size[0] = r_texpixel_size.x;
+ push_constant.color_texture_pixel_size[1] = r_texpixel_size.y;
+
+ r_last_texture = p_texture;
}
-////////////////////
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, PipelineVariants *p_pipeline_variants) {
//create an empty push constant
+ RS::CanvasItemTextureFilter current_filter = default_filter;
+ RS::CanvasItemTextureRepeat current_repeat = default_repeat;
+
+ if (p_item->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT) {
+ current_filter = p_item->texture_filter;
+ }
+
+ if (p_item->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) {
+ current_repeat = p_item->texture_repeat;
+ }
+
PushConstant push_constant;
Transform2D base_transform = p_canvas_transform_inverse * p_item->final_transform;
_update_transform_2d_to_mat2x3(base_transform, push_constant.world);
@@ -513,16 +403,6 @@ 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;
@@ -534,160 +414,34 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
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 == RS::CANVAS_LIGHT_MODE_MASK) {
base_flags |= FLAGS_USING_LIGHT_MASK;
}
- if (light_count == state.max_lights_per_item) {
+
+ if (light_count == 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;
}
- {
- RID &canvas_item_state = light_count ? state_data->state_uniform_set_with_light : state_data->state_uniform_set;
-
- bool invalid_uniform = canvas_item_state.is_valid() && !RD::get_singleton()->uniform_set_is_valid(canvas_item_state);
-
- if (canvas_item_state.is_null() || invalid_uniform || (light_count > 0 && light_uniform_set_dirty)) {
- //re create canvas state
- Vector<RD::Uniform> uniforms;
-
- if (state_data->state_uniform_set_with_light.is_valid() && !invalid_uniform) {
- RD::get_singleton()->free(canvas_item_state);
- }
-
- {
- 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_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);
- }
- }
-
- {
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 7;
- u.ids.push_back(storage->global_variables_get_storage_buffer());
- uniforms.push_back(u);
- }
-
- //validate and update lighs if they are being used
-
- if (light_count > 0) {
- //recreate uniform set
-
- {
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 3;
- 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 = 4;
-
- RD::Uniform u_shadows;
- u_shadows.type = RD::UNIFORM_TYPE_TEXTURE;
- u_shadows.binding = 5;
-
- //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(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE));
- }
- if (cl->shadow.texture.is_valid()) {
- u_shadows.ids.push_back(cl->shadow.texture);
- } else {
- u_shadows.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK));
- }
- } else {
- u_lights.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE));
- u_shadows.ids.push_back(storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_BLACK));
- }
- }
-
- uniforms.push_back(u_lights);
- uniforms.push_back(u_shadows);
- }
-
- {
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 6;
- u.ids.push_back(state.shadow_sampler);
- uniforms.push_back(u);
- }
-
- canvas_item_state = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader_light, 2);
- } else {
- canvas_item_state = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader, 2);
- }
- }
-
- RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, canvas_item_state, 2);
- }
-
light_mode = light_count > 0 ? PIPELINE_LIGHT_MODE_ENABLED : PIPELINE_LIGHT_MODE_DISABLED;
PipelineVariants *pipeline_variants = p_pipeline_variants;
bool reclip = false;
+ RID last_texture;
+ Size2 texpixel_size;
+
const Item::Command *c = p_item->commands;
while (c) {
- push_constant.flags = base_flags; //reset on each command for sanity
- push_constant.specular_shininess = 0xFFFFFFFF;
+ push_constant.flags = base_flags | (push_constant.flags & (FLAGS_DEFAULT_NORMAL_MAP_USED | FLAGS_DEFAULT_SPECULAR_MAP_USED)); //reset on each command for sanity, keep canvastexture binding config
switch (c->type) {
case Item::Command::TYPE_RECT: {
@@ -701,26 +455,12 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
//bind textures
- Size2 texpixel_size;
- {
- texpixel_size = _bind_texture_binding(rect->texture_binding.binding_id, p_draw_list, push_constant.flags);
- texpixel_size.x = 1.0 / texpixel_size.x;
- texpixel_size.y = 1.0 / texpixel_size.y;
- }
-
- if (rect->specular_shininess.a < 0.999) {
- push_constant.flags |= FLAGS_DEFAULT_SPECULAR_MAP_USED;
- }
-
- _update_specular_shininess(rect->specular_shininess, &push_constant.specular_shininess);
+ _bind_canvas_texture(p_draw_list, rect->texture, current_filter, current_repeat, last_texture, push_constant, texpixel_size);
Rect2 src_rect;
Rect2 dst_rect;
- if (texpixel_size != Vector2()) {
- push_constant.color_texture_pixel_size[0] = texpixel_size.x;
- push_constant.color_texture_pixel_size[1] = texpixel_size.y;
-
+ if (rect->texture != RID()) {
src_rect = (rect->flags & CANVAS_RECT_REGION) ? Rect2(rect->source.position * texpixel_size, rect->source.size * texpixel_size) : Rect2(0, 0, 1, 1);
dst_rect = Rect2(rect->rect.position, rect->rect.size);
@@ -762,7 +502,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
}
src_rect = Rect2(0, 0, 1, 1);
- texpixel_size = Vector2(1, 1);
}
push_constant.modulation[0] = rect->modulate.r * base_color.r;
@@ -780,9 +519,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
push_constant.dst_rect[2] = dst_rect.size.width;
push_constant.dst_rect[3] = dst_rect.size.height;
- push_constant.color_texture_pixel_size[0] = texpixel_size.x;
- push_constant.color_texture_pixel_size[1] = texpixel_size.y;
-
RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(PushConstant));
RD::get_singleton()->draw_list_bind_index_array(p_draw_list, shader.quad_index_array);
RD::get_singleton()->draw_list_draw(p_draw_list, true);
@@ -800,30 +536,21 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
//bind textures
- Size2 texpixel_size;
- {
- texpixel_size = _bind_texture_binding(np->texture_binding.binding_id, p_draw_list, push_constant.flags);
- texpixel_size.x = 1.0 / texpixel_size.x;
- texpixel_size.y = 1.0 / texpixel_size.y;
- }
-
- if (np->specular_shininess.a < 0.999) {
- push_constant.flags |= FLAGS_DEFAULT_SPECULAR_MAP_USED;
- }
-
- _update_specular_shininess(np->specular_shininess, &push_constant.specular_shininess);
+ _bind_canvas_texture(p_draw_list, np->texture, current_filter, current_repeat, last_texture, push_constant, texpixel_size);
Rect2 src_rect;
Rect2 dst_rect(np->rect.position.x, np->rect.position.y, np->rect.size.x, np->rect.size.y);
- if (texpixel_size == Size2()) {
+ if (np->texture == RID()) {
texpixel_size = Size2(1, 1);
src_rect = Rect2(0, 0, 1, 1);
} else {
if (np->source != Rect2()) {
src_rect = Rect2(np->source.position.x * texpixel_size.width, np->source.position.y * texpixel_size.height, np->source.size.x * texpixel_size.width, np->source.size.y * texpixel_size.height);
- texpixel_size = Size2(1.0 / np->source.size.width, 1.0 / np->source.size.height);
+ push_constant.color_texture_pixel_size[0] = 1.0 / np->source.size.width;
+ push_constant.color_texture_pixel_size[1] = 1.0 / np->source.size.height;
+
} else {
src_rect = Rect2(0, 0, 1, 1);
}
@@ -844,9 +571,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
push_constant.dst_rect[2] = dst_rect.size.width;
push_constant.dst_rect[3] = dst_rect.size.height;
- push_constant.color_texture_pixel_size[0] = texpixel_size.x;
- push_constant.color_texture_pixel_size[1] = texpixel_size.y;
-
push_constant.flags |= int(np->axis_x) << FLAGS_NINEPATCH_H_MODE_SHIFT;
push_constant.flags |= int(np->axis_y) << FLAGS_NINEPATCH_V_MODE_SHIFT;
@@ -863,6 +587,10 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
RD::get_singleton()->draw_list_bind_index_array(p_draw_list, shader.quad_index_array);
RD::get_singleton()->draw_list_draw(p_draw_list, true);
+ //restore if overrided
+ push_constant.color_texture_pixel_size[0] = texpixel_size.x;
+ push_constant.color_texture_pixel_size[1] = texpixel_size.y;
+
} break;
case Item::Command::TYPE_POLYGON: {
const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(c);
@@ -884,18 +612,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
//bind textures
- Size2 texpixel_size;
- {
- texpixel_size = _bind_texture_binding(polygon->texture_binding.binding_id, p_draw_list, push_constant.flags);
- texpixel_size.x = 1.0 / texpixel_size.x;
- texpixel_size.y = 1.0 / texpixel_size.y;
- }
-
- if (polygon->specular_shininess.a < 0.999) {
- push_constant.flags |= FLAGS_DEFAULT_SPECULAR_MAP_USED;
- }
-
- _update_specular_shininess(polygon->specular_shininess, &push_constant.specular_shininess);
+ _bind_canvas_texture(p_draw_list, polygon->texture, current_filter, current_repeat, last_texture, push_constant, texpixel_size);
push_constant.modulation[0] = base_color.r;
push_constant.modulation[1] = base_color.g;
@@ -908,9 +625,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
push_constant.ninepatch_margins[j] = 0;
}
- push_constant.color_texture_pixel_size[0] = texpixel_size.x;
- push_constant.color_texture_pixel_size[1] = texpixel_size.y;
-
RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(PushConstant));
RD::get_singleton()->draw_list_bind_vertex_array(p_draw_list, pb->vertex_array);
if (pb->indices.is_valid()) {
@@ -932,15 +646,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
//bind textures
- {
- _bind_texture_binding(primitive->texture_binding.binding_id, p_draw_list, push_constant.flags);
- }
-
- if (primitive->specular_shininess.a < 0.999) {
- push_constant.flags |= FLAGS_DEFAULT_SPECULAR_MAP_USED;
- }
-
- _update_specular_shininess(primitive->specular_shininess, &push_constant.specular_shininess);
+ _bind_canvas_texture(p_draw_list, RID(), current_filter, current_repeat, last_texture, push_constant, texpixel_size);
RD::get_singleton()->draw_list_bind_index_array(p_draw_list, primitive_arrays.index_array[MIN(3, primitive->point_count) - 1]);
@@ -1295,7 +1001,108 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
}
}
-void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, RID p_screen_uniform_set) {
+RID RasterizerCanvasRD::_create_base_uniform_set(RID p_to_render_target, bool p_backbuffer) {
+ //re create canvas state
+ Vector<RD::Uniform> uniforms;
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 1;
+ u.ids.push_back(state.canvas_state_buffer);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 2;
+ u.ids.push_back(state.lights_uniform_buffer);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 3;
+ u.ids.push_back(storage->decal_atlas_get_texture());
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 4;
+ u.ids.push_back(state.shadow_texture);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 5;
+ u.ids.push_back(state.shadow_sampler);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 6;
+ RID screen;
+ if (p_backbuffer) {
+ screen = storage->render_target_get_rd_texture(p_to_render_target);
+ } else {
+ screen = storage->render_target_get_rd_backbuffer(p_to_render_target);
+ if (screen.is_null()) { //unallocated backbuffer
+ screen = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE);
+ }
+ }
+ u.ids.push_back(screen);
+ uniforms.push_back(u);
+ }
+
+ {
+ //needs samplers for the material (uses custom textures) create them
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 7;
+ u.ids.resize(12);
+ RID *ids_ptr = u.ids.ptrw();
+ ids_ptr[0] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[1] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[2] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[3] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[4] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[5] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ ids_ptr[6] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ ids_ptr[7] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ ids_ptr[8] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ ids_ptr[9] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ ids_ptr[10] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ ids_ptr[11] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 8;
+ u.ids.push_back(storage->global_variables_get_storage_buffer());
+ uniforms.push_back(u);
+ }
+
+ RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader, BASE_UNIFORM_SET);
+ if (p_backbuffer) {
+ storage->render_target_set_backbuffer_uniform_set(p_to_render_target, uniform_set);
+ } else {
+ storage->render_target_set_framebuffer_uniform_set(p_to_render_target, uniform_set);
+ }
+
+ return uniform_set;
+}
+
+void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights) {
Item *current_clip = nullptr;
Transform2D canvas_transform_inverse = p_canvas_transform_inverse;
@@ -1313,13 +1120,19 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count,
#warning TODO obtain from framebuffer format eventually when this is implemented
#endif
+ RID fb_uniform_set = storage->render_target_get_framebuffer_uniform_set(p_to_render_target);
+
+ if (fb_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(fb_uniform_set)) {
+ fb_uniform_set = _create_base_uniform_set(p_to_render_target, false);
+ }
+
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer);
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, clear ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, clear_colors);
- if (p_screen_uniform_set.is_valid()) {
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_screen_uniform_set, 3);
- }
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, fb_uniform_set, BASE_UNIFORM_SET);
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, state.default_transforms_uniform_set, TRANSFORMS_UNIFORM_SET);
+
RID prev_material;
PipelineVariants *pipeline_variants = &shader.pipeline_variants;
@@ -1349,7 +1162,7 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count,
if (material_data->shader_data->version.is_valid() && material_data->shader_data->valid) {
pipeline_variants = &material_data->shader_data->pipeline_variants;
if (material_data->uniform_set.is_valid()) {
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, material_data->uniform_set, 1);
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, material_data->uniform_set, MATERIAL_UNIFORM_SET);
}
} else {
pipeline_variants = &shader.pipeline_variants;
@@ -1367,7 +1180,7 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count,
RD::get_singleton()->draw_list_end();
}
-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) {
+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, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat) {
int item_count = 0;
//setup canvas state uniforms if needed
@@ -1435,24 +1248,42 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
state.light_uniforms[index].height = l->height * (p_canvas_transform.elements[0].length() + p_canvas_transform.elements[1].length()) * 0.5; //approximate height conversion to the canvas size, since all calculations are done in canvas coords to avoid precision loss
for (int i = 0; i < 4; i++) {
- state.light_uniforms[index].shadow_color[i] = l->shadow_color[i];
+ state.light_uniforms[index].shadow_color[i] = uint8_t(CLAMP(int32_t(l->shadow_color[i] * 255.0), 0, 255));
state.light_uniforms[index].color[i] = l->color[i];
}
state.light_uniforms[index].color[3] = l->energy; //use alpha for energy, so base color can go separate
- if (clight->shadow.texture.is_valid()) {
- state.light_uniforms[index].shadow_pixel_size = (1.0 / clight->shadow.size) * (1.0 + l->shadow_smooth);
+ if (state.shadow_fb.is_valid()) {
+ state.light_uniforms[index].shadow_pixel_size = (1.0 / state.shadow_texture_size) * (1.0 + l->shadow_smooth);
+ state.light_uniforms[index].shadow_z_far_inv = 1.0 / clight->shadow.z_far;
+ state.light_uniforms[index].shadow_y_ofs = clight->shadow.y_offset;
} else {
state.light_uniforms[index].shadow_pixel_size = 1.0;
+ state.light_uniforms[index].shadow_z_far_inv = 1.0;
+ state.light_uniforms[index].shadow_y_ofs = 0;
}
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()) {
+ if (clight->shadow.enabled) {
state.light_uniforms[index].flags |= LIGHT_FLAGS_HAS_SHADOW;
}
+ if (clight->texture.is_valid()) {
+ Rect2 atlas_rect = storage->decal_atlas_get_texture_rect(clight->texture);
+ state.light_uniforms[index].atlas_rect[0] = atlas_rect.position.x;
+ state.light_uniforms[index].atlas_rect[1] = atlas_rect.position.y;
+ state.light_uniforms[index].atlas_rect[2] = atlas_rect.size.width;
+ state.light_uniforms[index].atlas_rect[3] = atlas_rect.size.height;
+
+ } else {
+ state.light_uniforms[index].atlas_rect[0] = 0;
+ state.light_uniforms[index].atlas_rect[1] = 0;
+ state.light_uniforms[index].atlas_rect[2] = 0;
+ state.light_uniforms[index].atlas_rect[3] = 0;
+ }
+
l->render_index_cache = index;
index++;
@@ -1464,12 +1295,16 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
}
}
+ { //default filter/repeat
+ default_filter = p_default_filter;
+ default_repeat = p_default_repeat;
+ }
+
//fill the list until rendering is possible.
bool material_screen_texture_found = false;
Item *ci = p_item_list;
Rect2 back_buffer_rect;
bool backbuffer_copy = false;
- RID screen_uniform_set;
while (ci) {
if (ci->copy_back_buffer) {
@@ -1490,10 +1325,6 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
backbuffer_copy = true;
back_buffer_rect = Rect2();
}
- if (screen_uniform_set.is_null()) {
- RID backbuffer_shader = shader.canvas_shader.version_get_shader(md->shader_data->version, 0); //any version is fine
- screen_uniform_set = storage->render_target_get_back_buffer_uniform_set(p_to_render_target, backbuffer_shader);
- }
}
if (md->last_frame != RasterizerRD::singleton->get_frame_number()) {
@@ -1509,7 +1340,7 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
if (backbuffer_copy) {
//render anything pending, including clearing if no items
- _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, screen_uniform_set);
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list);
item_count = 0;
storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect);
@@ -1521,7 +1352,7 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
items[item_count++] = ci;
if (!ci->next || item_count == MAX_RENDER_ITEMS - 1) {
- _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, screen_uniform_set);
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list);
//then reset
item_count = 0;
}
@@ -1532,7 +1363,6 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
RID RasterizerCanvasRD::light_create() {
CanvasLight canvas_light;
- canvas_light.shadow.size = 0;
return canvas_light_owner.make_rid(canvas_light);
}
@@ -1542,71 +1372,71 @@ void RasterizerCanvasRD::light_set_texture(RID p_rid, RID p_texture) {
if (cl->texture == p_texture) {
return;
}
-
+ if (cl->texture.is_valid()) {
+ storage->texture_remove_from_decal_atlas(cl->texture);
+ }
cl->texture = p_texture;
+
+ if (cl->texture.is_valid()) {
+ storage->texture_add_to_decal_atlas(cl->texture);
+ }
}
-void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable, int p_resolution) {
+void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable) {
CanvasLight *cl = canvas_light_owner.getornull(p_rid);
ERR_FAIL_COND(!cl);
- ERR_FAIL_COND(p_resolution < 64);
- if (cl->shadow.texture.is_valid() == p_enable && p_resolution == cl->shadow.size) {
- return;
- }
- if (cl->shadow.texture.is_valid()) {
- RD::get_singleton()->free(cl->shadow.fb);
- RD::get_singleton()->free(cl->shadow.depth);
- RD::get_singleton()->free(cl->shadow.texture);
- cl->shadow.fb = RID();
- cl->shadow.texture = RID();
- cl->shadow.depth = RID();
- }
+ cl->shadow.enabled = p_enable;
+}
+
+void RasterizerCanvasRD::light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) {
+ CanvasLight *cl = canvas_light_owner.getornull(p_rid);
+ ERR_FAIL_COND(!cl->shadow.enabled);
+
+ if (state.shadow_fb == RID()) {
+ //ah, we lack the shadow texture..
+ RD::get_singleton()->free(state.shadow_texture); //erase placeholder
- if (p_enable) {
Vector<RID> fb_textures;
{ //texture
RD::TextureFormat tf;
tf.type = RD::TEXTURE_TYPE_2D;
- tf.width = p_resolution;
- tf.height = 1;
+ tf.width = state.shadow_texture_size;
+ tf.height = state.max_lights_per_render * 2;
tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
tf.format = RD::DATA_FORMAT_R32_SFLOAT;
- cl->shadow.texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
- fb_textures.push_back(cl->shadow.texture);
+ state.shadow_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ fb_textures.push_back(state.shadow_texture);
}
{
RD::TextureFormat tf;
tf.type = RD::TEXTURE_TYPE_2D;
- tf.width = p_resolution;
- tf.height = 1;
+ tf.width = state.shadow_texture_size;
+ tf.height = state.max_lights_per_render * 2;
tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
- tf.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;
+ tf.format = RD::DATA_FORMAT_D32_SFLOAT;
//chunks to write
- cl->shadow.depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
- fb_textures.push_back(cl->shadow.depth);
+ state.shadow_depth_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ fb_textures.push_back(state.shadow_depth_texture);
}
- cl->shadow.fb = RD::get_singleton()->framebuffer_create(fb_textures);
+ state.shadow_fb = RD::get_singleton()->framebuffer_create(fb_textures);
}
- cl->shadow.size = p_resolution;
-}
-
-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) {
- CanvasLight *cl = canvas_light_owner.getornull(p_rid);
- ERR_FAIL_COND(cl->shadow.texture.is_null());
+ cl->shadow.z_far = p_far;
+ cl->shadow.y_offset = float(p_shadow_index * 2 + 1) / float(state.max_lights_per_render * 2);
+ Vector<Color> cc;
+ cc.push_back(Color(p_far, p_far, p_far, 1.0));
for (int i = 0; i < 4; i++) {
//make sure it remains orthogonal, makes easy to read angle later
//light.basis.scale(Vector3(to_light.elements[0].length(),to_light.elements[1].length(),1));
- Vector<Color> cc;
- cc.push_back(Color(p_far, p_far, p_far, 1.0));
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(cl->shadow.fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, Rect2i((cl->shadow.size / 4) * i, 0, (cl->shadow.size / 4), 1));
+ Rect2i rect((state.shadow_texture_size / 4) * i, p_shadow_index * 2, (state.shadow_texture_size / 4), 2);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, rect);
CameraMatrix projection;
{
@@ -1635,8 +1465,8 @@ void RasterizerCanvasRD::light_update_shadow(RID p_rid, const Transform2D &p_lig
static const Vector2 directions[4] = { Vector2(1, 0), Vector2(0, 1), Vector2(-1, 0), Vector2(0, -1) };
push_constant.direction[0] = directions[i].x;
push_constant.direction[1] = directions[i].y;
- push_constant.pad[0] = 0;
- push_constant.pad[1] = 0;
+ push_constant.z_far = p_far;
+ push_constant.pad = 0;
/*if (i == 0)
*p_xform_cache = projection;*/
@@ -1774,7 +1604,6 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) {
ubo_size = 0;
uniforms.clear();
uses_screen_texture = false;
- uses_material_samplers = false;
if (code == String()) {
return; //just invalid, but no error
@@ -1812,10 +1641,6 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) {
version = canvas_singleton->shader.canvas_shader.version_create();
}
- if (gen_code.texture_uniforms.size() || uses_screen_texture) { //requires the samplers
- gen_code.defines.push_back("\n#define USE_MATERIAL_SAMPLERS\n");
- uses_material_samplers = true;
- }
#if 0
print_line("**compiling shader:");
print_line("**defines:\n");
@@ -2022,7 +1847,6 @@ Variant RasterizerCanvasRD::ShaderData::get_default_parameter(const StringName &
RasterizerCanvasRD::ShaderData::ShaderData() {
valid = false;
uses_screen_texture = false;
- uses_material_samplers = false;
}
RasterizerCanvasRD::ShaderData::~ShaderData() {
@@ -2085,7 +1909,7 @@ void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, V
update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), false);
}
- if (shader_data->ubo_size == 0 && !shader_data->uses_material_samplers) {
+ if (shader_data->ubo_size == 0) {
// This material does not require an uniform set, so don't create it.
return;
}
@@ -2098,32 +1922,10 @@ void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, V
Vector<RD::Uniform> uniforms;
{
- if (shader_data->uses_material_samplers) {
- //needs samplers for the material (uses custom textures) create them
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 0;
- u.ids.resize(12);
- RID *ids_ptr = u.ids.ptrw();
- ids_ptr[0] = canvas_singleton->storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- ids_ptr[1] = canvas_singleton->storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- ids_ptr[2] = canvas_singleton->storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- ids_ptr[3] = canvas_singleton->storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- ids_ptr[4] = canvas_singleton->storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- ids_ptr[5] = canvas_singleton->storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- ids_ptr[6] = canvas_singleton->storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
- ids_ptr[7] = canvas_singleton->storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
- ids_ptr[8] = canvas_singleton->storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
- ids_ptr[9] = canvas_singleton->storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
- ids_ptr[10] = canvas_singleton->storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
- ids_ptr[11] = canvas_singleton->storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
- uniforms.push_back(u);
- }
-
if (shader_data->ubo_size) {
RD::Uniform u;
u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 1;
+ u.binding = 0;
u.ids.push_back(uniform_buffer);
uniforms.push_back(u);
}
@@ -2132,13 +1934,13 @@ void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, V
for (uint32_t i = 0; i < tex_uniform_count; i++) {
RD::Uniform u;
u.type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 2 + i;
+ u.binding = 1 + i;
u.ids.push_back(textures[i]);
uniforms.push_back(u);
}
}
- uniform_set = RD::get_singleton()->uniform_set_create(uniforms, canvas_singleton->shader.canvas_shader.version_get_shader(shader_data->version, 0), 1);
+ uniform_set = RD::get_singleton()->uniform_set_create(uniforms, canvas_singleton->shader.canvas_shader.version_get_shader(shader_data->version, 0), MATERIAL_UNIFORM_SET);
}
RasterizerCanvasRD::MaterialData::~MaterialData() {
@@ -2164,7 +1966,6 @@ void RasterizerCanvasRD::set_time(double p_time) {
}
void RasterizerCanvasRD::update() {
- _dispose_bindings();
}
RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
@@ -2178,22 +1979,7 @@ 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) {
@@ -2226,7 +2012,6 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
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 < PIPELINE_LIGHT_MODE_MAX; i++) {
for (int j = 0; j < PIPELINE_VARIANT_MAX; j++) {
@@ -2327,8 +2112,8 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
actions.custom_samplers["SPECULAR_SHININESS_TEXTURE"] = "texture_sampler";
actions.custom_samplers["SCREEN_TEXTURE"] = "material_samplers[3]"; //mipmap and filter for screen texture
actions.sampler_array_name = "material_samplers";
- actions.base_texture_binding_index = 2;
- actions.texture_layout_set = 1;
+ actions.base_texture_binding_index = 1;
+ actions.texture_layout_set = MATERIAL_UNIFORM_SET;
actions.base_uniform_string = "material.";
actions.default_filter = ShaderLanguage::FILTER_LINEAR;
actions.default_repeat = ShaderLanguage::REPEAT_DISABLE;
@@ -2354,7 +2139,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
attachments.push_back(af_color);
RD::AttachmentFormat af_depth;
- af_depth.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32;
+ af_depth.format = RD::DATA_FORMAT_D32_SFLOAT;
af_depth.usage_flags = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
attachments.push_back(af_depth);
@@ -2386,21 +2171,17 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
}
{ //bindings
- bindings.id_generator = 0;
- //generate for 0
- bindings.default_empty = request_texture_binding(RID(), RID(), RID(), RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, RID());
-
- { //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) * state.max_lights_per_render);
-
- RD::SamplerState shadow_sampler_state;
- shadow_sampler_state.mag_filter = RD::SAMPLER_FILTER_LINEAR;
- shadow_sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR;
- shadow_sampler_state.repeat_u = RD::SAMPLER_REPEAT_MODE_REPEAT; //shadow wrap around
- shadow_sampler_state.compare_op = RD::COMPARE_OP_GREATER;
- state.shadow_sampler = RD::get_singleton()->sampler_create(shadow_sampler_state);
- }
+
+ 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) * state.max_lights_per_render);
+
+ RD::SamplerState shadow_sampler_state;
+ shadow_sampler_state.mag_filter = RD::SAMPLER_FILTER_LINEAR;
+ shadow_sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR;
+ shadow_sampler_state.repeat_u = RD::SAMPLER_REPEAT_MODE_REPEAT; //shadow wrap around
+ shadow_sampler_state.compare_op = RD::COMPARE_OP_GREATER;
+ shadow_sampler_state.enable_compare = true;
+ state.shadow_sampler = RD::get_singleton()->sampler_create(shadow_sampler_state);
}
{
@@ -2443,6 +2224,35 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
shader.default_skeleton_texture_buffer = RD::get_singleton()->texture_buffer_create(32, RD::DATA_FORMAT_R32G32B32A32_SFLOAT);
}
+ {
+ //default shadow texture to keep uniform set happy
+ RD::TextureFormat tf;
+ tf.type = RD::TEXTURE_TYPE_2D;
+ tf.width = 4;
+ tf.height = 4;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT;
+ tf.format = RD::DATA_FORMAT_R32_SFLOAT;
+
+ state.shadow_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ }
+
+ {
+ Vector<RD::Uniform> uniforms;
+
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 0;
+ u.ids.push_back(storage->get_default_rd_storage_buffer());
+ uniforms.push_back(u);
+ }
+
+ state.default_transforms_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader, TRANSFORMS_UNIFORM_SET);
+ }
+
+ default_canvas_texture = storage->canvas_texture_create();
+
+ state.shadow_texture_size = GLOBAL_GET("rendering/quality/2d_shadow_atlas/size");
//create functions for shader and material
storage->shader_set_data_request_function(RasterizerStorageRD::SHADER_TYPE_2D, _create_shader_funcs);
@@ -2457,7 +2267,7 @@ bool RasterizerCanvasRD::free(RID p_rid) {
if (canvas_light_owner.owns(p_rid)) {
CanvasLight *cl = canvas_light_owner.getornull(p_rid);
ERR_FAIL_COND_V(!cl, false);
- light_set_use_shadow(p_rid, false, 64);
+ light_set_use_shadow(p_rid, false);
canvas_light_owner.free(p_rid);
} else if (occluder_polygon_owner.owns(p_rid)) {
occluder_polygon_set_shape_as_lines(p_rid, Vector<Vector2>());
@@ -2469,6 +2279,31 @@ bool RasterizerCanvasRD::free(RID p_rid) {
return true;
}
+void RasterizerCanvasRD::set_shadow_texture_size(int p_size) {
+ p_size = nearest_power_of_2_templated(p_size);
+ if (p_size == state.shadow_texture_size) {
+ return;
+ }
+ state.shadow_texture_size = p_size;
+ if (state.shadow_fb.is_valid()) {
+ RD::get_singleton()->free(state.shadow_texture);
+ RD::get_singleton()->free(state.shadow_depth_texture);
+ state.shadow_fb = RID();
+
+ {
+ //create a default shadow texture to keep uniform set happy (and that it gets erased when a new one is created)
+ RD::TextureFormat tf;
+ tf.type = RD::TEXTURE_TYPE_2D;
+ tf.width = 4;
+ tf.height = 4;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT;
+ tf.format = RD::DATA_FORMAT_R32_SFLOAT;
+
+ state.shadow_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ }
+ }
+}
+
RasterizerCanvasRD::~RasterizerCanvasRD() {
//canvas state
@@ -2490,24 +2325,6 @@ RasterizerCanvasRD::~RasterizerCanvasRD() {
RD::get_singleton()->free(state.shadow_sampler);
}
//bindings
- {
- free_texture_binding(bindings.default_empty);
-
- //dispose pending
- _dispose_bindings();
- //anything remains?
- if (bindings.texture_bindings.size()) {
- ERR_PRINT("Some texture bindings were not properly freed (leaked CanvasItems?)");
- const TextureBindingID *key = nullptr;
- while ((key = bindings.texture_bindings.next(key))) {
- TextureBinding *tb = bindings.texture_bindings[*key];
- tb->reference_count = 1;
- free_texture_binding(*key);
- }
- //dispose pending
- _dispose_bindings();
- }
- }
//shaders
@@ -2520,5 +2337,13 @@ RasterizerCanvasRD::~RasterizerCanvasRD() {
//primitives are erase by dependency
}
+ if (state.shadow_fb.is_valid()) {
+ RD::get_singleton()->free(state.shadow_depth_texture);
+ }
+ RD::get_singleton()->free(state.shadow_texture);
+
+ storage->free(default_canvas_texture);
//pipelines don't need freeing, they are all gone after shaders are gone
+
+ RD::get_singleton()->free(state.default_transforms_uniform_set);
}
diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h
index bfe4e61f47..5791efa4e5 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h
@@ -42,6 +42,13 @@
class RasterizerCanvasRD : public RasterizerCanvas {
RasterizerStorageRD *storage;
+ enum {
+ BASE_UNIFORM_SET = 0,
+ MATERIAL_UNIFORM_SET = 1,
+ TRANSFORMS_UNIFORM_SET = 2,
+ CANVAS_TEXTURE_UNIFORM_SET = 3,
+ };
+
enum ShaderVariant {
SHADER_VARIANT_QUAD,
SHADER_VARIANT_NINEPATCH,
@@ -100,7 +107,7 @@ class RasterizerCanvasRD : public RasterizerCanvas {
enum {
MAX_RENDER_ITEMS = 256 * 1024,
MAX_LIGHT_TEXTURES = 1024,
- DEFAULT_MAX_LIGHTS_PER_ITEM = 16,
+ MAX_LIGHTS_PER_ITEM = 16,
DEFAULT_MAX_LIGHTS_PER_RENDER = 256
};
@@ -135,7 +142,6 @@ class RasterizerCanvasRD : public RasterizerCanvas {
CanvasShaderRD canvas_shader;
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;
@@ -178,7 +184,6 @@ class RasterizerCanvasRD : public RasterizerCanvas {
Map<StringName, RID> default_texture_params;
bool uses_screen_texture;
- bool uses_material_samplers;
virtual void set_code(const String &p_Code);
virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
@@ -218,60 +223,9 @@ class RasterizerCanvasRD : public RasterizerCanvas {
}
/**************************/
- /**** TEXTURE BINDINGS ****/
+ /**** CANVAS TEXTURES *****/
/**************************/
- // bindings used to render commands,
- // cached for performance.
-
- struct TextureBindingKey {
- RID texture;
- RID normalmap;
- RID specular;
- RID multimesh;
- RS::CanvasItemTextureFilter texture_filter;
- RS::CanvasItemTextureRepeat texture_repeat;
- bool operator==(const TextureBindingKey &p_key) const {
- return texture == p_key.texture && normalmap == p_key.normalmap && specular == p_key.specular && multimesh == p_key.specular && texture_filter == p_key.texture_filter && texture_repeat == p_key.texture_repeat;
- }
- };
-
- struct TextureBindingKeyHasher {
- static _FORCE_INLINE_ uint32_t hash(const TextureBindingKey &p_key) {
- uint32_t hash = hash_djb2_one_64(p_key.texture.get_id());
- hash = hash_djb2_one_64(p_key.normalmap.get_id(), hash);
- hash = hash_djb2_one_64(p_key.specular.get_id(), hash);
- hash = hash_djb2_one_64(p_key.multimesh.get_id(), hash);
- hash = hash_djb2_one_32(uint32_t(p_key.texture_filter) << 16 | uint32_t(p_key.texture_repeat), hash);
- return hash;
- }
- };
-
- struct TextureBinding {
- TextureBindingID id;
- TextureBindingKey key;
- SelfList<TextureBinding> to_dispose;
- uint32_t reference_count;
- RID uniform_set;
- TextureBinding() :
- to_dispose(this) {
- reference_count = 0;
- }
- };
-
- struct {
- SelfList<TextureBinding>::List to_dispose_list;
-
- TextureBindingID id_generator;
- HashMap<TextureBindingKey, TextureBindingID, TextureBindingKeyHasher> texture_key_bindings;
- HashMap<TextureBindingID, TextureBinding *> texture_bindings;
-
- TextureBindingID default_empty;
- } bindings;
-
- RID _create_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat, RID p_multimesh);
- void _dispose_bindings();
-
struct {
RS::CanvasItemTextureFilter default_filter;
RS::CanvasItemTextureRepeat default_repeat;
@@ -313,10 +267,9 @@ class RasterizerCanvasRD : public RasterizerCanvas {
struct CanvasLight {
RID texture;
struct {
- int size;
- RID texture;
- RID depth;
- RID fb;
+ bool enabled = false;
+ float z_far;
+ float y_offset;
} shadow;
};
@@ -326,7 +279,8 @@ class RasterizerCanvasRD : public RasterizerCanvas {
float projection[16];
float modelview[8];
float direction[2];
- float pad[2];
+ float z_far;
+ float pad;
};
struct OccluderPolygon {
@@ -342,12 +296,17 @@ class RasterizerCanvasRD : public RasterizerCanvas {
float matrix[8]; //light to texture coordinate matrix
float shadow_matrix[8]; //light to shadow coordinate matrix
float color[4];
- float shadow_color[4];
- float position[2];
+
+ uint8_t shadow_color[4];
uint32_t flags; //index to light texture
- float height;
float shadow_pixel_size;
- float pad[3];
+ float height;
+
+ float position[2];
+ float shadow_z_far_inv;
+ float shadow_y_ofs;
+
+ float atlas_rect[4];
};
RID_Owner<OccluderPolygon> occluder_polygon_owner;
@@ -366,34 +325,6 @@ 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 state_uniform_set_with_light;
- 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 = nullptr;
- }
- light_cache_count = 0xFFFFFFFF;
- }
-
- ~ItemStateData() {
- if (state_uniform_set_with_light.is_valid() && RD::get_singleton()->uniform_set_is_valid(state_uniform_set_with_light)) {
- RD::get_singleton()->free(state_uniform_set_with_light);
- }
- 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
struct Buffer {
@@ -414,6 +345,12 @@ class RasterizerCanvasRD : public RasterizerCanvas {
RID lights_uniform_buffer;
RID canvas_state_buffer;
RID shadow_sampler;
+ RID shadow_texture;
+ RID shadow_depth_texture;
+ RID shadow_fb;
+ int shadow_texture_size = 2048;
+
+ RID default_transforms_uniform_set;
uint32_t max_lights_per_render;
uint32_t max_lights_per_item;
@@ -452,9 +389,16 @@ class RasterizerCanvasRD : public RasterizerCanvas {
Item *items[MAX_RENDER_ITEMS];
- Size2i _bind_texture_binding(TextureBindingID p_binding, RenderingDevice::DrawListID p_draw_list, uint32_t &flags);
+ RID default_canvas_texture;
+
+ RS::CanvasItemTextureFilter default_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR;
+ RS::CanvasItemTextureRepeat default_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED;
+
+ RID _create_base_uniform_set(RID p_to_render_target, bool p_backbuffer);
+
+ inline void _bind_canvas_texture(RD::DrawListID p_draw_list, RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID &r_last_texture, PushConstant &push_constant, Size2 &r_texpixel_size); //recursive, so regular inline used instead.
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, PipelineVariants *p_pipeline_variants);
- void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, RID p_screen_uniform_set);
+ 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);
_FORCE_INLINE_ void _update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3);
@@ -462,30 +406,27 @@ class RasterizerCanvasRD : public RasterizerCanvas {
_FORCE_INLINE_ void _update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4);
_FORCE_INLINE_ void _update_transform_to_mat4(const Transform &p_transform, float *p_mat4);
- _FORCE_INLINE_ void _update_specular_shininess(const Color &p_transform, uint32_t *r_ss);
-
public:
- TextureBindingID request_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, RS::CanvasItemTextureFilter p_filter, RS::CanvasItemTextureRepeat p_repeat, RID p_multimesh);
- void free_texture_binding(TextureBindingID p_binding);
-
PolygonID request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>());
void free_polygon(PolygonID p_polygon);
RID light_create();
void light_set_texture(RID p_rid, RID p_texture);
- void light_set_use_shadow(RID p_rid, bool p_enable, int p_resolution);
- void light_update_shadow(RID p_rid, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders);
+ void light_set_use_shadow(RID p_rid, bool p_enable);
+ void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders);
RID occluder_polygon_create();
void occluder_polygon_set_shape_as_lines(RID p_occluder, const Vector<Vector2> &p_lines);
void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode);
- void 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);
+ void 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, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat);
void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) {}
void draw_window_margins(int *p_margins, RID *p_margin_textures) {}
+ virtual void set_shadow_texture_size(int p_size);
+
void set_time(double p_time);
void update();
bool free(RID p_rid);
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
index f708b6ce00..0cae141138 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
@@ -8334,8 +8334,8 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
{
RD::SamplerState sampler;
- sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR;
- sampler.min_filter = RD::SAMPLER_FILTER_LINEAR;
+ sampler.mag_filter = RD::SAMPLER_FILTER_NEAREST;
+ sampler.min_filter = RD::SAMPLER_FILTER_NEAREST;
sampler.enable_compare = true;
sampler.compare_op = RD::COMPARE_OP_LESS;
shadow_sampler = RD::get_singleton()->sampler_create(sampler);
diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
index e723028e56..b47d724147 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
@@ -1118,6 +1118,11 @@ void RasterizerStorageRD::texture_replace(RID p_texture, RID p_by_texture) {
}
RD::get_singleton()->free(tex->rd_texture);
+ if (tex->canvas_texture) {
+ memdelete(tex->canvas_texture);
+ tex->canvas_texture = nullptr;
+ }
+
Vector<RID> proxies_to_update = tex->proxies;
Vector<RID> proxies_to_redirect = by_tex->proxies;
@@ -1125,6 +1130,10 @@ void RasterizerStorageRD::texture_replace(RID p_texture, RID p_by_texture) {
tex->proxies = proxies_to_update; //restore proxies, so they can be updated
+ if (tex->canvas_texture) {
+ tex->canvas_texture->diffuse = p_texture; //update
+ }
+
for (int i = 0; i < proxies_to_update.size(); i++) {
texture_proxy_update(proxies_to_update[i], p_texture);
}
@@ -1193,6 +1202,167 @@ Size2 RasterizerStorageRD::texture_size_with_proxy(RID p_proxy) {
return texture_2d_get_size(p_proxy);
}
+/* CANVAS TEXTURE */
+
+void RasterizerStorageRD::CanvasTexture::clear_sets() {
+ if (cleared_cache) {
+ return;
+ }
+ for (int i = 1; i < RS::CANVAS_ITEM_TEXTURE_FILTER_MAX; i++) {
+ for (int j = 1; j < RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX; j++) {
+ if (RD::get_singleton()->uniform_set_is_valid(uniform_sets[i][j])) {
+ RD::get_singleton()->free(uniform_sets[i][j]);
+ uniform_sets[i][j] = RID();
+ }
+ }
+ }
+ cleared_cache = true;
+}
+
+RasterizerStorageRD::CanvasTexture::~CanvasTexture() {
+ clear_sets();
+}
+
+RID RasterizerStorageRD::canvas_texture_create() {
+ return canvas_texture_owner.make_rid(memnew(CanvasTexture));
+}
+
+void RasterizerStorageRD::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
+ CanvasTexture *ct = canvas_texture_owner.getornull(p_canvas_texture);
+ switch (p_channel) {
+ case RS::CANVAS_TEXTURE_CHANNEL_DIFFUSE: {
+ ct->diffuse = p_texture;
+ } break;
+ case RS::CANVAS_TEXTURE_CHANNEL_NORMAL: {
+ ct->normalmap = p_texture;
+ } break;
+ case RS::CANVAS_TEXTURE_CHANNEL_SPECULAR: {
+ ct->specular = p_texture;
+ } break;
+ }
+
+ ct->clear_sets();
+}
+
+void RasterizerStorageRD::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) {
+ CanvasTexture *ct = canvas_texture_owner.getornull(p_canvas_texture);
+ ct->specular_color.r = p_specular_color.r;
+ ct->specular_color.g = p_specular_color.g;
+ ct->specular_color.b = p_specular_color.b;
+ ct->specular_color.a = p_shininess;
+ ct->clear_sets();
+}
+
+void RasterizerStorageRD::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) {
+ CanvasTexture *ct = canvas_texture_owner.getornull(p_canvas_texture);
+ ct->texture_filter = p_filter;
+ ct->clear_sets();
+}
+
+void RasterizerStorageRD::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {
+ CanvasTexture *ct = canvas_texture_owner.getornull(p_canvas_texture);
+ ct->texture_repeat = p_repeat;
+ ct->clear_sets();
+}
+
+bool RasterizerStorageRD::canvas_texture_get_unifom_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular) {
+ CanvasTexture *ct = nullptr;
+
+ Texture *t = texture_owner.getornull(p_texture);
+
+ if (t) {
+ //regular texture
+ if (!t->canvas_texture) {
+ t->canvas_texture = memnew(CanvasTexture);
+ t->canvas_texture->diffuse = p_texture;
+ }
+
+ ct = t->canvas_texture;
+ } else {
+ ct = canvas_texture_owner.getornull(p_texture);
+ }
+
+ if (!ct) {
+ return false; //invalid texture RID
+ }
+
+ RS::CanvasItemTextureFilter filter = ct->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT ? ct->texture_filter : p_base_filter;
+ ERR_FAIL_COND_V(filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, false);
+
+ RS::CanvasItemTextureRepeat repeat = ct->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT ? ct->texture_repeat : p_base_repeat;
+ ERR_FAIL_COND_V(repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, false);
+
+ RID uniform_set = ct->uniform_sets[filter][repeat];
+ if (!RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ //create and update
+ Vector<RD::Uniform> uniforms;
+ { //diffuse
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 0;
+
+ t = texture_owner.getornull(ct->diffuse);
+ if (!t) {
+ u.ids.push_back(texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE));
+ ct->size_cache = Size2i(1, 1);
+ } else {
+ u.ids.push_back(t->rd_texture);
+ ct->size_cache = Size2i(t->width_2d, t->height_2d);
+ }
+ uniforms.push_back(u);
+ }
+ { //normal
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 1;
+
+ t = texture_owner.getornull(ct->normalmap);
+ if (!t) {
+ u.ids.push_back(texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL));
+ ct->use_normal_cache = false;
+ } else {
+ u.ids.push_back(t->rd_texture);
+ ct->use_normal_cache = true;
+ }
+ uniforms.push_back(u);
+ }
+ { //specular
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 2;
+
+ t = texture_owner.getornull(ct->specular);
+ if (!t) {
+ u.ids.push_back(texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE));
+ ct->use_specular_cache = false;
+ } else {
+ u.ids.push_back(t->rd_texture);
+ ct->use_specular_cache = true;
+ }
+ uniforms.push_back(u);
+ }
+ { //sampler
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 3;
+ u.ids.push_back(sampler_rd_get_default(filter, repeat));
+ uniforms.push_back(u);
+ }
+
+ uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_base_shader, p_base_set);
+ ct->uniform_sets[filter][repeat] = uniform_set;
+ ct->cleared_cache = false;
+ }
+
+ r_uniform_set = uniform_set;
+ r_size = ct->size_cache;
+ r_specular_shininess = ct->specular_color;
+ r_use_normal = ct->use_normal_cache;
+ r_use_specular = ct->use_specular_cache;
+
+ return true;
+}
+
/* SHADER API */
RID RasterizerStorageRD::shader_create() {
@@ -5842,6 +6012,7 @@ void RasterizerStorageRD::_clear_render_target(RenderTarget *rt) {
//free in reverse dependency order
if (rt->framebuffer.is_valid()) {
RD::get_singleton()->free(rt->framebuffer);
+ rt->framebuffer_uniform_set = RID(); //chain deleted
}
if (rt->color.is_valid()) {
@@ -5856,10 +6027,7 @@ void RasterizerStorageRD::_clear_render_target(RenderTarget *rt) {
RD::get_singleton()->free(rt->backbuffer_mipmaps[i].mipmap_copy);
}
rt->backbuffer_mipmaps.clear();
- if (rt->backbuffer_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rt->backbuffer_uniform_set)) {
- RD::get_singleton()->free(rt->backbuffer_uniform_set);
- }
- rt->backbuffer_uniform_set = RID();
+ rt->backbuffer_uniform_set = RID(); //chain deleted
}
rt->framebuffer = RID();
@@ -5969,6 +6137,11 @@ void RasterizerStorageRD::_create_render_target_backbuffer(RenderTarget *rt) {
rt->backbuffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
rt->backbuffer_mipmap0 = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, 0);
+ if (rt->framebuffer_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rt->framebuffer_uniform_set)) {
+ //the new one will require the backbuffer.
+ RD::get_singleton()->free(rt->framebuffer_uniform_set);
+ rt->framebuffer_uniform_set = RID();
+ }
//create mipmaps
for (uint32_t i = 1; i < mipmaps_required; i++) {
RenderTarget::BackbufferMipmap mm;
@@ -6066,6 +6239,12 @@ RID RasterizerStorageRD::render_target_get_rd_texture(RID p_render_target) {
return rt->color;
}
+RID RasterizerStorageRD::render_target_get_rd_backbuffer(RID p_render_target) {
+ RenderTarget *rt = render_target_owner.getornull(p_render_target);
+ ERR_FAIL_COND_V(!rt, RID());
+ return rt->backbuffer;
+}
+
void RasterizerStorageRD::render_target_request_clear(RID p_render_target, const Color &p_clear_color) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
@@ -6135,32 +6314,28 @@ void RasterizerStorageRD::render_target_copy_to_back_buffer(RID p_render_target,
}
}
-RID RasterizerStorageRD::render_target_get_back_buffer_uniform_set(RID p_render_target, RID p_base_shader) {
+RID RasterizerStorageRD::render_target_get_framebuffer_uniform_set(RID p_render_target) {
+ RenderTarget *rt = render_target_owner.getornull(p_render_target);
+ ERR_FAIL_COND_V(!rt, RID());
+ return rt->framebuffer_uniform_set;
+}
+RID RasterizerStorageRD::render_target_get_backbuffer_uniform_set(RID p_render_target) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, RID());
-
- if (!rt->backbuffer.is_valid()) {
- _create_render_target_backbuffer(rt);
- }
-
- if (rt->backbuffer_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rt->backbuffer_uniform_set)) {
- return rt->backbuffer_uniform_set; //if still valid, return/reuse it.
- }
-
- //create otherwise
- Vector<RD::Uniform> uniforms;
- RD::Uniform u;
- u.type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 0;
- u.ids.push_back(rt->backbuffer);
- uniforms.push_back(u);
-
- rt->backbuffer_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_base_shader, 3);
- ERR_FAIL_COND_V(!rt->backbuffer_uniform_set.is_valid(), RID());
-
return rt->backbuffer_uniform_set;
}
+void RasterizerStorageRD::render_target_set_framebuffer_uniform_set(RID p_render_target, RID p_uniform_set) {
+ RenderTarget *rt = render_target_owner.getornull(p_render_target);
+ ERR_FAIL_COND(!rt);
+ rt->framebuffer_uniform_set = p_uniform_set;
+}
+void RasterizerStorageRD::render_target_set_backbuffer_uniform_set(RID p_render_target, RID p_uniform_set) {
+ RenderTarget *rt = render_target_owner.getornull(p_render_target);
+ ERR_FAIL_COND(!rt);
+ rt->backbuffer_uniform_set = p_uniform_set;
+}
+
void RasterizerStorageRD::base_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) {
if (mesh_owner.owns(p_base)) {
Mesh *mesh = mesh_owner.getornull(p_base);
@@ -7192,8 +7367,16 @@ bool RasterizerStorageRD::free(RID p_rid) {
p->rd_texture = RID();
p->rd_texture_srgb = RID();
}
+
+ if (t->canvas_texture) {
+ memdelete(t->canvas_texture);
+ }
texture_owner.free(p_rid);
+ } else if (canvas_texture_owner.owns(p_rid)) {
+ CanvasTexture *ct = canvas_texture_owner.getornull(p_rid);
+ memdelete(ct);
+ canvas_texture_owner.free(p_rid);
} else if (shader_owner.owns(p_rid)) {
Shader *shader = shader_owner.getornull(p_rid);
//make material unreference this
diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h
index b03a26e200..7caafca2e0 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h
@@ -174,6 +174,29 @@ public:
};
private:
+ /* CANVAS TEXTURE API (2D) */
+
+ struct CanvasTexture {
+ RID diffuse;
+ RID normalmap;
+ RID specular;
+ Color specular_color = Color(1, 1, 1, 1);
+ float shininess = 1.0;
+
+ RS::CanvasItemTextureFilter texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT;
+ RS::CanvasItemTextureRepeat texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT;
+ RID uniform_sets[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX];
+
+ Size2i size_cache = Size2i(1, 1);
+ bool use_normal_cache = false;
+ bool use_specular_cache = false;
+ bool cleared_cache = true;
+ void clear_sets();
+ ~CanvasTexture();
+ };
+
+ RID_PtrOwner<CanvasTexture> canvas_texture_owner;
+
/* TEXTURE API */
struct Texture {
enum Type {
@@ -231,6 +254,8 @@ private:
RS::TextureDetectRoughnessCallback detect_roughness_callback = nullptr;
void *detect_roughness_callback_ud = nullptr;
+
+ CanvasTexture *canvas_texture = nullptr;
};
struct TextureToRDFormat {
@@ -972,6 +997,8 @@ private:
};
Vector<BackbufferMipmap> backbuffer_mipmaps;
+
+ RID framebuffer_uniform_set;
RID backbuffer_uniform_set;
//texture generated for this owner (nor RD).
@@ -1147,6 +1174,18 @@ public:
return default_rd_samplers[p_filter][p_repeat];
}
+ /* CANVAS TEXTURE API */
+
+ virtual RID canvas_texture_create();
+
+ virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture);
+ virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess);
+
+ virtual void canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter);
+ virtual void canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat);
+
+ bool canvas_texture_get_unifom_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular);
+
/* SHADER API */
RID shader_create();
@@ -1878,6 +1917,7 @@ public:
bool render_target_was_used(RID p_render_target);
void render_target_set_as_unused(RID p_render_target);
void render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region);
+
RID render_target_get_back_buffer_uniform_set(RID p_render_target, RID p_base_shader);
virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color);
@@ -1889,6 +1929,13 @@ public:
Size2 render_target_get_size(RID p_render_target);
RID render_target_get_rd_framebuffer(RID p_render_target);
RID render_target_get_rd_texture(RID p_render_target);
+ RID render_target_get_rd_backbuffer(RID p_render_target);
+
+ RID render_target_get_framebuffer_uniform_set(RID p_render_target);
+ RID render_target_get_backbuffer_uniform_set(RID p_render_target);
+
+ void render_target_set_framebuffer_uniform_set(RID p_render_target, RID p_uniform_set);
+ void render_target_set_backbuffer_uniform_set(RID p_render_target, RID p_uniform_set);
RS::InstanceType get_base_type(RID p_rid) const;
@@ -1916,6 +1963,8 @@ public:
virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const;
virtual String get_captured_timestamp_name(uint32_t p_index) const;
+ RID get_default_rd_storage_buffer() { return default_rd_storage_buffer; }
+
static RasterizerStorageRD *base_singleton;
RasterizerEffectsRD *get_effects();
diff --git a/servers/rendering/rasterizer_rd/shaders/canvas.glsl b/servers/rendering/rasterizer_rd/shaders/canvas.glsl
index 4a40584e16..04a37e501f 100644
--- a/servers/rendering/rasterizer_rd/shaders/canvas.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/canvas.glsl
@@ -26,7 +26,7 @@ layout(location = 3) out vec2 pixel_size_interp;
#endif
#ifdef USE_MATERIAL_UNIFORMS
-layout(set = 1, binding = 1, std140) uniform MaterialUniforms{
+layout(set = 1, binding = 0, std140) uniform MaterialUniforms{
/* clang-format off */
MATERIAL_UNIFORMS
/* clang-format on */
@@ -226,7 +226,7 @@ layout(location = 3) in vec2 pixel_size_interp;
layout(location = 0) out vec4 frag_color;
#ifdef USE_MATERIAL_UNIFORMS
-layout(set = 1, binding = 1, std140) uniform MaterialUniforms{
+layout(set = 1, binding = 0, std140) uniform MaterialUniforms{
/* clang-format off */
MATERIAL_UNIFORMS
/* clang-format on */
@@ -408,7 +408,7 @@ FRAGMENT_SHADER_CODE
color *= canvas_data.canvas_modulation;
#ifdef USE_LIGHTING
- for (uint i = 0; i < MAX_LIGHT_TEXTURES; i++) {
+ for (uint i = 0; i < MAX_LIGHTS_PER_ITEM; i++) {
if (i >= light_count) {
break;
}
@@ -430,7 +430,8 @@ FRAGMENT_SHADER_CODE
light_base &= 0xFF;
vec2 tex_uv = (vec4(vertex, 0.0, 1.0) * mat4(light_array.data[light_base].texture_matrix[0], light_array.data[light_base].texture_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.
- vec4 light_color = texture(sampler2D(light_textures[i], texture_sampler), tex_uv);
+ vec2 tex_uv_atlas = tex_uv * light_array.data[light_base].atlas_rect.zw + light_array.data[light_base].atlas_rect.xy;
+ vec4 light_color = textureLod(sampler2D(atlas_texture, texture_sampler), tex_uv_atlas, 0.0);
vec4 light_base_color = light_array.data[light_base].color;
#ifdef LIGHT_SHADER_CODE_USED
@@ -502,47 +503,53 @@ FRAGMENT_SHADER_CODE
}
}
+ distance *= light_array.data[light_base].shadow_zfar_inv;
+
//float distance = length(shadow_pos);
float shadow;
uint shadow_mode = light_array.data[light_base].flags & LIGHT_FLAGS_FILTER_MASK;
- vec4 shadow_uv = vec4(tex_ofs, 0.0, distance, 1.0);
+ vec4 shadow_uv = vec4(tex_ofs, light_array.data[light_base].shadow_y_ofs, distance, 1.0);
if (shadow_mode == LIGHT_FLAGS_SHADOW_NEAREST) {
- shadow = textureProj(sampler2DShadow(shadow_textures[i], shadow_sampler), shadow_uv).x;
+ shadow = textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv, 0.0).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[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 += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 2.0, 0.0).x;
+ shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size, 0.0).x;
+ shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv, 0.0).x;
+ shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size, 0.0).x;
+ shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 2.0, 0.0).x;
shadow /= 5.0;
} 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[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 += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 6.0, 0.0).x;
+ shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 5.0, 0.0).x;
+ shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 4.0, 0.0).x;
+ shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 3.0, 0.0).x;
+ shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size * 2.0, 0.0).x;
+ shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv - shadow_pixel_size, 0.0).x;
+ shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv, 0.0).x;
+ shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size, 0.0).x;
+ shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 2.0, 0.0).x;
+ shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 3.0, 0.0).x;
+ shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 4.0, 0.0).x;
+ shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 5.0, 0.0).x;
+ shadow += textureProjLod(sampler2DShadow(shadow_atlas_texture, shadow_sampler), shadow_uv + shadow_pixel_size * 6.0, 0.0).x;
shadow /= 13.0;
}
- vec4 shadow_color = light_array.data[light_base].shadow_color;
+ vec4 shadow_color = unpackUnorm4x8(light_array.data[light_base].shadow_color);
#ifdef LIGHT_SHADER_CODE_USED
shadow_color *= shadow_modulate;
#endif
+
+ shadow_color.a *= light_color.a; //respect light alpha
+
light_color = mix(light_color, shadow_color, shadow);
+ //light_color = mix(light_color, shadow_color, shadow);
}
uint blend_mode = light_array.data[light_base].flags & LIGHT_FLAGS_BLEND_MASK;
diff --git a/servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl b/servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl
index 99e70a1976..421282cd4d 100644
--- a/servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl
@@ -8,7 +8,8 @@ layout(push_constant, binding = 0, std430) uniform Constants {
mat4 projection;
mat2x4 modelview;
vec2 direction;
- vec2 pad;
+ float z_far;
+ float pad;
}
constants;
@@ -25,9 +26,18 @@ void main() {
#version 450
+layout(push_constant, binding = 0, std430) uniform Constants {
+ mat4 projection;
+ mat2x4 modelview;
+ vec2 direction;
+ float z_far;
+ float pad;
+}
+constants;
+
layout(location = 0) in highp float depth;
layout(location = 0) out highp float distance_buf;
void main() {
- distance_buf = depth;
+ distance_buf = depth / constants.z_far;
}
diff --git a/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl b/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl
index a39866004b..e4dc326af6 100644
--- a/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/canvas_uniforms_inc.glsl
@@ -1,3 +1,6 @@
+
+#define MAX_LIGHTS_PER_ITEM 16
+
#define M_PI 3.14159265359
#define FLAGS_INSTANCING_STRIDE_MASK 0xF
@@ -22,13 +25,7 @@
#define FLAGS_DEFAULT_NORMAL_MAP_USED (1 << 26)
#define FLAGS_DEFAULT_SPECULAR_MAP_USED (1 << 27)
-// In vulkan, sets should always be ordered using the following logic:
-// Lower Sets: Sets that change format and layout less often
-// Higher sets: Sets that change format and layout very often
-// This is because changing a set for another with a different layout or format,
-// invalidates all the upper ones.
-
-/* SET0: Draw Primitive */
+// Push Constant
layout(push_constant, binding = 0, std430) uniform DrawData {
vec2 world_x;
@@ -53,26 +50,17 @@ layout(push_constant, binding = 0, std430) uniform DrawData {
}
draw_data;
-// The values passed per draw primitives are cached within it
-
-layout(set = 0, binding = 1) uniform texture2D color_texture;
-layout(set = 0, binding = 2) uniform texture2D normal_texture;
-layout(set = 0, binding = 3) uniform texture2D specular_texture;
-layout(set = 0, binding = 4) uniform sampler texture_sampler;
-
-layout(set = 0, binding = 5) uniform textureBuffer instancing_buffer;
-
-/* SET1: Is reserved for the material */
-
-#ifdef USE_MATERIAL_SAMPLERS
-
-layout(set = 1, binding = 0) uniform sampler material_samplers[12];
+// In vulkan, sets should always be ordered using the following logic:
+// Lower Sets: Sets that change format and layout less often
+// Higher sets: Sets that change format and layout very often
+// This is because changing a set for another with a different layout or format,
+// invalidates all the upper ones (as likely internal base offset changes)
-#endif
+/* SET0: Globals */
-/* SET2: Canvas Item State (including lighting) */
+// The values passed per draw primitives are cached within it
-layout(set = 2, binding = 0, std140) uniform CanvasData {
+layout(set = 0, binding = 1, std140) uniform CanvasData {
mat4 canvas_transform;
mat4 screen_transform;
mat4 canvas_normal_transform;
@@ -84,16 +72,6 @@ layout(set = 2, binding = 0, std140) uniform CanvasData {
}
canvas_data;
-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;
-
-#ifdef USE_LIGHTING
-
#define LIGHT_FLAGS_BLEND_MASK (3 << 16)
#define LIGHT_FLAGS_BLEND_MODE_ADD (0 << 16)
#define LIGHT_FLAGS_BLEND_MODE_SUB (1 << 16)
@@ -110,37 +88,52 @@ struct Light {
mat2x4 texture_matrix; //light to texture coordinate matrix (transposed)
mat2x4 shadow_matrix; //light to shadow coordinate matrix (transposed)
vec4 color;
- vec4 shadow_color;
- vec2 position;
+
+ uint shadow_color; // packed
uint flags; //index to light texture
- float height;
float shadow_pixel_size;
- float pad0;
- float pad1;
- float pad2;
+ float height;
+
+ vec2 position;
+ float shadow_zfar_inv;
+ float shadow_y_ofs;
+
+ vec4 atlas_rect;
};
-layout(set = 2, binding = 3, std140) uniform LightData {
+layout(set = 0, binding = 2, std140) uniform LightData {
Light data[MAX_LIGHTS];
}
light_array;
-layout(set = 2, binding = 4) uniform texture2D light_textures[MAX_LIGHT_TEXTURES];
-layout(set = 2, binding = 5) uniform texture2D shadow_textures[MAX_LIGHT_TEXTURES];
+layout(set = 0, binding = 3) uniform texture2D atlas_texture;
+layout(set = 0, binding = 4) uniform texture2D shadow_atlas_texture;
-layout(set = 2, binding = 6) uniform sampler shadow_sampler;
+layout(set = 0, binding = 5) uniform sampler shadow_sampler;
-#endif
+layout(set = 0, binding = 6) uniform texture2D screen_texture;
+
+layout(set = 0, binding = 7) uniform sampler material_samplers[12];
-layout(set = 2, binding = 7, std430) restrict readonly buffer GlobalVariableData {
+layout(set = 0, binding = 8, std430) restrict readonly buffer GlobalVariableData {
vec4 data[];
}
global_variables;
-/* SET3: Render Target Data */
+/* SET1: Is reserved for the material */
-#ifdef SCREEN_TEXTURE_USED
+//
-layout(set = 3, binding = 0) uniform texture2D screen_texture;
+/* SET2: Instancing and Skeleton */
-#endif
+layout(set = 2, binding = 0, std430) restrict readonly buffer Transforms {
+ vec4 data[];
+}
+transforms;
+
+/* SET3: Texture */
+
+layout(set = 3, binding = 0) uniform texture2D color_texture;
+layout(set = 3, binding = 1) uniform texture2D normal_texture;
+layout(set = 3, binding = 2) uniform texture2D specular_texture;
+layout(set = 3, binding = 3) uniform sampler texture_sampler;
diff --git a/servers/rendering/rendering_server_canvas.cpp b/servers/rendering/rendering_server_canvas.cpp
index b3d5b0ad83..b0bff8b2c2 100644
--- a/servers/rendering/rendering_server_canvas.cpp
+++ b/servers/rendering/rendering_server_canvas.cpp
@@ -37,7 +37,7 @@
static const int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1;
-void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights) {
+void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat) {
RENDER_TIMESTAMP("Cull CanvasItem Tree");
memset(z_list, 0, z_range * sizeof(RasterizerCanvas::Item *));
@@ -68,7 +68,7 @@ void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Can
RENDER_TIMESTAMP("Render Canvas Items");
- RSG::canvas_render->canvas_render_items(p_to_render_target, list, p_modulate, p_lights, p_transform);
+ RSG::canvas_render->canvas_render_items(p_to_render_target, list, p_modulate, p_lights, p_transform, p_default_filter, p_default_repeat);
}
void _collect_ysort_children(RenderingServerCanvas::Item *p_canvas_item, Transform2D p_transform, RenderingServerCanvas::Item *p_material_owner, RenderingServerCanvas::Item **r_items, int &r_index) {
@@ -243,7 +243,7 @@ void RenderingServerCanvas::_light_mask_canvas_items(int p_z, RasterizerCanvas::
}
}
-void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_masked_lights, const Rect2 &p_clip_rect) {
+void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_masked_lights, const Rect2 &p_clip_rect, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat) {
RENDER_TIMESTAMP(">Render Canvas");
if (p_canvas->children_order_dirty) {
@@ -263,26 +263,26 @@ void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas,
}
if (!has_mirror) {
- _render_canvas_item_tree(p_render_target, ci, l, nullptr, p_transform, p_clip_rect, p_canvas->modulate, p_lights);
+ _render_canvas_item_tree(p_render_target, ci, l, nullptr, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat);
} else {
//used for parallaxlayer mirroring
for (int i = 0; i < l; i++) {
const Canvas::ChildItem &ci2 = p_canvas->child_items[i];
- _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, p_transform, p_clip_rect, p_canvas->modulate, p_lights);
+ _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, p_transform, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat);
//mirroring (useful for scrolling backgrounds)
if (ci2.mirror.x != 0) {
Transform2D xform2 = p_transform * Transform2D(0, Vector2(ci2.mirror.x, 0));
- _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights);
+ _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat);
}
if (ci2.mirror.y != 0) {
Transform2D xform2 = p_transform * Transform2D(0, Vector2(0, ci2.mirror.y));
- _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights);
+ _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat);
}
if (ci2.mirror.y != 0 && ci2.mirror.x != 0) {
Transform2D xform2 = p_transform * Transform2D(0, ci2.mirror);
- _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights);
+ _render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights, p_default_filter, p_default_repeat);
}
}
}
@@ -451,18 +451,6 @@ void RenderingServerCanvas::canvas_item_set_update_when_visible(RID p_item, bool
canvas_item->update_when_visible = p_update;
}
-void RenderingServerCanvas::canvas_item_set_default_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) {
- Item *canvas_item = canvas_item_owner.getornull(p_item);
- ERR_FAIL_COND(!canvas_item);
- canvas_item->texture_filter = p_filter;
-}
-
-void RenderingServerCanvas::canvas_item_set_default_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) {
- Item *canvas_item = canvas_item_owner.getornull(p_item);
- ERR_FAIL_COND(!canvas_item);
- canvas_item->texture_repeat = p_repeat;
-}
-
void RenderingServerCanvas::canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -484,7 +472,6 @@ void RenderingServerCanvas::canvas_item_add_line(RID p_item, const Point2 &p_fro
for (uint32_t i = 0; i < line->point_count; i++) {
line->colors[i] = p_color;
}
- line->specular_shininess = Color(1, 1, 1, 1);
}
void RenderingServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) {
@@ -495,8 +482,6 @@ void RenderingServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Po
Item::CommandPolygon *pline = canvas_item->alloc_command<Item::CommandPolygon>();
ERR_FAIL_COND(!pline);
- pline->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, RID(), RID(), RID(), RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED, RID());
-
if (true || p_width <= 1) {
#define TODO make thick lines possible
Vector<int> indices;
@@ -511,7 +496,6 @@ void RenderingServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Po
}
pline->primitive = RS::PRIMITIVE_LINES;
- pline->specular_shininess = Color(1, 1, 1, 1);
pline->polygon.create(indices, p_points, p_colors);
} else {
#if 0
@@ -586,13 +570,10 @@ void RenderingServerCanvas::canvas_item_add_multiline(RID p_item, const Vector<P
Item::CommandPolygon *pline = canvas_item->alloc_command<Item::CommandPolygon>();
ERR_FAIL_COND(!pline);
- pline->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, RID(), RID(), RID(), RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED, RID());
-
if (true || p_width <= 1) {
#define TODO make thick lines possible
pline->primitive = RS::PRIMITIVE_LINES;
- pline->specular_shininess = Color(1, 1, 1, 1);
pline->polygon.create(Vector<int>(), p_points, p_colors);
} else {
}
@@ -615,10 +596,7 @@ void RenderingServerCanvas::canvas_item_add_circle(RID p_item, const Point2 &p_p
Item::CommandPolygon *circle = canvas_item->alloc_command<Item::CommandPolygon>();
ERR_FAIL_COND(!circle);
- circle->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, RID(), RID(), RID(), RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED, RID());
-
circle->primitive = RS::PRIMITIVE_TRIANGLES;
- circle->specular_shininess = Color(1, 1, 1, 1);
Vector<int> indices;
Vector<Vector2> points;
@@ -645,7 +623,7 @@ void RenderingServerCanvas::canvas_item_add_circle(RID p_item, const Point2 &p_p
circle->polygon.create(indices, points, color);
}
-void RenderingServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile, const Color &p_modulate, bool p_transpose, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) {
+void RenderingServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile, const Color &p_modulate, bool p_transpose) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -672,11 +650,11 @@ void RenderingServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2
rect->flags |= RasterizerCanvas::CANVAS_RECT_TRANSPOSE;
SWAP(rect->rect.size.x, rect->rect.size.y);
}
- rect->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, p_texture, p_normal_map, p_specular_map, p_filter, p_repeat, RID());
- rect->specular_shininess = p_specular_color_shininess;
+
+ rect->texture = p_texture;
}
-void RenderingServerCanvas::canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, bool p_clip_uv, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) {
+void RenderingServerCanvas::canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, bool p_clip_uv) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -684,8 +662,9 @@ void RenderingServerCanvas::canvas_item_add_texture_rect_region(RID p_item, cons
ERR_FAIL_COND(!rect);
rect->modulate = p_modulate;
rect->rect = p_rect;
- rect->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, p_texture, p_normal_map, p_specular_map, p_filter, p_repeat, RID());
- rect->specular_shininess = p_specular_color_shininess;
+
+ rect->texture = p_texture;
+
rect->source = p_src_rect;
rect->flags = RasterizerCanvas::CANVAS_RECT_REGION;
@@ -716,14 +695,15 @@ void RenderingServerCanvas::canvas_item_add_texture_rect_region(RID p_item, cons
}
}
-void RenderingServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, RS::NinePatchAxisMode p_x_axis_mode, RS::NinePatchAxisMode p_y_axis_mode, bool p_draw_center, const Color &p_modulate, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) {
+void RenderingServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, RS::NinePatchAxisMode p_x_axis_mode, RS::NinePatchAxisMode p_y_axis_mode, bool p_draw_center, const Color &p_modulate) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
Item::CommandNinePatch *style = canvas_item->alloc_command<Item::CommandNinePatch>();
ERR_FAIL_COND(!style);
- style->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, p_texture, p_normal_map, p_specular_map, p_filter, p_repeat, RID());
- style->specular_shininess = p_specular_color_shininess;
+
+ style->texture = p_texture;
+
style->rect = p_rect;
style->source = p_source;
style->draw_center = p_draw_center;
@@ -736,7 +716,7 @@ void RenderingServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 &
style->axis_y = p_y_axis_mode;
}
-void RenderingServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) {
+void RenderingServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width) {
uint32_t pc = p_points.size();
ERR_FAIL_COND(pc == 0 || pc > 4);
@@ -762,11 +742,10 @@ void RenderingServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<P
prim->point_count = p_points.size();
- prim->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, p_texture, p_normal_map, p_specular_map, p_filter, p_repeat, RID());
- prim->specular_shininess = p_specular_color_shininess;
+ prim->texture = p_texture;
}
-void RenderingServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) {
+void RenderingServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
#ifdef DEBUG_ENABLED
@@ -783,12 +762,11 @@ void RenderingServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Poi
Item::CommandPolygon *polygon = canvas_item->alloc_command<Item::CommandPolygon>();
ERR_FAIL_COND(!polygon);
polygon->primitive = RS::PRIMITIVE_TRIANGLES;
- polygon->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, p_texture, p_normal_map, p_specular_map, p_filter, p_repeat, RID());
- polygon->specular_shininess = p_specular_color_shininess;
+ polygon->texture = p_texture;
polygon->polygon.create(indices, p_points, p_colors, p_uvs);
}
-void RenderingServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights, RID p_texture, int p_count, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) {
+void RenderingServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights, RID p_texture, int p_count) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -803,8 +781,9 @@ void RenderingServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vec
Item::CommandPolygon *polygon = canvas_item->alloc_command<Item::CommandPolygon>();
ERR_FAIL_COND(!polygon);
- polygon->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, p_texture, p_normal_map, p_specular_map, p_filter, p_repeat, RID());
- polygon->specular_shininess = p_specular_color_shininess;
+
+ polygon->texture = p_texture;
+
polygon->polygon.create(indices, p_points, p_colors, p_uvs, p_bones, p_weights);
polygon->primitive = RS::PRIMITIVE_TRIANGLES;
@@ -819,42 +798,43 @@ void RenderingServerCanvas::canvas_item_add_set_transform(RID p_item, const Tran
tr->xform = p_transform;
}
-void RenderingServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform, const Color &p_modulate, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) {
+void RenderingServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform, const Color &p_modulate, RID p_texture) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
Item::CommandMesh *m = canvas_item->alloc_command<Item::CommandMesh>();
ERR_FAIL_COND(!m);
m->mesh = p_mesh;
- m->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, p_texture, p_normal_map, p_specular_map, p_filter, p_repeat, RID());
- m->specular_shininess = p_specular_color_shininess;
+
+ m->texture = p_texture;
+
m->transform = p_transform;
m->modulate = p_modulate;
}
-void RenderingServerCanvas::canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) {
+void RenderingServerCanvas::canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
Item::CommandParticles *part = canvas_item->alloc_command<Item::CommandParticles>();
ERR_FAIL_COND(!part);
part->particles = p_particles;
- part->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, p_texture, p_normal_map, p_specular_map, p_filter, p_repeat, RID());
- part->specular_shininess = p_specular_color_shininess;
+
+ part->texture = p_texture;
//take the chance and request processing for them, at least once until they become visible again
RSG::storage->particles_request_process(p_particles);
}
-void RenderingServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) {
+void RenderingServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
Item::CommandMultiMesh *mm = canvas_item->alloc_command<Item::CommandMultiMesh>();
ERR_FAIL_COND(!mm);
mm->multimesh = p_mesh;
- mm->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, p_texture, p_normal_map, p_specular_map, p_filter, p_repeat, mm->multimesh);
- mm->specular_shininess = p_specular_color_shininess;
+
+ mm->texture = p_texture;
}
void RenderingServerCanvas::canvas_item_add_clip_ignore(RID p_item, bool p_ignore) {
@@ -1007,6 +987,9 @@ void RenderingServerCanvas::canvas_light_set_texture(RID p_light, RID p_texture)
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
+ if (clight->texture == p_texture) {
+ return;
+ }
clight->texture = p_texture;
clight->version++;
RSG::canvas_render->light_set_texture(clight->light_internal, p_texture);
@@ -1086,24 +1069,7 @@ void RenderingServerCanvas::canvas_light_set_shadow_enabled(RID p_light, bool p_
}
clight->use_shadow = p_enabled;
clight->version++;
- RSG::canvas_render->light_set_use_shadow(clight->light_internal, clight->use_shadow, clight->shadow_buffer_size);
-}
-
-void RenderingServerCanvas::canvas_light_set_shadow_buffer_size(RID p_light, int p_size) {
- ERR_FAIL_COND(p_size < 32 || p_size > 16384);
-
- RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
- ERR_FAIL_COND(!clight);
-
- int new_size = next_power_of_2(p_size);
- if (new_size == clight->shadow_buffer_size) {
- return;
- }
-
- clight->shadow_buffer_size = next_power_of_2(p_size);
- clight->version++;
-
- RSG::canvas_render->light_set_use_shadow(clight->light_internal, clight->use_shadow, clight->shadow_buffer_size);
+ RSG::canvas_render->light_set_use_shadow(clight->light_internal, clight->use_shadow);
}
void RenderingServerCanvas::canvas_light_set_shadow_filter(RID p_light, RS::CanvasLightShadowFilter p_filter) {
@@ -1271,6 +1237,41 @@ void RenderingServerCanvas::canvas_occluder_polygon_set_cull_mode(RID p_occluder
}
}
+void RenderingServerCanvas::canvas_set_shadow_texture_size(int p_size) {
+ RSG::canvas_render->set_shadow_texture_size(p_size);
+}
+
+RID RenderingServerCanvas::canvas_texture_create() {
+ return RSG::storage->canvas_texture_create();
+}
+
+void RenderingServerCanvas::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
+ RSG::storage->canvas_texture_set_channel(p_canvas_texture, p_channel, p_texture);
+}
+
+void RenderingServerCanvas::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) {
+ RSG::storage->canvas_texture_set_shading_parameters(p_canvas_texture, p_base_color, p_shininess);
+}
+
+void RenderingServerCanvas::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) {
+ RSG::storage->canvas_texture_set_texture_filter(p_canvas_texture, p_filter);
+}
+
+void RenderingServerCanvas::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {
+ RSG::storage->canvas_texture_set_texture_repeat(p_canvas_texture, p_repeat);
+}
+
+void RenderingServerCanvas::canvas_item_set_default_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) {
+ Item *ci = canvas_item_owner.getornull(p_item);
+ ERR_FAIL_COND(!ci);
+ ci->texture_filter = p_filter;
+}
+void RenderingServerCanvas::canvas_item_set_default_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) {
+ Item *ci = canvas_item_owner.getornull(p_item);
+ ERR_FAIL_COND(!ci);
+ ci->texture_repeat = p_repeat;
+}
+
bool RenderingServerCanvas::free(RID p_rid) {
if (canvas_owner.owns(p_rid)) {
Canvas *canvas = canvas_owner.getornull(p_rid);
diff --git a/servers/rendering/rendering_server_canvas.h b/servers/rendering/rendering_server_canvas.h
index cebe32fba0..16edfd54e1 100644
--- a/servers/rendering/rendering_server_canvas.h
+++ b/servers/rendering/rendering_server_canvas.h
@@ -52,8 +52,6 @@ public:
Transform2D ysort_xform;
Vector2 ysort_pos;
int ysort_index;
- RS::CanvasItemTextureFilter texture_filter;
- RS::CanvasItemTextureRepeat texture_repeat;
Vector<Item *> child_items;
@@ -71,8 +69,6 @@ public:
ysort_xform = Transform2D();
ysort_pos = Vector2();
ysort_index = 0;
- texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT;
- texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT;
}
};
@@ -158,7 +154,7 @@ public:
bool disable_scale;
private:
- void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights);
+ void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat);
void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RasterizerCanvas::Item **z_list, RasterizerCanvas::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner);
void _light_mask_canvas_items(int p_z, RasterizerCanvas::Item *p_canvas_item, RasterizerCanvas::Light *p_masked_lights);
@@ -166,7 +162,7 @@ private:
RasterizerCanvas::Item **z_last_list;
public:
- void render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_masked_lights, const Rect2 &p_clip_rect);
+ void render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_masked_lights, const Rect2 &p_clip_rect, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat);
RID canvas_create();
void canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring);
@@ -191,23 +187,20 @@ public:
void canvas_item_set_update_when_visible(RID p_item, bool p_update);
- void canvas_item_set_default_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter);
- void canvas_item_set_default_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat);
-
void canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0);
void canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0);
void canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0);
void canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color);
void canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color);
- void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID(), RID p_specular_map = RID(), const Color &p_specular_color_shininess = Color(), RS::CanvasItemTextureFilter p_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT);
- void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID(), RID p_specular_map = RID(), const Color &p_specular_color_shininess = Color(), bool p_clip_uv = false, RS::CanvasItemTextureFilter p_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT);
- void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, RS::NinePatchAxisMode p_x_axis_mode = RS::NINE_PATCH_STRETCH, RS::NinePatchAxisMode p_y_axis_mode = RS::NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1), RID p_normal_map = RID(), RID p_specular_map = RID(), const Color &p_specular_color_shininess = Color(), RS::CanvasItemTextureFilter p_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT);
- void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID(), RID p_specular_map = RID(), const Color &p_specular_color_shininess = Color(), RS::CanvasItemTextureFilter p_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT);
- void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID(), RID p_specular_map = RID(), const Color &p_specular_color_shininess = Color(), RS::CanvasItemTextureFilter p_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT);
- void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID(), RID p_specular_map = RID(), const Color &p_specular_color_shininess = Color(), RS::CanvasItemTextureFilter p_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT);
- void canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1), RID p_texture = RID(), RID p_normal_map = RID(), RID p_specular_map = RID(), const Color &p_specular_color_shininess = Color(), RS::CanvasItemTextureFilter p_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT);
- void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID(), RID p_specular_map = RID(), const Color &p_specular_color_shininess = Color(), RS::CanvasItemTextureFilter p_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT);
- void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal_map, RID p_specular_map = RID(), const Color &p_specular_color_shininess = Color(), RS::CanvasItemTextureFilter p_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, RS::CanvasItemTextureRepeat p_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT);
+ void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false);
+ void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, bool p_clip_uv = false);
+ void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, RS::NinePatchAxisMode p_x_axis_mode = RS::NINE_PATCH_STRETCH, RS::NinePatchAxisMode p_y_axis_mode = RS::NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1));
+ void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0);
+ void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID());
+ void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>(), RID p_texture = RID(), int p_count = -1);
+ void canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1), RID p_texture = RID());
+ void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID());
+ void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture);
void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform);
void canvas_item_add_clip_ignore(RID p_item, bool p_ignore);
void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable);
@@ -241,7 +234,6 @@ public:
void canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode);
void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled);
- void canvas_light_set_shadow_buffer_size(RID p_light, int p_size);
void canvas_light_set_shadow_filter(RID p_light, RS::CanvasLightShadowFilter p_filter);
void canvas_light_set_shadow_color(RID p_light, const Color &p_color);
void canvas_light_set_shadow_smooth(RID p_light, float p_smooth);
@@ -259,6 +251,18 @@ public:
void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, RS::CanvasOccluderPolygonCullMode p_mode);
+ void canvas_set_shadow_texture_size(int p_size);
+
+ RID canvas_texture_create();
+ void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture);
+ void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess);
+
+ void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter);
+ void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat);
+
+ void canvas_item_set_default_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter);
+ void canvas_item_set_default_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat);
+
bool free(RID p_rid);
RenderingServerCanvas();
~RenderingServerCanvas();
diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_raster.h
index 97477f1d3e..5744b40321 100644
--- a/servers/rendering/rendering_server_raster.h
+++ b/servers/rendering/rendering_server_raster.h
@@ -529,6 +529,9 @@ public:
BIND3(viewport_set_canvas_transform, RID, RID, const Transform2D &)
BIND2(viewport_set_transparent_background, RID, bool)
+ BIND2(viewport_set_default_canvas_item_texture_filter, RID, CanvasItemTextureFilter)
+ BIND2(viewport_set_default_canvas_item_texture_repeat, RID, CanvasItemTextureRepeat)
+
BIND2(viewport_set_global_canvas_transform, RID, const Transform2D &)
BIND4(viewport_set_canvas_stacking, RID, RID, int, int)
BIND2(viewport_set_shadow_atlas_size, RID, int)
@@ -684,9 +687,19 @@ public:
BIND3(canvas_set_parent, RID, RID, float)
BIND1(canvas_set_disable_scale, bool)
+ BIND0R(RID, canvas_texture_create)
+ BIND3(canvas_texture_set_channel, RID, CanvasTextureChannel, RID)
+ BIND3(canvas_texture_set_shading_parameters, RID, const Color &, float)
+
+ BIND2(canvas_texture_set_texture_filter, RID, CanvasItemTextureFilter)
+ BIND2(canvas_texture_set_texture_repeat, RID, CanvasItemTextureRepeat)
+
BIND0R(RID, canvas_item_create)
BIND2(canvas_item_set_parent, RID, RID)
+ BIND2(canvas_item_set_default_texture_filter, RID, CanvasItemTextureFilter)
+ BIND2(canvas_item_set_default_texture_repeat, RID, CanvasItemTextureRepeat)
+
BIND2(canvas_item_set_visible, RID, bool)
BIND2(canvas_item_set_light_mask, RID, int)
@@ -701,23 +714,20 @@ public:
BIND2(canvas_item_set_draw_behind_parent, RID, bool)
- BIND2(canvas_item_set_default_texture_filter, RID, CanvasItemTextureFilter)
- BIND2(canvas_item_set_default_texture_repeat, RID, CanvasItemTextureRepeat)
-
BIND5(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float)
BIND4(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float)
BIND4(canvas_item_add_multiline, RID, const Vector<Point2> &, const Vector<Color> &, float)
BIND3(canvas_item_add_rect, RID, const Rect2 &, const Color &)
BIND4(canvas_item_add_circle, RID, const Point2 &, float, const Color &)
- BIND11(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool, RID, RID, const Color &, CanvasItemTextureFilter, CanvasItemTextureRepeat)
- BIND12(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, RID, RID, const Color &, bool, CanvasItemTextureFilter, CanvasItemTextureRepeat)
- BIND15(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &, RID, RID, const Color &, CanvasItemTextureFilter, CanvasItemTextureRepeat)
- BIND11(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float, RID, RID, const Color &, CanvasItemTextureFilter, CanvasItemTextureRepeat)
- BIND10(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, RID, RID, const Color &, CanvasItemTextureFilter, CanvasItemTextureRepeat)
- BIND14(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int, RID, RID, const Color &, CanvasItemTextureFilter, CanvasItemTextureRepeat)
- BIND10(canvas_item_add_mesh, RID, const RID &, const Transform2D &, const Color &, RID, RID, RID, const Color &, CanvasItemTextureFilter, CanvasItemTextureRepeat)
- BIND8(canvas_item_add_multimesh, RID, RID, RID, RID, RID, const Color &, CanvasItemTextureFilter, CanvasItemTextureRepeat)
- BIND8(canvas_item_add_particles, RID, RID, RID, RID, RID, const Color &, CanvasItemTextureFilter, CanvasItemTextureRepeat)
+ BIND6(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool)
+ BIND7(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, bool)
+ BIND10(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &)
+ BIND6(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float)
+ BIND5(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID)
+ BIND9(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int)
+ BIND5(canvas_item_add_mesh, RID, const RID &, const Transform2D &, const Color &, RID)
+ BIND3(canvas_item_add_multimesh, RID, RID, RID)
+ BIND3(canvas_item_add_particles, RID, RID, RID)
BIND2(canvas_item_add_set_transform, RID, const Transform2D &)
BIND2(canvas_item_add_clip_ignore, RID, bool)
BIND2(canvas_item_set_sort_children_by_y, RID, bool)
@@ -751,7 +761,6 @@ public:
BIND2(canvas_light_set_mode, RID, CanvasLightMode)
BIND2(canvas_light_set_shadow_enabled, RID, bool)
- BIND2(canvas_light_set_shadow_buffer_size, RID, int)
BIND2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter)
BIND2(canvas_light_set_shadow_color, RID, const Color &)
BIND2(canvas_light_set_shadow_smooth, RID, float)
@@ -769,6 +778,8 @@ public:
BIND2(canvas_occluder_polygon_set_cull_mode, RID, CanvasOccluderPolygonCullMode)
+ BIND1(canvas_set_shadow_texture_size, int)
+
/* GLOBAL VARIABLES */
#undef BINDBASE
diff --git a/servers/rendering/rendering_server_viewport.cpp b/servers/rendering/rendering_server_viewport.cpp
index bd9aa32147..a8dbe1e254 100644
--- a/servers/rendering/rendering_server_viewport.cpp
+++ b/servers/rendering/rendering_server_viewport.cpp
@@ -136,6 +136,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
Rect2 shadow_rect;
int light_count = 0;
+ int shadow_count = 0;
RENDER_TIMESTAMP("Cull Canvas Lights");
for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) {
@@ -221,7 +222,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
while (light) {
RENDER_TIMESTAMP("Render Shadow");
- RSG::canvas_render->light_update_shadow(light->light_internal, light->xform_cache.affine_inverse(), light->item_shadow_mask, light->radius_cache / 1000.0, light->radius_cache * 1.1, occluders);
+ RSG::canvas_render->light_update_shadow(light->light_internal, shadow_count++, light->xform_cache.affine_inverse(), light->item_shadow_mask, light->radius_cache / 1000.0, light->radius_cache * 1.1, occluders);
light = light->shadows_next_ptr;
}
@@ -254,7 +255,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
ptr = ptr->filter_next_ptr;
}
- RSG::canvas->render_canvas(p_viewport->render_target, canvas, xform, canvas_lights, lights_with_mask, clip_rect);
+ RSG::canvas->render_canvas(p_viewport->render_target, canvas, xform, canvas_lights, lights_with_mask, clip_rect, p_viewport->texture_filter, p_viewport->texture_repeat);
i++;
if (scenario_draw_canvas_bg && E->key().get_layer() >= scenario_canvas_max_layer) {
@@ -773,6 +774,21 @@ float RenderingServerViewport::viewport_get_measured_render_time_gpu(RID p_viewp
return double((viewport->time_gpu_end - viewport->time_gpu_begin) / 1000) / 1000.0;
}
+void RenderingServerViewport::viewport_set_default_canvas_item_texture_filter(RID p_viewport, RS::CanvasItemTextureFilter p_filter) {
+ ERR_FAIL_COND_MSG(p_filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, "Viewport does not accept DEFAULT as texture filter (it's the topmost choice already).)");
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ viewport->texture_filter = p_filter;
+}
+void RenderingServerViewport::viewport_set_default_canvas_item_texture_repeat(RID p_viewport, RS::CanvasItemTextureRepeat p_repeat) {
+ ERR_FAIL_COND_MSG(p_repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, "Viewport does not accept DEFAULT as texture repeat (it's the topmost choice already).)");
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ viewport->texture_repeat = p_repeat;
+}
+
bool RenderingServerViewport::free(RID p_rid) {
if (viewport_owner.owns(p_rid)) {
Viewport *viewport = viewport_owner.getornull(p_rid);
diff --git a/servers/rendering/rendering_server_viewport.h b/servers/rendering/rendering_server_viewport.h
index ed251f5da0..161ae94fb0 100644
--- a/servers/rendering/rendering_server_viewport.h
+++ b/servers/rendering/rendering_server_viewport.h
@@ -86,6 +86,9 @@ public:
RS::ViewportClearMode clear_mode;
+ RS::CanvasItemTextureFilter texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR;
+ RS::CanvasItemTextureRepeat texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED;
+
bool transparent_bg;
struct CanvasKey {
@@ -217,6 +220,9 @@ public:
float viewport_get_measured_render_time_cpu(RID p_viewport) const;
float viewport_get_measured_render_time_gpu(RID p_viewport) const;
+ void viewport_set_default_canvas_item_texture_filter(RID p_viewport, RS::CanvasItemTextureFilter p_filter);
+ void viewport_set_default_canvas_item_texture_repeat(RID p_viewport, RS::CanvasItemTextureRepeat p_repeat);
+
void handle_timestamp(String p_timestamp, uint64_t p_cpu_time, uint64_t p_gpu_time);
void set_default_clear_color(const Color &p_color);
diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h
index c2337f8c9e..1836f99c99 100644
--- a/servers/rendering/rendering_server_wrap_mt.h
+++ b/servers/rendering/rendering_server_wrap_mt.h
@@ -432,6 +432,9 @@ public:
FUNC3(viewport_set_canvas_transform, RID, RID, const Transform2D &)
FUNC2(viewport_set_transparent_background, RID, bool)
+ FUNC2(viewport_set_default_canvas_item_texture_filter, RID, CanvasItemTextureFilter)
+ FUNC2(viewport_set_default_canvas_item_texture_repeat, RID, CanvasItemTextureRepeat)
+
FUNC2(viewport_set_global_canvas_transform, RID, const Transform2D &)
FUNC4(viewport_set_canvas_stacking, RID, RID, int, int)
FUNC2(viewport_set_shadow_atlas_size, RID, int)
@@ -583,9 +586,19 @@ public:
FUNC3(canvas_set_parent, RID, RID, float)
FUNC1(canvas_set_disable_scale, bool)
+ FUNCRID(canvas_texture)
+ FUNC3(canvas_texture_set_channel, RID, CanvasTextureChannel, RID)
+ FUNC3(canvas_texture_set_shading_parameters, RID, const Color &, float)
+
+ FUNC2(canvas_texture_set_texture_filter, RID, CanvasItemTextureFilter)
+ FUNC2(canvas_texture_set_texture_repeat, RID, CanvasItemTextureRepeat)
+
FUNCRID(canvas_item)
FUNC2(canvas_item_set_parent, RID, RID)
+ FUNC2(canvas_item_set_default_texture_filter, RID, CanvasItemTextureFilter)
+ FUNC2(canvas_item_set_default_texture_repeat, RID, CanvasItemTextureRepeat)
+
FUNC2(canvas_item_set_visible, RID, bool)
FUNC2(canvas_item_set_light_mask, RID, int)
@@ -600,23 +613,20 @@ public:
FUNC2(canvas_item_set_draw_behind_parent, RID, bool)
- FUNC2(canvas_item_set_default_texture_filter, RID, CanvasItemTextureFilter)
- FUNC2(canvas_item_set_default_texture_repeat, RID, CanvasItemTextureRepeat)
-
FUNC5(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float)
FUNC4(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float)
FUNC4(canvas_item_add_multiline, RID, const Vector<Point2> &, const Vector<Color> &, float)
FUNC3(canvas_item_add_rect, RID, const Rect2 &, const Color &)
FUNC4(canvas_item_add_circle, RID, const Point2 &, float, const Color &)
- FUNC11(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool, RID, RID, const Color &, CanvasItemTextureFilter, CanvasItemTextureRepeat)
- FUNC12(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, RID, RID, const Color &, bool, CanvasItemTextureFilter, CanvasItemTextureRepeat)
- FUNC15(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &, RID, RID, const Color &, CanvasItemTextureFilter, CanvasItemTextureRepeat)
- FUNC11(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float, RID, RID, const Color &, CanvasItemTextureFilter, CanvasItemTextureRepeat)
- FUNC10(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, RID, RID, const Color &, CanvasItemTextureFilter, CanvasItemTextureRepeat)
- FUNC14(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int, RID, RID, const Color &, CanvasItemTextureFilter, CanvasItemTextureRepeat)
- FUNC10(canvas_item_add_mesh, RID, const RID &, const Transform2D &, const Color &, RID, RID, RID, const Color &, CanvasItemTextureFilter, CanvasItemTextureRepeat)
- FUNC8(canvas_item_add_multimesh, RID, RID, RID, RID, RID, const Color &, CanvasItemTextureFilter, CanvasItemTextureRepeat)
- FUNC8(canvas_item_add_particles, RID, RID, RID, RID, RID, const Color &, CanvasItemTextureFilter, CanvasItemTextureRepeat)
+ FUNC6(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool)
+ FUNC7(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, bool)
+ FUNC10(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &)
+ FUNC6(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float)
+ FUNC5(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID)
+ FUNC9(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int)
+ FUNC5(canvas_item_add_mesh, RID, const RID &, const Transform2D &, const Color &, RID)
+ FUNC3(canvas_item_add_multimesh, RID, RID, RID)
+ FUNC3(canvas_item_add_particles, RID, RID, RID)
FUNC2(canvas_item_add_set_transform, RID, const Transform2D &)
FUNC2(canvas_item_add_clip_ignore, RID, bool)
FUNC2(canvas_item_set_sort_children_by_y, RID, bool)
@@ -650,7 +660,6 @@ public:
FUNC2(canvas_light_set_mode, RID, CanvasLightMode)
FUNC2(canvas_light_set_shadow_enabled, RID, bool)
- FUNC2(canvas_light_set_shadow_buffer_size, RID, int)
FUNC2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter)
FUNC2(canvas_light_set_shadow_color, RID, const Color &)
FUNC2(canvas_light_set_shadow_smooth, RID, float)
@@ -668,6 +677,8 @@ public:
FUNC2(canvas_occluder_polygon_set_cull_mode, RID, CanvasOccluderPolygonCullMode)
+ FUNC1(canvas_set_shadow_texture_size, int)
+
/* GLOBAL VARIABLES */
FUNC3(global_variable_add, const StringName &, GlobalVariableType, const Variant &)
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index e2f1ddb224..42a77101f7 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -1846,7 +1846,6 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("canvas_light_set_item_shadow_cull_mask", "light", "mask"), &RenderingServer::canvas_light_set_item_shadow_cull_mask);
ClassDB::bind_method(D_METHOD("canvas_light_set_mode", "light", "mode"), &RenderingServer::canvas_light_set_mode);
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_enabled", "light", "enabled"), &RenderingServer::canvas_light_set_shadow_enabled);
- ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_buffer_size", "light", "size"), &RenderingServer::canvas_light_set_shadow_buffer_size);
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_filter", "light", "filter"), &RenderingServer::canvas_light_set_shadow_filter);
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_color", "light", "color"), &RenderingServer::canvas_light_set_shadow_color);
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_smooth", "light", "smooth"), &RenderingServer::canvas_light_set_shadow_smooth);
@@ -2335,6 +2334,8 @@ RenderingServer::RenderingServer() {
GLOBAL_DEF("rendering/quality/shadows/soft_shadow_quality.mobile", 0);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadows/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/quality/shadows/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)"));
+ GLOBAL_DEF("rendering/quality/2d_shadow_atlas/size", 2048);
+
GLOBAL_DEF("rendering/quality/shadow_atlas/size", 4096);
GLOBAL_DEF("rendering/quality/shadow_atlas/size.mobile", 2048);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/size", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/size", PROPERTY_HINT_RANGE, "256,16384"));
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index e50170bdf7..61d0fed52f 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -661,6 +661,25 @@ public:
/* VIEWPORT TARGET API */
+ enum CanvasItemTextureFilter {
+ CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, //uses canvas item setting for draw command, uses global setting for canvas item
+ CANVAS_ITEM_TEXTURE_FILTER_NEAREST,
+ CANVAS_ITEM_TEXTURE_FILTER_LINEAR,
+ CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS,
+ CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS,
+ CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC,
+ CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC,
+ CANVAS_ITEM_TEXTURE_FILTER_MAX
+ };
+
+ enum CanvasItemTextureRepeat {
+ CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, //uses canvas item setting for draw command, uses global setting for canvas item
+ CANVAS_ITEM_TEXTURE_REPEAT_DISABLED,
+ CANVAS_ITEM_TEXTURE_REPEAT_ENABLED,
+ CANVAS_ITEM_TEXTURE_REPEAT_MIRROR,
+ CANVAS_ITEM_TEXTURE_REPEAT_MAX,
+ };
+
virtual RID viewport_create() = 0;
virtual void viewport_set_use_xr(RID p_viewport, bool p_use_xr) = 0;
@@ -702,6 +721,9 @@ public:
virtual void viewport_set_canvas_transform(RID p_viewport, RID p_canvas, const Transform2D &p_offset) = 0;
virtual void viewport_set_transparent_background(RID p_viewport, bool p_enabled) = 0;
+ virtual void viewport_set_default_canvas_item_texture_filter(RID p_viewport, CanvasItemTextureFilter p_filter) = 0;
+ virtual void viewport_set_default_canvas_item_texture_repeat(RID p_viewport, CanvasItemTextureRepeat p_repeat) = 0;
+
virtual void viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform) = 0;
virtual void viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer) = 0;
@@ -1092,9 +1114,26 @@ public:
virtual void canvas_set_disable_scale(bool p_disable) = 0;
+ virtual RID canvas_texture_create() = 0;
+
+ enum CanvasTextureChannel {
+ CANVAS_TEXTURE_CHANNEL_DIFFUSE,
+ CANVAS_TEXTURE_CHANNEL_NORMAL,
+ CANVAS_TEXTURE_CHANNEL_SPECULAR,
+ };
+ virtual void canvas_texture_set_channel(RID p_canvas_texture, CanvasTextureChannel p_channel, RID p_texture) = 0;
+ virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) = 0;
+
+ //takes effect only for new draw commands
+ virtual void canvas_texture_set_texture_filter(RID p_canvas_texture, CanvasItemTextureFilter p_filter) = 0;
+ virtual void canvas_texture_set_texture_repeat(RID p_canvas_texture, CanvasItemTextureRepeat p_repeat) = 0;
+
virtual RID canvas_item_create() = 0;
virtual void canvas_item_set_parent(RID p_item, RID p_parent) = 0;
+ virtual void canvas_item_set_default_texture_filter(RID p_item, CanvasItemTextureFilter p_filter) = 0;
+ virtual void canvas_item_set_default_texture_repeat(RID p_item, CanvasItemTextureRepeat p_repeat) = 0;
+
virtual void canvas_item_set_visible(RID p_item, bool p_visible) = 0;
virtual void canvas_item_set_light_mask(RID p_item, int p_mask) = 0;
@@ -1115,43 +1154,20 @@ public:
NINE_PATCH_TILE_FIT,
};
- enum CanvasItemTextureFilter {
- CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, //uses canvas item setting for draw command, uses global setting for canvas item
- CANVAS_ITEM_TEXTURE_FILTER_NEAREST,
- CANVAS_ITEM_TEXTURE_FILTER_LINEAR,
- CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS,
- CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS,
- CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC,
- CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC,
- CANVAS_ITEM_TEXTURE_FILTER_MAX
- };
-
- enum CanvasItemTextureRepeat {
- CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, //uses canvas item setting for draw command, uses global setting for canvas item
- CANVAS_ITEM_TEXTURE_REPEAT_DISABLED,
- CANVAS_ITEM_TEXTURE_REPEAT_ENABLED,
- CANVAS_ITEM_TEXTURE_REPEAT_MIRROR,
- CANVAS_ITEM_TEXTURE_REPEAT_MAX,
- };
-
- //takes effect only for new draw commands
- virtual void canvas_item_set_default_texture_filter(RID p_item, CanvasItemTextureFilter p_filter) = 0;
- virtual void canvas_item_set_default_texture_repeat(RID p_item, CanvasItemTextureRepeat p_repeat) = 0;
-
virtual void canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0) = 0;
virtual void canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0) = 0;
virtual void canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0) = 0;
virtual void canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) = 0;
virtual void canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color) = 0;
- virtual void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID(), RID p_specular_map = RID(), const Color &p_specular_color_shininess = Color(), CanvasItemTextureFilter p_texture_filter = CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, CanvasItemTextureRepeat = CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) = 0;
- virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID(), RID p_specular_map = RID(), const Color &p_specular_color_shininess = Color(), bool p_clip_uv = false, CanvasItemTextureFilter p_texture_filter = CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, CanvasItemTextureRepeat = CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) = 0;
- virtual void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, NinePatchAxisMode p_x_axis_mode = NINE_PATCH_STRETCH, NinePatchAxisMode p_y_axis_mode = NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1), RID p_normal_map = RID(), RID p_specular_map = RID(), const Color &p_specular_color_shininess = Color(), CanvasItemTextureFilter p_texture_filter = CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, CanvasItemTextureRepeat = CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) = 0;
- virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID(), RID p_specular_map = RID(), const Color &p_specular_color_shininess = Color(), CanvasItemTextureFilter p_texture_filter = CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, CanvasItemTextureRepeat = CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) = 0;
- virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID(), RID p_specular_map = RID(), const Color &p_specular_color_shininess = Color(), CanvasItemTextureFilter p_texture_filter = CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, CanvasItemTextureRepeat = CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) = 0;
- virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID(), RID p_specular_map = RID(), const Color &p_specular_color_shininess = Color(), CanvasItemTextureFilter p_texture_filter = CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, CanvasItemTextureRepeat = CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) = 0;
- virtual void canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1), RID p_texture = RID(), RID p_normal_map = RID(), RID p_specular_map = RID(), const Color &p_specular_color_shininess = Color(), CanvasItemTextureFilter p_texture_filter = CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, CanvasItemTextureRepeat = CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) = 0;
- virtual void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID(), RID p_specular_map = RID(), const Color &p_specular_color_shininess = Color(), CanvasItemTextureFilter p_texture_filter = CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, CanvasItemTextureRepeat = CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) = 0;
- virtual void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal_map, RID p_specular_map = RID(), const Color &p_specular_color_shininess = Color(), CanvasItemTextureFilter p_texture_filter = CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, CanvasItemTextureRepeat = CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) = 0;
+ virtual void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) = 0;
+ virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, bool p_clip_uv = false) = 0;
+ virtual void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, NinePatchAxisMode p_x_axis_mode = NINE_PATCH_STRETCH, NinePatchAxisMode p_y_axis_mode = NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1)) = 0;
+ virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0) = 0;
+ virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID()) = 0;
+ virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>(), RID p_texture = RID(), int p_count = -1) = 0;
+ virtual void canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1), RID p_texture = RID()) = 0;
+ virtual void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID()) = 0;
+ virtual void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture) = 0;
virtual void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform) = 0;
virtual void canvas_item_add_clip_ignore(RID p_item, bool p_ignore) = 0;
virtual void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) = 0;
@@ -1200,7 +1216,6 @@ public:
};
virtual void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled) = 0;
- virtual void canvas_light_set_shadow_buffer_size(RID p_light, int p_size) = 0;
virtual void canvas_light_set_shadow_filter(RID p_light, CanvasLightShadowFilter p_filter) = 0;
virtual void canvas_light_set_shadow_color(RID p_light, const Color &p_color) = 0;
virtual void canvas_light_set_shadow_smooth(RID p_light, float p_smooth) = 0;
@@ -1224,6 +1239,8 @@ public:
virtual void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, CanvasOccluderPolygonCullMode p_mode) = 0;
+ virtual void canvas_set_shadow_texture_size(int p_size) = 0;
+
/* GLOBAL VARIABLES */
enum GlobalVariableType {