summaryrefslogtreecommitdiff
path: root/servers/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering')
-rw-r--r--servers/rendering/renderer_canvas_cull.cpp34
-rw-r--r--servers/rendering/renderer_canvas_cull.h1
-rw-r--r--servers/rendering/renderer_canvas_render.h5
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp12
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp8
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.h8
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp10
-rw-r--r--servers/rendering/renderer_rd/shaders/canvas.glsl37
-rw-r--r--servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/giprobe_write.glsl47
-rw-r--r--servers/rendering/renderer_rd/shaders/voxel_gi.glsl162
-rw-r--r--servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl5
-rw-r--r--servers/rendering/renderer_viewport.cpp84
-rw-r--r--servers/rendering/renderer_viewport.h6
-rw-r--r--servers/rendering/rendering_device.h1
-rw-r--r--servers/rendering/rendering_server_default.h2
16 files changed, 172 insertions, 252 deletions
diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp
index fd7d5b91fa..efa3a457d3 100644
--- a/servers/rendering/renderer_canvas_cull.cpp
+++ b/servers/rendering/renderer_canvas_cull.cpp
@@ -806,6 +806,40 @@ void RendererCanvasCull::canvas_item_add_texture_rect(RID p_item, const Rect2 &p
rect->texture = p_texture;
}
+void RendererCanvasCull::canvas_item_add_msdf_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate, int p_outline_size, float p_px_range) {
+ Item *canvas_item = canvas_item_owner.getornull(p_item);
+ ERR_FAIL_COND(!canvas_item);
+
+ Item::CommandRect *rect = canvas_item->alloc_command<Item::CommandRect>();
+ ERR_FAIL_COND(!rect);
+ rect->modulate = p_modulate;
+ rect->rect = p_rect;
+
+ rect->texture = p_texture;
+
+ rect->source = p_src_rect;
+ rect->flags = RendererCanvasRender::CANVAS_RECT_REGION | RendererCanvasRender::CANVAS_RECT_MSDF;
+
+ if (p_rect.size.x < 0) {
+ rect->flags |= RendererCanvasRender::CANVAS_RECT_FLIP_H;
+ rect->rect.size.x = -rect->rect.size.x;
+ }
+ if (p_src_rect.size.x < 0) {
+ rect->flags ^= RendererCanvasRender::CANVAS_RECT_FLIP_H;
+ rect->source.size.x = -rect->source.size.x;
+ }
+ if (p_rect.size.y < 0) {
+ rect->flags |= RendererCanvasRender::CANVAS_RECT_FLIP_V;
+ rect->rect.size.y = -rect->rect.size.y;
+ }
+ if (p_src_rect.size.y < 0) {
+ rect->flags ^= RendererCanvasRender::CANVAS_RECT_FLIP_V;
+ rect->source.size.y = -rect->source.size.y;
+ }
+ rect->outline = p_outline_size;
+ rect->px_range = p_px_range;
+}
+
void RendererCanvasCull::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);
diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h
index 79b5450d14..5e343dcf02 100644
--- a/servers/rendering/renderer_canvas_cull.h
+++ b/servers/rendering/renderer_canvas_cull.h
@@ -222,6 +222,7 @@ public:
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);
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_msdf_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), int p_outline_size = 0, float p_px_range = 1.0);
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());
diff --git a/servers/rendering/renderer_canvas_render.h b/servers/rendering/renderer_canvas_render.h
index 8afe9ef410..04ddae4089 100644
--- a/servers/rendering/renderer_canvas_render.h
+++ b/servers/rendering/renderer_canvas_render.h
@@ -45,6 +45,7 @@ public:
CANVAS_RECT_TRANSPOSE = 16,
CANVAS_RECT_CLIP_UV = 32,
CANVAS_RECT_IS_GROUP = 64,
+ CANVAS_RECT_MSDF = 128,
};
struct Light {
@@ -193,11 +194,15 @@ public:
Color modulate;
Rect2 source;
uint8_t flags;
+ float outline;
+ float px_range;
RID texture;
CommandRect() {
flags = 0;
+ outline = 0;
+ px_range = 1;
type = TYPE_RECT;
}
};
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
index 926d599c84..1b4052b622 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -86,12 +86,13 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::clear() {
void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, uint32_t p_view_count) {
clear();
- bool is_half_resolution = false; // Set this once we support this feature.
-
msaa = p_msaa;
+ Size2i target_size = RD::get_singleton()->texture_size(p_target_buffer);
+
width = p_width;
height = p_height;
+ bool is_scaled = (target_size.width != p_width) || (target_size.height != p_height);
view_count = p_view_count;
color = p_color_buffer;
@@ -124,7 +125,7 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_b
passes.push_back(pass);
color_fbs[FB_CONFIG_THREE_SUBPASSES] = RD::get_singleton()->framebuffer_create_multipass(fb, passes, RenderingDevice::INVALID_ID, view_count);
- if (!is_half_resolution) {
+ if (!is_scaled) {
// - add blit to 2D pass
fb.push_back(p_target_buffer); // 2 - target buffer
@@ -211,7 +212,7 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_b
color_fbs[FB_CONFIG_ONE_PASS] = RD::get_singleton()->framebuffer_create_multipass(fb, one_pass_with_resolve, RenderingDevice::INVALID_ID, view_count);
}
- if (!is_half_resolution) {
+ if (!is_scaled) {
// - add blit to 2D pass
fb.push_back(p_target_buffer); // 3 - target buffer
RD::FramebufferPass blit_pass;
@@ -497,7 +498,6 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
bool using_subpass_transparent = true;
bool using_subpass_post_process = true;
- bool is_half_resolution = false; // Set this once we support this feature.
bool using_ssr = false; // I don't think we support this in our mobile renderer so probably should phase it out
bool using_sss = false; // I don't think we support this in our mobile renderer so probably should phase it out
@@ -518,7 +518,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
screen_size.x = render_buffer->width;
screen_size.y = render_buffer->height;
- if (is_half_resolution) {
+ if (render_buffer->color_fbs[FB_CONFIG_FOUR_SUBPASSES].is_null()) {
// can't do blit subpass
using_subpass_post_process = false;
} else if (env && (env->glow_enabled || env->auto_exposure || camera_effects_uses_dof(p_render_data->camera_effects))) {
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index 3af5047854..6267f684e3 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -541,6 +541,14 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
src_rect = Rect2(0, 0, 1, 1);
}
+ if (rect->flags & CANVAS_RECT_MSDF) {
+ push_constant.flags |= FLAGS_USE_MSDF;
+ push_constant.msdf[0] = rect->px_range; // Pixel range.
+ push_constant.msdf[1] = rect->outline; // Outline size.
+ push_constant.msdf[2] = 0.f; // Reserved.
+ push_constant.msdf[3] = 0.f; // Reserved.
+ }
+
push_constant.modulation[0] = rect->modulate.r * base_color.r;
push_constant.modulation[1] = rect->modulate.g * base_color.g;
push_constant.modulation[2] = rect->modulate.b * base_color.b;
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
index 7c4f62832c..ec7d7e2854 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
@@ -84,8 +84,9 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
FLAGS_LIGHT_COUNT_SHIFT = 20,
FLAGS_DEFAULT_NORMAL_MAP_USED = (1 << 26),
- FLAGS_DEFAULT_SPECULAR_MAP_USED = (1 << 27)
+ FLAGS_DEFAULT_SPECULAR_MAP_USED = (1 << 27),
+ FLAGS_USE_MSDF = (1 << 28),
};
enum {
@@ -388,7 +389,10 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
//rect
struct {
float modulation[4];
- float ninepatch_margins[4];
+ union {
+ float msdf[4];
+ float ninepatch_margins[4];
+ };
float dst_rect[4];
float src_rect[4];
float pad[2];
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index acda68abb7..fa66ed85a9 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -2591,6 +2591,8 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
ERR_FAIL_COND_MSG(p_view_count == 0, "Must have at least 1 view");
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
+
+ // Should we add an overrule per viewport?
rb->width = p_width;
rb->height = p_height;
rb->render_target = p_render_target;
@@ -2637,8 +2639,8 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
tf.format = RD::DATA_FORMAT_R32_SFLOAT;
}
- tf.width = p_width;
- tf.height = p_height;
+ tf.width = rb->width;
+ tf.height = rb->height;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT;
tf.array_layers = rb->view_count; // create a layer for every view
@@ -2660,10 +2662,10 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
}
RID target_texture = storage->render_target_get_rd_texture(rb->render_target);
- rb->data->configure(rb->texture, rb->depth_texture, target_texture, p_width, p_height, p_msaa, p_view_count);
+ rb->data->configure(rb->texture, rb->depth_texture, target_texture, rb->width, rb->height, p_msaa, p_view_count);
if (is_clustered_enabled()) {
- rb->cluster_builder->setup(Size2i(p_width, p_height), max_cluster_elements, rb->depth_texture, storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED), rb->texture);
+ rb->cluster_builder->setup(Size2i(rb->width, rb->height), max_cluster_elements, rb->depth_texture, storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED), rb->texture);
}
}
diff --git a/servers/rendering/renderer_rd/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl
index a443bcdcb8..2911e8b731 100644
--- a/servers/rendering/renderer_rd/shaders/canvas.glsl
+++ b/servers/rendering/renderer_rd/shaders/canvas.glsl
@@ -458,6 +458,14 @@ void light_blend_compute(uint light_base, vec4 light_color, inout vec3 color) {
#endif
+float msdf_median(float r, float g, float b, float a) {
+ return min(max(min(r, g), min(max(r, g), b)), a);
+}
+
+vec2 msdf_map(vec2 value, vec2 in_min, vec2 in_max, vec2 out_min, vec2 out_max) {
+ return out_min + (out_max - out_min) * (value - in_min) / (in_max - in_min);
+}
+
void main() {
vec4 color = color_interp;
vec2 uv = uv_interp;
@@ -485,7 +493,34 @@ void main() {
#endif
- color *= texture(sampler2D(color_texture, texture_sampler), uv);
+#ifndef USE_PRIMITIVE
+ if (bool(draw_data.flags & FLAGS_USE_MSDF)) {
+ float px_range = draw_data.ninepatch_margins.x;
+ float outline_thickness = draw_data.ninepatch_margins.y;
+ //float reserved1 = draw_data.ninepatch_margins.z;
+ //float reserved2 = draw_data.ninepatch_margins.w;
+
+ vec4 msdf_sample = texture(sampler2D(color_texture, texture_sampler), uv);
+ vec2 msdf_size = vec2(textureSize(sampler2D(color_texture, texture_sampler), 0));
+ vec2 dest_size = vec2(1.0) / fwidth(uv);
+ float px_size = max(0.5 * dot((vec2(px_range) / msdf_size), dest_size), 1.0);
+ float d = msdf_median(msdf_sample.r, msdf_sample.g, msdf_sample.b, msdf_sample.a) - 0.5;
+
+ if (outline_thickness > 0) {
+ float cr = clamp(outline_thickness, 0.0, px_range / 2) / px_range;
+ float a = clamp((d + cr) * px_size, 0.0, 1.0);
+ color.a = a * color.a;
+ } else {
+ float a = clamp(d * px_size + 0.5, 0.0, 1.0);
+ color.a = a * color.a;
+ }
+
+ } else {
+#else
+ {
+#endif
+ color *= texture(sampler2D(color_texture, texture_sampler), uv);
+ }
uint light_count = (draw_data.flags >> FLAGS_LIGHT_COUNT_SHIFT) & 0xF; //max 16 lights
bool using_light = light_count > 0 || canvas_data.directional_light_count > 0;
diff --git a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl
index 451f9b0089..0cff505cae 100644
--- a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl
@@ -24,6 +24,8 @@
#define FLAGS_DEFAULT_NORMAL_MAP_USED (1 << 26)
#define FLAGS_DEFAULT_SPECULAR_MAP_USED (1 << 27)
+#define FLAGS_USE_MSDF (1 << 28)
+
#define SAMPLER_NEAREST_CLAMP 0
#define SAMPLER_LINEAR_CLAMP 1
#define SAMPLER_NEAREST_WITH_MIPMAPS_CLAMP 2
diff --git a/servers/rendering/renderer_rd/shaders/giprobe_write.glsl b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl
index 5dc2d08a3b..25d87ca45d 100644
--- a/servers/rendering/renderer_rd/shaders/giprobe_write.glsl
+++ b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl
@@ -202,12 +202,7 @@ void main() {
vec3 emission = vec3(ivec3(cell_data.data[cell_index].emission & 0x3FF, (cell_data.data[cell_index].emission >> 10) & 0x7FF, cell_data.data[cell_index].emission >> 21)) * params.emission_scale;
vec4 normal = unpackSnorm4x8(cell_data.data[cell_index].normal);
-#ifdef MODE_ANISOTROPIC
- vec3 accum[6] = vec3[](vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0));
- const vec3 accum_dirs[6] = vec3[](vec3(1.0, 0.0, 0.0), vec3(-1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(0.0, -1.0, 0.0), vec3(0.0, 0.0, 1.0), vec3(0.0, 0.0, -1.0));
-#else
vec3 accum = vec3(0.0);
-#endif
for (uint i = 0; i < params.light_count; i++) {
float attenuation;
@@ -242,77 +237,35 @@ void main() {
vec3 light = lights.data[i].color * albedo.rgb * attenuation * lights.data[i].energy;
-#ifdef MODE_ANISOTROPIC
- for (uint j = 0; j < 6; j++) {
- accum[j] += max(0.0, dot(accum_dir, -light_dir)) * light + emission;
- }
-#else
if (length(normal.xyz) > 0.2) {
accum += max(0.0, dot(normal.xyz, -light_dir)) * light + emission;
} else {
//all directions
accum += light + emission;
}
-#endif
}
-#ifdef MODE_ANISOTROPIC
-
- output.data[cell_index * 6 + 0] = vec4(accum[0], 0.0);
- output.data[cell_index * 6 + 1] = vec4(accum[1], 0.0);
- output.data[cell_index * 6 + 2] = vec4(accum[2], 0.0);
- output.data[cell_index * 6 + 3] = vec4(accum[3], 0.0);
- output.data[cell_index * 6 + 4] = vec4(accum[4], 0.0);
- output.data[cell_index * 6 + 5] = vec4(accum[5], 0.0);
-#else
output.data[cell_index] = vec4(accum, 0.0);
-#endif
-
#endif //MODE_COMPUTE_LIGHT
#ifdef MODE_UPDATE_MIPMAPS
{
-#ifdef MODE_ANISOTROPIC
- vec3 light_accum[6] = vec3[](vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0));
-#else
vec3 light_accum = vec3(0.0);
-#endif
float count = 0.0;
for (uint i = 0; i < 8; i++) {
uint child_index = cell_children.data[cell_index].children[i];
if (child_index == NO_CHILDREN) {
continue;
}
-#ifdef MODE_ANISOTROPIC
- light_accum[1] += output.data[child_index * 6 + 0].rgb;
- light_accum[2] += output.data[child_index * 6 + 1].rgb;
- light_accum[3] += output.data[child_index * 6 + 2].rgb;
- light_accum[4] += output.data[child_index * 6 + 3].rgb;
- light_accum[5] += output.data[child_index * 6 + 4].rgb;
- light_accum[6] += output.data[child_index * 6 + 5].rgb;
-
-#else
light_accum += output.data[child_index].rgb;
-#endif
-
count += 1.0;
}
float divisor = mix(8.0, count, params.propagation);
-#ifdef MODE_ANISOTROPIC
- output.data[cell_index * 6 + 0] = vec4(light_accum[0] / divisor, 0.0);
- output.data[cell_index * 6 + 1] = vec4(light_accum[1] / divisor, 0.0);
- output.data[cell_index * 6 + 2] = vec4(light_accum[2] / divisor, 0.0);
- output.data[cell_index * 6 + 3] = vec4(light_accum[3] / divisor, 0.0);
- output.data[cell_index * 6 + 4] = vec4(light_accum[4] / divisor, 0.0);
- output.data[cell_index * 6 + 5] = vec4(light_accum[5] / divisor, 0.0);
-
-#else
output.data[cell_index] = vec4(light_accum / divisor, 0.0);
-#endif
}
#endif
diff --git a/servers/rendering/renderer_rd/shaders/voxel_gi.glsl b/servers/rendering/renderer_rd/shaders/voxel_gi.glsl
index 49a493cdc7..779f04ed35 100644
--- a/servers/rendering/renderer_rd/shaders/voxel_gi.glsl
+++ b/servers/rendering/renderer_rd/shaders/voxel_gi.glsl
@@ -71,11 +71,6 @@ lights;
layout(set = 0, binding = 5) uniform texture3D color_texture;
-#ifdef MODE_ANISOTROPIC
-layout(set = 0, binding = 7) uniform texture3D aniso_pos_texture;
-layout(set = 0, binding = 8) uniform texture3D aniso_neg_texture;
-#endif // MODE ANISOTROPIC
-
#endif // MODE_SECOND_BOUNCE
#ifndef MODE_DYNAMIC
@@ -110,13 +105,6 @@ layout(set = 0, binding = 10) uniform sampler texture_sampler;
layout(rgba8, set = 0, binding = 5) uniform restrict writeonly image3D color_tex;
-#ifdef MODE_ANISOTROPIC
-
-layout(r16ui, set = 0, binding = 6) uniform restrict writeonly uimage3D aniso_pos_tex;
-layout(r16ui, set = 0, binding = 7) uniform restrict writeonly uimage3D aniso_neg_tex;
-
-#endif
-
#endif
#ifdef MODE_DYNAMIC
@@ -170,13 +158,6 @@ layout(r32f, set = 0, binding = 8) uniform restrict writeonly image2D depth;
layout(rgba8, set = 0, binding = 11) uniform restrict image3D color_texture;
-#ifdef MODE_ANISOTROPIC
-
-layout(r16ui, set = 0, binding = 12) uniform restrict writeonly uimage3D aniso_pos_texture;
-layout(r16ui, set = 0, binding = 13) uniform restrict writeonly uimage3D aniso_neg_texture;
-
-#endif // MODE ANISOTROPIC
-
#endif //MODE_DYNAMIC_SHRINK_PLOT
#endif // MODE_DYNAMIC_SHRINK
@@ -374,12 +355,7 @@ void main() {
vec3 emission = vec3(uvec3(cell_data.data[cell_index].emission & 0x1ff, (cell_data.data[cell_index].emission >> 9) & 0x1ff, (cell_data.data[cell_index].emission >> 18) & 0x1ff)) * pow(2.0, float(cell_data.data[cell_index].emission >> 27) - 15.0 - 9.0);
vec3 normal = unpackSnorm4x8(cell_data.data[cell_index].normal).xyz;
-#ifdef MODE_ANISOTROPIC
- vec3 accum[6] = vec3[](vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0));
- const vec3 accum_dirs[6] = vec3[](vec3(1.0, 0.0, 0.0), vec3(-1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(0.0, -1.0, 0.0), vec3(0.0, 0.0, 1.0), vec3(0.0, 0.0, -1.0));
-#else
vec3 accum = vec3(0.0);
-#endif
for (uint i = 0; i < params.light_count; i++) {
vec3 light;
@@ -390,38 +366,16 @@ void main() {
light *= albedo.rgb;
-#ifdef MODE_ANISOTROPIC
- for (uint j = 0; j < 6; j++) {
- accum[j] += max(0.0, dot(accum_dirs[j], -light_dir)) * light;
- }
-#else
if (length(normal) > 0.2) {
accum += max(0.0, dot(normal, -light_dir)) * light;
} else {
//all directions
accum += light;
}
-#endif
}
-#ifdef MODE_ANISOTROPIC
-
- for (uint i = 0; i < 6; i++) {
- vec3 light = accum[i];
- if (length(normal) > 0.2) {
- light += max(0.0, dot(accum_dirs[i], -normal)) * emission;
- } else {
- light += emission;
- }
-
- outputs.data[cell_index * 6 + i] = vec4(light, 0.0);
- }
-
-#else
outputs.data[cell_index] = vec4(accum + emission, 0.0);
-#endif
-
#endif //MODE_COMPUTE_LIGHT
/////////////////SECOND BOUNCE///////////////////////////////
@@ -431,32 +385,8 @@ void main() {
ivec3 ipos = ivec3(posu);
vec4 normal = unpackSnorm4x8(cell_data.data[cell_index].normal);
-#ifdef MODE_ANISOTROPIC
- vec3 accum[6];
- const vec3 accum_dirs[6] = vec3[](vec3(1.0, 0.0, 0.0), vec3(-1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(0.0, -1.0, 0.0), vec3(0.0, 0.0, 1.0), vec3(0.0, 0.0, -1.0));
-
- /*vec3 src_color = texelFetch(sampler3D(color_texture,texture_sampler),ipos,0).rgb * params.dynamic_range;
- vec3 src_aniso_pos = texelFetch(sampler3D(aniso_pos_texture,texture_sampler),ipos,0).rgb;
- vec3 src_anisp_neg = texelFetch(sampler3D(anisp_neg_texture,texture_sampler),ipos,0).rgb;
- accum[0]=src_col * src_aniso_pos.x;
- accum[1]=src_col * src_aniso_neg.x;
- accum[2]=src_col * src_aniso_pos.y;
- accum[3]=src_col * src_aniso_neg.y;
- accum[4]=src_col * src_aniso_pos.z;
- accum[5]=src_col * src_aniso_neg.z;*/
-
- accum[0] = outputs.data[cell_index * 6 + 0].rgb;
- accum[1] = outputs.data[cell_index * 6 + 1].rgb;
- accum[2] = outputs.data[cell_index * 6 + 2].rgb;
- accum[3] = outputs.data[cell_index * 6 + 3].rgb;
- accum[4] = outputs.data[cell_index * 6 + 4].rgb;
- accum[5] = outputs.data[cell_index * 6 + 5].rgb;
-
-#else
vec3 accum = outputs.data[cell_index].rgb;
-#endif
-
if (length(normal.xyz) > 0.2) {
vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);
vec3 tangent = normalize(cross(v0, normal.xyz));
@@ -484,9 +414,6 @@ void main() {
float max_distance = length(vec3(params.limits));
vec3 cell_size = 1.0 / vec3(params.limits);
-#ifdef MODE_ANISOTROPIC
- vec3 aniso_normal = mix(direction, normal.xyz, params.aniso_strength);
-#endif
while (dist < max_distance && color.a < 0.95) {
float diameter = max(1.0, 2.0 * tan_half_angle * dist);
vec3 uvw_pos = (pos + dist * direction) * cell_size;
@@ -498,42 +425,18 @@ void main() {
float log2_diameter = log2(diameter);
vec4 scolor = textureLod(sampler3D(color_texture, texture_sampler), uvw_pos, log2_diameter);
-#ifdef MODE_ANISOTROPIC
-
- vec3 aniso_neg = textureLod(sampler3D(aniso_neg_texture, texture_sampler), uvw_pos, log2_diameter).rgb;
- vec3 aniso_pos = textureLod(sampler3D(aniso_pos_texture, texture_sampler), uvw_pos, log2_diameter).rgb;
-
- scolor.rgb *= dot(max(vec3(0.0), (aniso_normal * aniso_pos)), vec3(1.0)) + dot(max(vec3(0.0), (-aniso_normal * aniso_neg)), vec3(1.0));
-#endif
float a = (1.0 - color.a);
color += a * scolor;
dist += half_diameter;
}
}
color *= cone_weights[i] * vec4(albedo.rgb, 1.0) * params.dynamic_range; //restore range
-#ifdef MODE_ANISOTROPIC
- for (uint j = 0; j < 6; j++) {
- accum[j] += max(0.0, dot(accum_dirs[j], direction)) * color.rgb;
- }
-#else
accum += color.rgb;
-#endif
}
}
-#ifdef MODE_ANISOTROPIC
-
- outputs.data[cell_index * 6 + 0] = vec4(accum[0], 0.0);
- outputs.data[cell_index * 6 + 1] = vec4(accum[1], 0.0);
- outputs.data[cell_index * 6 + 2] = vec4(accum[2], 0.0);
- outputs.data[cell_index * 6 + 3] = vec4(accum[3], 0.0);
- outputs.data[cell_index * 6 + 4] = vec4(accum[4], 0.0);
- outputs.data[cell_index * 6 + 5] = vec4(accum[5], 0.0);
-#else
outputs.data[cell_index] = vec4(accum, 0.0);
-#endif
-
#endif // MODE_SECOND_BOUNCE
/////////////////UPDATE MIPMAPS///////////////////////////////
@@ -541,45 +444,20 @@ void main() {
#ifdef MODE_UPDATE_MIPMAPS
{
-#ifdef MODE_ANISOTROPIC
- vec3 light_accum[6] = vec3[](vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0));
-#else
vec3 light_accum = vec3(0.0);
-#endif
float count = 0.0;
for (uint i = 0; i < 8; i++) {
uint child_index = cell_children.data[cell_index].children[i];
if (child_index == NO_CHILDREN) {
continue;
}
-#ifdef MODE_ANISOTROPIC
- light_accum[0] += outputs.data[child_index * 6 + 0].rgb;
- light_accum[1] += outputs.data[child_index * 6 + 1].rgb;
- light_accum[2] += outputs.data[child_index * 6 + 2].rgb;
- light_accum[3] += outputs.data[child_index * 6 + 3].rgb;
- light_accum[4] += outputs.data[child_index * 6 + 4].rgb;
- light_accum[5] += outputs.data[child_index * 6 + 5].rgb;
-
-#else
light_accum += outputs.data[child_index].rgb;
-#endif
-
count += 1.0;
}
float divisor = mix(8.0, count, params.propagation);
-#ifdef MODE_ANISOTROPIC
- outputs.data[cell_index * 6 + 0] = vec4(light_accum[0] / divisor, 0.0);
- outputs.data[cell_index * 6 + 1] = vec4(light_accum[1] / divisor, 0.0);
- outputs.data[cell_index * 6 + 2] = vec4(light_accum[2] / divisor, 0.0);
- outputs.data[cell_index * 6 + 3] = vec4(light_accum[3] / divisor, 0.0);
- outputs.data[cell_index * 6 + 4] = vec4(light_accum[4] / divisor, 0.0);
- outputs.data[cell_index * 6 + 5] = vec4(light_accum[5] / divisor, 0.0);
-
-#else
outputs.data[cell_index] = vec4(light_accum / divisor, 0.0);
-#endif
}
#endif
@@ -587,40 +465,7 @@ void main() {
#ifdef MODE_WRITE_TEXTURE
{
-#ifdef MODE_ANISOTROPIC
- vec3 accum_total = vec3(0.0);
- accum_total += outputs.data[cell_index * 6 + 0].rgb;
- accum_total += outputs.data[cell_index * 6 + 1].rgb;
- accum_total += outputs.data[cell_index * 6 + 2].rgb;
- accum_total += outputs.data[cell_index * 6 + 3].rgb;
- accum_total += outputs.data[cell_index * 6 + 4].rgb;
- accum_total += outputs.data[cell_index * 6 + 5].rgb;
-
- float accum_total_energy = max(dot(accum_total, GREY_VEC), 0.00001);
- vec3 iso_positive = vec3(dot(outputs.data[cell_index * 6 + 0].rgb, GREY_VEC), dot(outputs.data[cell_index * 6 + 2].rgb, GREY_VEC), dot(outputs.data[cell_index * 6 + 4].rgb, GREY_VEC)) / vec3(accum_total_energy);
- vec3 iso_negative = vec3(dot(outputs.data[cell_index * 6 + 1].rgb, GREY_VEC), dot(outputs.data[cell_index * 6 + 3].rgb, GREY_VEC), dot(outputs.data[cell_index * 6 + 5].rgb, GREY_VEC)) / vec3(accum_total_energy);
-
- {
- uint aniso_pos = uint(clamp(iso_positive.b * 31.0, 0.0, 31.0));
- aniso_pos |= uint(clamp(iso_positive.g * 63.0, 0.0, 63.0)) << 5;
- aniso_pos |= uint(clamp(iso_positive.r * 31.0, 0.0, 31.0)) << 11;
- imageStore(aniso_pos_tex, ivec3(posu), uvec4(aniso_pos));
- }
-
- {
- uint aniso_neg = uint(clamp(iso_negative.b * 31.0, 0.0, 31.0));
- aniso_neg |= uint(clamp(iso_negative.g * 63.0, 0.0, 63.0)) << 5;
- aniso_neg |= uint(clamp(iso_negative.r * 31.0, 0.0, 31.0)) << 11;
- imageStore(aniso_neg_tex, ivec3(posu), uvec4(aniso_neg));
- }
-
- imageStore(color_tex, ivec3(posu), vec4(accum_total / params.dynamic_range, albedo.a));
-
-#else
-
imageStore(color_tex, ivec3(posu), vec4(outputs.data[cell_index].rgb / params.dynamic_range, albedo.a));
-
-#endif
}
#endif
@@ -763,13 +608,6 @@ void main() {
color.rgb /= params.dynamic_range;
imageStore(color_texture, pos3d, color);
//imageStore(color_texture,pos3d,vec4(1,1,1,1));
-
-#ifdef MODE_ANISOTROPIC
- //do not care about anisotropy for dynamic objects, just store full lit in all directions
- imageStore(aniso_pos_texture, pos3d, uvec4(0xFFFF));
- imageStore(aniso_neg_texture, pos3d, uvec4(0xFFFF));
-
-#endif // ANISOTROPIC
}
#endif // MODE_DYNAMIC_SHRINK_PLOT
}
diff --git a/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl b/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl
index 7d4d72967a..281c496df3 100644
--- a/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl
+++ b/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl
@@ -20,11 +20,6 @@ layout(set = 0, binding = 2) uniform texture3D color_tex;
layout(set = 0, binding = 3) uniform sampler tex_sampler;
-#ifdef USE_ANISOTROPY
-layout(set = 0, binding = 4) uniform texture3D aniso_pos_tex;
-layout(set = 0, binding = 5) uniform texture3D aniso_neg_tex;
-#endif
-
layout(push_constant, binding = 0, std430) uniform Params {
mat4 projection;
uint cell_offset;
diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index 15ce1dbe63..3ede9fed2d 100644
--- a/servers/rendering/renderer_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -71,6 +71,44 @@ static Transform2D _canvas_get_transform(RendererViewport::Viewport *p_viewport,
return xf;
}
+void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
+ if (p_viewport->render_buffers.is_valid()) {
+ if (p_viewport->size.width == 0 || p_viewport->size.height == 0) {
+ RSG::scene->free(p_viewport->render_buffers);
+ p_viewport->render_buffers = RID();
+ } else {
+ RS::ViewportScale3D scale_3d = p_viewport->scale_3d;
+ if (Engine::get_singleton()->is_editor_hint()) { // ignore this inside of the editor
+ scale_3d = RS::VIEWPORT_SCALE_3D_DISABLED;
+ }
+
+ int width = p_viewport->size.width;
+ int height = p_viewport->size.height;
+ switch (scale_3d) {
+ case RS::VIEWPORT_SCALE_3D_75_PERCENT: {
+ width = (width * 3) / 4;
+ height = (height * 3) / 4;
+ }; break;
+ case RS::VIEWPORT_SCALE_3D_50_PERCENT: {
+ width = width >> 1;
+ height = height >> 1;
+ }; break;
+ case RS::VIEWPORT_SCALE_3D_33_PERCENT: {
+ width = width / 3;
+ height = height / 3;
+ }; break;
+ case RS::VIEWPORT_SCALE_3D_25_PERCENT: {
+ width = width >> 2;
+ height = height >> 2;
+ }; break;
+ default:
+ break;
+ }
+ RSG::scene->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, width, height, p_viewport->msaa, p_viewport->screen_space_aa, p_viewport->use_debanding, p_viewport->get_view_count());
+ }
+ }
+}
+
void RendererViewport::_draw_3d(Viewport *p_viewport) {
RENDER_TIMESTAMP(">Begin Rendering 3D Scene");
@@ -100,7 +138,7 @@ void RendererViewport::_draw_3d(Viewport *p_viewport) {
RENDER_TIMESTAMP("<End Rendering 3D Scene");
}
-void RendererViewport::_draw_viewport(Viewport *p_viewport, uint32_t p_view_count) {
+void RendererViewport::_draw_viewport(Viewport *p_viewport) {
if (p_viewport->measure_render_time) {
String rt_id = "vp_begin_" + itos(p_viewport->self.get_id());
RSG::storage->capture_timestamp(rt_id);
@@ -142,7 +180,8 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport, uint32_t p_view_coun
if ((scenario_draw_canvas_bg || can_draw_3d) && !p_viewport->render_buffers.is_valid()) {
//wants to draw 3D but there is no render buffer, create
p_viewport->render_buffers = RSG::scene->render_buffers_create();
- RSG::scene->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, p_viewport->size.width, p_viewport->size.height, p_viewport->msaa, p_viewport->screen_space_aa, p_viewport->use_debanding, p_view_count);
+
+ _configure_3d_render_buffers(p_viewport);
}
RSG::storage->render_target_request_clear(p_viewport->render_target, bgcolor);
@@ -544,7 +583,7 @@ void RendererViewport::draw_viewports() {
RSG::storage->render_target_set_as_unused(vp->render_target);
if (vp->use_xr && xr_interface.is_valid()) {
// override our size, make sure it matches our required size and is created as a stereo target
- vp->size = xr_interface->get_render_targetsize();
+ vp->size = xr_interface->get_render_target_size();
uint32_t view_count = xr_interface->get_view_count();
RSG::storage->render_target_set_size(vp->render_target, vp->size.x, vp->size.y, view_count);
@@ -556,7 +595,7 @@ void RendererViewport::draw_viewports() {
RSG::scene->set_debug_draw_mode(vp->debug_draw);
// and draw viewport
- _draw_viewport(vp, view_count);
+ _draw_viewport(vp);
// measure
@@ -580,7 +619,7 @@ void RendererViewport::draw_viewports() {
RSG::scene->set_debug_draw_mode(vp->debug_draw);
// render standard mono camera
- _draw_viewport(vp, 1);
+ _draw_viewport(vp);
if (vp->viewport_to_screen != DisplayServer::INVALID_WINDOW_ID && (!vp->viewport_render_direct_to_screen || !RSG::rasterizer->is_low_end())) {
//copy to screen if set as such
@@ -648,9 +687,19 @@ void RendererViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr) {
}
viewport->use_xr = p_use_xr;
- if (viewport->render_buffers.is_valid()) {
- RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa, viewport->use_debanding, viewport->get_view_count());
+ _configure_3d_render_buffers(viewport);
+}
+
+void RendererViewport::viewport_set_scale_3d(RID p_viewport, RenderingServer::ViewportScale3D p_scale_3d) {
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ if (viewport->scale_3d == p_scale_3d) {
+ return;
}
+
+ viewport->scale_3d = p_scale_3d;
+ _configure_3d_render_buffers(viewport);
}
uint32_t RendererViewport::Viewport::get_view_count() {
@@ -677,14 +726,7 @@ void RendererViewport::viewport_set_size(RID p_viewport, int p_width, int p_heig
viewport->size = Size2(p_width, p_height);
uint32_t view_count = viewport->get_view_count();
RSG::storage->render_target_set_size(viewport->render_target, p_width, p_height, view_count);
- if (viewport->render_buffers.is_valid()) {
- if (p_width == 0 || p_height == 0) {
- RSG::scene->free(viewport->render_buffers);
- viewport->render_buffers = RID();
- } else {
- RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa, viewport->use_debanding, view_count);
- }
- }
+ _configure_3d_render_buffers(viewport);
viewport->occlusion_buffer_dirty = true;
}
@@ -915,9 +957,7 @@ void RendererViewport::viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa
return;
}
viewport->msaa = p_msaa;
- if (viewport->render_buffers.is_valid()) {
- RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, p_msaa, viewport->screen_space_aa, viewport->use_debanding, viewport->get_view_count());
- }
+ _configure_3d_render_buffers(viewport);
}
void RendererViewport::viewport_set_screen_space_aa(RID p_viewport, RS::ViewportScreenSpaceAA p_mode) {
@@ -928,9 +968,7 @@ void RendererViewport::viewport_set_screen_space_aa(RID p_viewport, RS::Viewport
return;
}
viewport->screen_space_aa = p_mode;
- if (viewport->render_buffers.is_valid()) {
- RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, p_mode, viewport->use_debanding, viewport->get_view_count());
- }
+ _configure_3d_render_buffers(viewport);
}
void RendererViewport::viewport_set_use_debanding(RID p_viewport, bool p_use_debanding) {
@@ -941,9 +979,7 @@ void RendererViewport::viewport_set_use_debanding(RID p_viewport, bool p_use_deb
return;
}
viewport->use_debanding = p_use_debanding;
- if (viewport->render_buffers.is_valid()) {
- RSG::scene->render_buffers_configure(viewport->render_buffers, viewport->render_target, viewport->size.width, viewport->size.height, viewport->msaa, viewport->screen_space_aa, p_use_debanding, viewport->get_view_count());
- }
+ _configure_3d_render_buffers(viewport);
}
void RendererViewport::viewport_set_use_occlusion_culling(RID p_viewport, bool p_use_occlusion_culling) {
diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h
index ac7a35f97d..f6095e18d7 100644
--- a/servers/rendering/renderer_viewport.h
+++ b/servers/rendering/renderer_viewport.h
@@ -49,6 +49,8 @@ public:
bool use_xr; /* use xr interface to override camera positioning and projection matrices and control output */
+ RS::ViewportScale3D scale_3d = RenderingServer::VIEWPORT_SCALE_3D_DISABLED;
+
Size2i size;
RID camera;
RID scenario;
@@ -192,8 +194,9 @@ public:
int total_draw_calls_used = 0;
private:
+ void _configure_3d_render_buffers(Viewport *p_viewport);
void _draw_3d(Viewport *p_viewport);
- void _draw_viewport(Viewport *p_viewport, uint32_t p_view_count = 1);
+ void _draw_viewport(Viewport *p_viewport);
int occlusion_rays_per_thread = 512;
@@ -204,6 +207,7 @@ public:
void viewport_initialize(RID p_rid);
void viewport_set_use_xr(RID p_viewport, bool p_use_xr);
+ void viewport_set_scale_3d(RID p_viewport, RenderingServer::ViewportScale3D p_scale_3d);
void viewport_set_size(RID p_viewport, int p_width, int p_height);
diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h
index e2d207dab2..2cf1f165dd 100644
--- a/servers/rendering/rendering_device.h
+++ b/servers/rendering/rendering_device.h
@@ -495,6 +495,7 @@ public:
virtual bool texture_is_format_supported_for_usage(DataFormat p_format, uint32_t p_usage) const = 0;
virtual bool texture_is_shared(RID p_texture) = 0;
virtual bool texture_is_valid(RID p_texture) = 0;
+ virtual Size2i texture_size(RID p_texture) = 0;
virtual Error texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
virtual Error texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index c1336ee42d..56e79b62f2 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -526,6 +526,7 @@ public:
FUNCRIDSPLIT(viewport)
FUNC2(viewport_set_use_xr, RID, bool)
+ FUNC2(viewport_set_scale_3d, RID, ViewportScale3D)
FUNC3(viewport_set_size, RID, int, int)
FUNC2(viewport_set_active, RID, bool)
@@ -762,6 +763,7 @@ public:
FUNC4(canvas_item_add_circle, RID, const Point2 &, float, const Color &)
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)
+ FUNC7(canvas_item_add_msdf_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, int, float)
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)