Modified light rendering to make it more compatible.
Modified polygon management to make it more compatible with MoltenVK
This commit is contained in:
parent
a3f8ffac63
commit
ef083a583b
23 changed files with 682 additions and 498 deletions
|
@ -1866,6 +1866,93 @@ RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID
|
|||
return id;
|
||||
}
|
||||
|
||||
RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, int p_layer, int p_mipmap) {
|
||||
|
||||
Texture *src_texture = texture_owner.getornull(p_with_texture);
|
||||
ERR_FAIL_COND_V(!src_texture, RID());
|
||||
|
||||
if (src_texture->owner.is_valid()) { //ahh this is a share
|
||||
p_with_texture = src_texture->owner;
|
||||
src_texture = texture_owner.getornull(src_texture->owner);
|
||||
ERR_FAIL_COND_V(!src_texture, RID()); //this is a bug
|
||||
}
|
||||
|
||||
//create view
|
||||
|
||||
Texture texture = *src_texture;
|
||||
|
||||
uint32_t array_layer_multiplier = 1;
|
||||
if (texture.type == TEXTURE_TYPE_CUBE_ARRAY || texture.type == TEXTURE_TYPE_CUBE) {
|
||||
array_layer_multiplier = 6;
|
||||
}
|
||||
|
||||
VkImageViewCreateInfo image_view_create_info;
|
||||
image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
image_view_create_info.pNext = NULL;
|
||||
image_view_create_info.flags = 0;
|
||||
image_view_create_info.image = texture.image;
|
||||
|
||||
static const VkImageViewType view_types[TEXTURE_TYPE_MAX] = {
|
||||
VK_IMAGE_VIEW_TYPE_1D,
|
||||
VK_IMAGE_VIEW_TYPE_2D,
|
||||
VK_IMAGE_VIEW_TYPE_2D,
|
||||
VK_IMAGE_VIEW_TYPE_2D,
|
||||
VK_IMAGE_VIEW_TYPE_1D,
|
||||
VK_IMAGE_VIEW_TYPE_2D,
|
||||
VK_IMAGE_VIEW_TYPE_2D,
|
||||
};
|
||||
|
||||
image_view_create_info.viewType = view_types[texture.type];
|
||||
if (p_view.format_override == DATA_FORMAT_MAX || p_view.format_override == texture.format) {
|
||||
image_view_create_info.format = vulkan_formats[texture.format];
|
||||
} else {
|
||||
ERR_FAIL_INDEX_V(p_view.format_override, DATA_FORMAT_MAX, RID());
|
||||
|
||||
ERR_FAIL_COND_V_MSG(texture.allowed_shared_formats.find(p_view.format_override) == -1, RID(),
|
||||
"Format override is not in the list of allowed shareable formats for original texture.");
|
||||
image_view_create_info.format = vulkan_formats[p_view.format_override];
|
||||
}
|
||||
|
||||
static const VkComponentSwizzle component_swizzles[TEXTURE_SWIZZLE_MAX] = {
|
||||
VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||
VK_COMPONENT_SWIZZLE_ZERO,
|
||||
VK_COMPONENT_SWIZZLE_ONE,
|
||||
VK_COMPONENT_SWIZZLE_R,
|
||||
VK_COMPONENT_SWIZZLE_G,
|
||||
VK_COMPONENT_SWIZZLE_B,
|
||||
VK_COMPONENT_SWIZZLE_A
|
||||
};
|
||||
|
||||
image_view_create_info.components.r = component_swizzles[p_view.swizzle_r];
|
||||
image_view_create_info.components.g = component_swizzles[p_view.swizzle_g];
|
||||
image_view_create_info.components.b = component_swizzles[p_view.swizzle_b];
|
||||
image_view_create_info.components.a = component_swizzles[p_view.swizzle_a];
|
||||
|
||||
ERR_FAIL_INDEX_V(p_mipmap, texture.mipmaps, RID());
|
||||
image_view_create_info.subresourceRange.baseMipLevel = p_mipmap;
|
||||
image_view_create_info.subresourceRange.levelCount = 1;
|
||||
image_view_create_info.subresourceRange.layerCount = 1;
|
||||
image_view_create_info.subresourceRange.baseArrayLayer = p_layer;
|
||||
|
||||
if (texture.usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
|
||||
image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
} else {
|
||||
image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
}
|
||||
|
||||
VkResult err = vkCreateImageView(device, &image_view_create_info, NULL, &texture.view);
|
||||
|
||||
if (err) {
|
||||
ERR_FAIL_V(RID());
|
||||
}
|
||||
|
||||
texture.owner = p_with_texture;
|
||||
RID id = texture_owner.make_rid(texture);
|
||||
_add_dependency(id, p_with_texture);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, const PoolVector<uint8_t> &p_data, bool p_sync_with_draw) {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
@ -2618,10 +2705,18 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_c
|
|||
fb_format.E = E;
|
||||
fb_format.color_attachments = color_references;
|
||||
fb_format.render_pass = render_pass;
|
||||
fb_format.samples = p_format[0].samples;
|
||||
framebuffer_formats[id] = fb_format;
|
||||
return id;
|
||||
}
|
||||
|
||||
RenderingDevice::TextureSamples RenderingDeviceVulkan::framebuffer_format_get_texture_samples(FramebufferFormatID p_format) {
|
||||
Map<FramebufferFormatID, FramebufferFormat>::Element *E = framebuffer_formats.find(p_format);
|
||||
ERR_FAIL_COND_V(!E, TEXTURE_SAMPLES_1);
|
||||
|
||||
return E->get().samples;
|
||||
}
|
||||
|
||||
/***********************/
|
||||
/**** RENDER TARGET ****/
|
||||
/***********************/
|
||||
|
@ -5689,6 +5784,41 @@ void RenderingDeviceVulkan::_free_rids(T &p_owner, const char *p_type) {
|
|||
}
|
||||
}
|
||||
|
||||
int RenderingDeviceVulkan::limit_get(Limit p_limit) {
|
||||
switch (p_limit) {
|
||||
case LIMIT_MAX_BOUND_UNIFORM_SETS: return limits.maxBoundDescriptorSets;
|
||||
case LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS: return limits.maxColorAttachments;
|
||||
case LIMIT_MAX_TEXTURES_PER_UNIFORM_SET: return limits.maxDescriptorSetSampledImages;
|
||||
case LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET: return limits.maxDescriptorSetSamplers;
|
||||
case LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET: return limits.maxDescriptorSetStorageBuffers;
|
||||
case LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET: return limits.maxDescriptorSetStorageImages;
|
||||
case LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET: return limits.maxDescriptorSetUniformBuffers;
|
||||
case LIMIT_MAX_DRAW_INDEXED_INDEX: return limits.maxDrawIndexedIndexValue;
|
||||
case LIMIT_MAX_FRAMEBUFFER_HEIGHT: return limits.maxFramebufferHeight;
|
||||
case LIMIT_MAX_FRAMEBUFFER_WIDTH: return limits.maxFramebufferWidth;
|
||||
case LIMIT_MAX_TEXTURE_ARRAY_LAYERS: return limits.maxImageArrayLayers;
|
||||
case LIMIT_MAX_TEXTURE_SIZE_1D: return limits.maxImageDimension1D;
|
||||
case LIMIT_MAX_TEXTURE_SIZE_2D: return limits.maxImageDimension2D;
|
||||
case LIMIT_MAX_TEXTURE_SIZE_3D: return limits.maxImageDimension3D;
|
||||
case LIMIT_MAX_TEXTURE_SIZE_CUBE: return limits.maxImageDimensionCube;
|
||||
case LIMIT_MAX_TEXTURES_PER_SHADER_STAGE: return limits.maxPerStageDescriptorSampledImages;
|
||||
case LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE: return limits.maxPerStageDescriptorSamplers;
|
||||
case LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE: return limits.maxPerStageDescriptorStorageBuffers;
|
||||
case LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE: return limits.maxPerStageDescriptorStorageImages;
|
||||
case LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE: return limits.maxPerStageDescriptorUniformBuffers;
|
||||
case LIMIT_MAX_PUSH_CONSTANT_SIZE: return limits.maxPushConstantsSize;
|
||||
case LIMIT_MAX_UNIFORM_BUFFER_SIZE: return limits.maxUniformBufferRange;
|
||||
case LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET: return limits.maxVertexInputAttributeOffset;
|
||||
case LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES: return limits.maxVertexInputAttributes;
|
||||
case LIMIT_MAX_VERTEX_INPUT_BINDINGS: return limits.maxVertexInputBindings;
|
||||
case LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE: return limits.maxVertexInputBindingStride;
|
||||
case LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT: return limits.minUniformBufferOffsetAlignment;
|
||||
default: ERR_FAIL_V(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RenderingDeviceVulkan::finalize() {
|
||||
|
||||
//free all resources
|
||||
|
|
|
@ -234,6 +234,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
|
|||
const Map<FramebufferFormatKey, FramebufferFormatID>::Element *E;
|
||||
VkRenderPass render_pass; //here for constructing shaders, never used, see section (7.2. Render Pass Compatibility from Vulkan spec)
|
||||
int color_attachments; //used for pipeline validation
|
||||
TextureSamples samples;
|
||||
};
|
||||
|
||||
Map<FramebufferFormatID, FramebufferFormat> framebuffer_formats;
|
||||
|
@ -714,6 +715,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
|
|||
public:
|
||||
virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<PoolVector<uint8_t> > &p_data = Vector<PoolVector<uint8_t> >());
|
||||
virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture);
|
||||
virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, int p_layer, int p_mipmap);
|
||||
virtual Error texture_update(RID p_texture, uint32_t p_layer, const PoolVector<uint8_t> &p_data, bool p_sync_with_draw = false);
|
||||
virtual PoolVector<uint8_t> texture_get_data(RID p_texture, uint32_t p_layer);
|
||||
|
||||
|
@ -725,7 +727,8 @@ public:
|
|||
/**** FRAMEBUFFER ****/
|
||||
/*********************/
|
||||
|
||||
FramebufferFormatID framebuffer_format_create(const Vector<AttachmentFormat> &p_format);
|
||||
virtual FramebufferFormatID framebuffer_format_create(const Vector<AttachmentFormat> &p_format);
|
||||
virtual TextureSamples framebuffer_format_get_texture_samples(FramebufferFormatID p_format);
|
||||
|
||||
virtual RID framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check = INVALID_ID);
|
||||
|
||||
|
@ -814,6 +817,8 @@ public:
|
|||
|
||||
virtual void free(RID p_id);
|
||||
|
||||
virtual int limit_get(Limit p_limit);
|
||||
|
||||
virtual void prepare_screen_for_drawing();
|
||||
void initialize(VulkanContext *p_context);
|
||||
void finalize();
|
||||
|
|
|
@ -86,6 +86,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_messenger_callback(VkDebugU
|
|||
|
||||
free(message);
|
||||
|
||||
abort();
|
||||
// Don't bail out, but keep going.
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -296,17 +296,6 @@ int Light2D::get_shadow_buffer_size() const {
|
|||
return shadow_buffer_size;
|
||||
}
|
||||
|
||||
void Light2D::set_shadow_gradient_length(float p_multiplier) {
|
||||
|
||||
shadow_gradient_length = p_multiplier;
|
||||
VS::get_singleton()->canvas_light_set_shadow_gradient_length(canvas_light, p_multiplier);
|
||||
}
|
||||
|
||||
float Light2D::get_shadow_gradient_length() const {
|
||||
|
||||
return shadow_gradient_length;
|
||||
}
|
||||
|
||||
void Light2D::set_shadow_filter(ShadowFilter p_filter) {
|
||||
ERR_FAIL_INDEX(p_filter, SHADOW_FILTER_MAX);
|
||||
shadow_filter = p_filter;
|
||||
|
@ -427,9 +416,6 @@ void Light2D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_shadow_smooth", "smooth"), &Light2D::set_shadow_smooth);
|
||||
ClassDB::bind_method(D_METHOD("get_shadow_smooth"), &Light2D::get_shadow_smooth);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_shadow_gradient_length", "multiplier"), &Light2D::set_shadow_gradient_length);
|
||||
ClassDB::bind_method(D_METHOD("get_shadow_gradient_length"), &Light2D::get_shadow_gradient_length);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_shadow_filter", "filter"), &Light2D::set_shadow_filter);
|
||||
ClassDB::bind_method(D_METHOD("get_shadow_filter"), &Light2D::get_shadow_filter);
|
||||
|
||||
|
@ -456,7 +442,6 @@ void Light2D::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_enabled"), "set_shadow_enabled", "is_shadow_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color"), "set_shadow_color", "get_shadow_color");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_buffer_size", PROPERTY_HINT_RANGE, "32,16384,1"), "set_shadow_buffer_size", "get_shadow_buffer_size");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_gradient_length", PROPERTY_HINT_RANGE, "0,4096,0.1"), "set_shadow_gradient_length", "get_shadow_gradient_length");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_filter", PROPERTY_HINT_ENUM, "None,PCF5,PCF13"), "set_shadow_filter", "get_shadow_filter");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_filter_smooth", PROPERTY_HINT_RANGE, "0,64,0.1"), "set_shadow_smooth", "get_shadow_smooth");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_item_cull_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_item_shadow_cull_mask", "get_item_shadow_cull_mask");
|
||||
|
@ -488,7 +473,6 @@ Light2D::Light2D() {
|
|||
item_shadow_mask = 1;
|
||||
mode = MODE_ADD;
|
||||
shadow_buffer_size = 2048;
|
||||
shadow_gradient_length = 0;
|
||||
energy = 1.0;
|
||||
shadow_color = Color(0, 0, 0, 0);
|
||||
shadow_filter = SHADOW_FILTER_NONE;
|
||||
|
|
|
@ -70,7 +70,6 @@ private:
|
|||
int item_shadow_mask;
|
||||
int shadow_buffer_size;
|
||||
float shadow_smooth;
|
||||
float shadow_gradient_length;
|
||||
Mode mode;
|
||||
Ref<Texture2D> texture;
|
||||
Vector2 texture_offset;
|
||||
|
@ -147,9 +146,6 @@ public:
|
|||
void set_shadow_buffer_size(int p_size);
|
||||
int get_shadow_buffer_size() const;
|
||||
|
||||
void set_shadow_gradient_length(float p_multiplier);
|
||||
float get_shadow_gradient_length() const;
|
||||
|
||||
void set_shadow_filter(ShadowFilter p_filter);
|
||||
ShadowFilter get_shadow_filter() const;
|
||||
|
||||
|
|
|
@ -618,7 +618,6 @@ public:
|
|||
RID canvas;
|
||||
bool use_shadow;
|
||||
int shadow_buffer_size;
|
||||
float shadow_gradient_length;
|
||||
VS::CanvasLightShadowFilter shadow_filter;
|
||||
Color shadow_color;
|
||||
float shadow_smooth;
|
||||
|
@ -638,10 +637,12 @@ public:
|
|||
Light *mask_next_ptr;
|
||||
|
||||
RID light_internal;
|
||||
uint64_t version;
|
||||
|
||||
int32_t render_index_cache;
|
||||
|
||||
Light() {
|
||||
version = 0;
|
||||
enabled = true;
|
||||
color = Color(1, 1, 1);
|
||||
shadow_color = Color(0, 0, 0, 0);
|
||||
|
@ -661,7 +662,6 @@ public:
|
|||
filter_next_ptr = NULL;
|
||||
use_shadow = false;
|
||||
shadow_buffer_size = 2048;
|
||||
shadow_gradient_length = 0;
|
||||
shadow_filter = VS::CANVAS_LIGHT_FILTER_NONE;
|
||||
shadow_smooth = 0.0;
|
||||
render_index_cache = -1;
|
||||
|
@ -1064,6 +1064,13 @@ public:
|
|||
return command;
|
||||
}
|
||||
|
||||
struct CustomData {
|
||||
|
||||
virtual ~CustomData() {}
|
||||
};
|
||||
|
||||
mutable CustomData *custom_data; //implementation dependent
|
||||
|
||||
void clear() {
|
||||
Command *c = commands;
|
||||
while (c) {
|
||||
|
@ -1112,6 +1119,7 @@ public:
|
|||
light_masked = false;
|
||||
update_when_visible = false;
|
||||
z_final = 0;
|
||||
custom_data = NULL;
|
||||
}
|
||||
virtual ~Item() {
|
||||
clear();
|
||||
|
@ -1119,6 +1127,9 @@ public:
|
|||
memfree(blocks[i].memory);
|
||||
}
|
||||
if (copy_back_buffer) memdelete(copy_back_buffer);
|
||||
if (custom_data) {
|
||||
memdelete(custom_data);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -225,42 +225,34 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
// that need to be created for these formats.
|
||||
|
||||
uint32_t vertex_count = p_points.size();
|
||||
uint32_t base_offset = 0;
|
||||
uint32_t stride = 2; //vertices always repeat
|
||||
if ((uint32_t)p_colors.size() == vertex_count) {
|
||||
if ((uint32_t)p_colors.size() == vertex_count || p_colors.size() == 1) {
|
||||
stride += 4;
|
||||
} else {
|
||||
base_offset += 4;
|
||||
}
|
||||
if ((uint32_t)p_uvs.size() == vertex_count) {
|
||||
stride += 2;
|
||||
} else {
|
||||
base_offset += 2;
|
||||
}
|
||||
if ((uint32_t)p_bones.size() == vertex_count * 4) {
|
||||
stride += 4;
|
||||
} else {
|
||||
base_offset += 4;
|
||||
}
|
||||
if ((uint32_t)p_weights.size() == vertex_count * 4) {
|
||||
stride += 4;
|
||||
} else {
|
||||
base_offset += 4;
|
||||
}
|
||||
|
||||
uint32_t buffer_size = base_offset + stride * p_points.size();
|
||||
uint32_t buffer_size = stride * p_points.size();
|
||||
|
||||
PoolVector<uint8_t> polygon_buffer;
|
||||
polygon_buffer.resize(buffer_size * sizeof(float));
|
||||
Vector<RD::VertexDescription> descriptions;
|
||||
descriptions.resize(5);
|
||||
Vector<RID> buffers;
|
||||
buffers.resize(5);
|
||||
|
||||
{
|
||||
PoolVector<uint8_t>::Read r = polygon_buffer.read();
|
||||
float *fptr = (float *)r.ptr();
|
||||
uint32_t *uptr = (uint32_t *)r.ptr();
|
||||
uint32_t single_offset = 0;
|
||||
|
||||
uint32_t base_offset = 0;
|
||||
{ //vertices
|
||||
RD::VertexDescription vd;
|
||||
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
|
||||
|
@ -281,7 +273,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
}
|
||||
|
||||
//colors
|
||||
if ((uint32_t)p_colors.size() == vertex_count) {
|
||||
if ((uint32_t)p_colors.size() == vertex_count || p_colors.size() == 1) {
|
||||
RD::VertexDescription vd;
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
|
||||
vd.offset = base_offset * sizeof(float);
|
||||
|
@ -290,31 +282,34 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
|
||||
descriptions.write[1] = vd;
|
||||
|
||||
const Color *color_ptr = p_colors.ptr();
|
||||
if (p_colors.size() == 1) {
|
||||
Color color = p_colors[0];
|
||||
for (uint32_t i = 0; i < vertex_count; i++) {
|
||||
fptr[base_offset + i * stride + 0] = color.r;
|
||||
fptr[base_offset + i * stride + 1] = color.g;
|
||||
fptr[base_offset + i * stride + 2] = color.b;
|
||||
fptr[base_offset + i * stride + 3] = color.a;
|
||||
}
|
||||
} else {
|
||||
const Color *color_ptr = p_colors.ptr();
|
||||
|
||||
for (uint32_t i = 0; i < vertex_count; i++) {
|
||||
fptr[base_offset + i * stride + 0] = color_ptr[i].r;
|
||||
fptr[base_offset + i * stride + 1] = color_ptr[i].g;
|
||||
fptr[base_offset + i * stride + 2] = color_ptr[i].b;
|
||||
fptr[base_offset + i * stride + 3] = color_ptr[i].a;
|
||||
for (uint32_t i = 0; i < vertex_count; i++) {
|
||||
fptr[base_offset + i * stride + 0] = color_ptr[i].r;
|
||||
fptr[base_offset + i * stride + 1] = color_ptr[i].g;
|
||||
fptr[base_offset + i * stride + 2] = color_ptr[i].b;
|
||||
fptr[base_offset + i * stride + 3] = color_ptr[i].a;
|
||||
}
|
||||
}
|
||||
base_offset += 4;
|
||||
} else {
|
||||
RD::VertexDescription vd;
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
|
||||
vd.offset = single_offset * sizeof(float);
|
||||
vd.offset = 0;
|
||||
vd.location = VS::ARRAY_COLOR;
|
||||
vd.stride = 0;
|
||||
|
||||
descriptions.write[1] = vd;
|
||||
|
||||
Color color = p_colors.size() ? p_colors[0] : Color(1, 1, 1, 1);
|
||||
fptr[single_offset + 0] = color.r;
|
||||
fptr[single_offset + 1] = color.g;
|
||||
fptr[single_offset + 2] = color.b;
|
||||
fptr[single_offset + 3] = color.a;
|
||||
|
||||
single_offset += 4;
|
||||
buffers.write[1] = polygon_buffers.default_color_buffer;
|
||||
}
|
||||
|
||||
//uvs
|
||||
|
@ -337,17 +332,12 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
} else {
|
||||
RD::VertexDescription vd;
|
||||
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
|
||||
vd.offset = single_offset * sizeof(float);
|
||||
vd.offset = 0;
|
||||
vd.location = VS::ARRAY_TEX_UV;
|
||||
vd.stride = 0;
|
||||
|
||||
descriptions.write[2] = vd;
|
||||
|
||||
Vector2 uv;
|
||||
fptr[single_offset + 0] = uv.x;
|
||||
fptr[single_offset + 1] = uv.y;
|
||||
|
||||
single_offset += 2;
|
||||
buffers.write[2] = polygon_buffers.default_uv_buffer;
|
||||
}
|
||||
|
||||
//bones
|
||||
|
@ -373,17 +363,12 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
} else {
|
||||
RD::VertexDescription vd;
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
|
||||
vd.offset = single_offset * sizeof(float);
|
||||
vd.offset = 0;
|
||||
vd.location = VS::ARRAY_BONES;
|
||||
vd.stride = 0;
|
||||
|
||||
descriptions.write[3] = vd;
|
||||
|
||||
uptr[single_offset + 0] = 0;
|
||||
uptr[single_offset + 1] = 0;
|
||||
uptr[single_offset + 2] = 0;
|
||||
uptr[single_offset + 3] = 0;
|
||||
single_offset += 4;
|
||||
buffers.write[3] = polygon_buffers.default_bone_buffer;
|
||||
}
|
||||
|
||||
//bones
|
||||
|
@ -409,22 +394,16 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
} else {
|
||||
RD::VertexDescription vd;
|
||||
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
|
||||
vd.offset = single_offset * sizeof(float);
|
||||
vd.offset = 0;
|
||||
vd.location = VS::ARRAY_WEIGHTS;
|
||||
vd.stride = 0;
|
||||
|
||||
descriptions.write[4] = vd;
|
||||
|
||||
fptr[single_offset + 0] = 0.0;
|
||||
fptr[single_offset + 1] = 0.0;
|
||||
fptr[single_offset + 2] = 0.0;
|
||||
fptr[single_offset + 3] = 0.0;
|
||||
single_offset += 4;
|
||||
buffers.write[4] = polygon_buffers.default_weight_buffer;
|
||||
}
|
||||
|
||||
//check that everything is as it should be
|
||||
ERR_FAIL_COND_V(single_offset != (base_offset - stride), 0);
|
||||
ERR_FAIL_COND_V(((base_offset - stride) + stride * vertex_count) != buffer_size, 0);
|
||||
ERR_FAIL_COND_V(base_offset != stride, 0); //bug
|
||||
}
|
||||
|
||||
RD::VertexFormatID vertex_id = RD::get_singleton()->vertex_format_create(descriptions);
|
||||
|
@ -432,11 +411,12 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
|
|||
|
||||
PolygonBuffers pb;
|
||||
pb.vertex_buffer = RD::get_singleton()->vertex_buffer_create(polygon_buffer.size(), polygon_buffer);
|
||||
Vector<RID> buffers;
|
||||
buffers.resize(descriptions.size());
|
||||
for (int i = 0; i < descriptions.size(); i++) {
|
||||
buffers.write[i] = pb.vertex_buffer;
|
||||
if (buffers[i] == RID()) { //if put in vertex, use as vertex
|
||||
buffers.write[i] = pb.vertex_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
pb.vertex_array = RD::get_singleton()->vertex_array_create(p_points.size(), vertex_id, buffers);
|
||||
|
||||
if (p_indices.size()) {
|
||||
|
@ -508,9 +488,10 @@ Size2i RasterizerCanvasRD::_bind_texture_binding(TextureBindingID p_binding, RD:
|
|||
}
|
||||
|
||||
////////////////////
|
||||
void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_item, RenderTargetFormat p_render_target_format, RD::TextureSamples p_samples, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights) {
|
||||
void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_item, RD::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights) {
|
||||
|
||||
//create an empty push constant
|
||||
|
||||
PushConstant push_constant;
|
||||
Transform2D base_transform = p_canvas_transform_inverse * p_item->final_transform;
|
||||
_update_transform_2d_to_mat2x3(base_transform, push_constant.world);
|
||||
|
@ -538,30 +519,190 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
|
|||
|
||||
uint32_t base_flags = 0;
|
||||
|
||||
bool light_uniform_set_dirty = false;
|
||||
|
||||
if (!p_item->custom_data) {
|
||||
p_item->custom_data = memnew(ItemStateData);
|
||||
light_uniform_set_dirty = true;
|
||||
}
|
||||
|
||||
ItemStateData *state_data = (ItemStateData *)p_item->custom_data;
|
||||
|
||||
Light *light_cache[DEFAULT_MAX_LIGHTS_PER_ITEM];
|
||||
uint16_t light_count = 0;
|
||||
PipelineLightMode light_mode;
|
||||
|
||||
{
|
||||
|
||||
Light *light = p_lights;
|
||||
|
||||
uint16_t light_count = 0;
|
||||
while (light) {
|
||||
|
||||
if (light->render_index_cache >= 0 && p_item->light_mask & light->item_mask && p_item->z_final >= light->z_min && p_item->z_final <= light->z_max && p_item->global_rect_cache.intersects_transformed(light->xform_cache, light->rect_cache)) {
|
||||
|
||||
uint32_t light_index = light->render_index_cache;
|
||||
push_constant.lights[light_count >> 2] |= light_index << ((light_count & 3) * 8);
|
||||
|
||||
if (!light_uniform_set_dirty && (state_data->light_cache[light_count].light != light || state_data->light_cache[light_count].light_version != light->version)) {
|
||||
light_uniform_set_dirty = true;
|
||||
}
|
||||
|
||||
light_cache[light_count] = light;
|
||||
|
||||
light_count++;
|
||||
if (light->mode == VS::CANVAS_LIGHT_MODE_MASK) {
|
||||
base_flags |= FLAGS_USING_LIGHT_MASK;
|
||||
}
|
||||
if (light_count == MAX_LIGHTS_PER_ITEM) {
|
||||
if (light_count == state.max_lights_per_item) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
light = light->next_ptr;
|
||||
}
|
||||
|
||||
if (light_count != state_data->light_cache_count) {
|
||||
light_uniform_set_dirty = true;
|
||||
}
|
||||
base_flags |= light_count << FLAGS_LIGHT_COUNT_SHIFT;
|
||||
}
|
||||
|
||||
if (light_count) {
|
||||
|
||||
//validate and update lighs if they are being used
|
||||
bool invalid_uniform = state_data->light_uniform_set.is_valid() && !RD::get_singleton()->uniform_set_is_valid(state_data->light_uniform_set);
|
||||
|
||||
if (state_data->light_uniform_set.is_null() || invalid_uniform || light_uniform_set_dirty) {
|
||||
//recreate uniform set
|
||||
if (state_data->light_uniform_set.is_valid() && !invalid_uniform) {
|
||||
RD::get_singleton()->free(state_data->light_uniform_set);
|
||||
}
|
||||
|
||||
state_data->light_uniform_set = RID();
|
||||
|
||||
Vector<RD::Uniform> uniforms;
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
||||
u.binding = 0;
|
||||
u.ids.push_back(state.lights_uniform_buffer);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
RD::Uniform u_lights;
|
||||
u_lights.type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
u_lights.binding = 1;
|
||||
|
||||
RD::Uniform u_shadows;
|
||||
u_shadows.type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
u_shadows.binding = 2;
|
||||
|
||||
//lights
|
||||
for (uint32_t i = 0; i < state.max_lights_per_item; i++) {
|
||||
if (i < light_count) {
|
||||
|
||||
CanvasLight *cl = canvas_light_owner.getornull(light_cache[i]->light_internal);
|
||||
ERR_CONTINUE(!cl);
|
||||
|
||||
RID rd_texture;
|
||||
|
||||
if (cl->texture.is_valid()) {
|
||||
rd_texture = storage->texture_get_rd_texture(cl->texture);
|
||||
}
|
||||
if (rd_texture.is_valid()) {
|
||||
u_lights.ids.push_back(rd_texture);
|
||||
} else {
|
||||
u_lights.ids.push_back(default_textures.white_texture);
|
||||
}
|
||||
if (cl->shadow.texture.is_valid()) {
|
||||
u_shadows.ids.push_back(cl->shadow.texture);
|
||||
} else {
|
||||
u_shadows.ids.push_back(default_textures.black_texture);
|
||||
}
|
||||
} else {
|
||||
u_lights.ids.push_back(default_textures.white_texture);
|
||||
u_shadows.ids.push_back(default_textures.black_texture);
|
||||
}
|
||||
}
|
||||
|
||||
uniforms.push_back(u_lights);
|
||||
uniforms.push_back(u_shadows);
|
||||
}
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.type = RD::UNIFORM_TYPE_SAMPLER;
|
||||
u.binding = 3;
|
||||
u.ids.push_back(state.shadow_sampler);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
state_data->light_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader_light, 3);
|
||||
}
|
||||
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, state_data->light_uniform_set, 3);
|
||||
light_mode = PIPELINE_LIGHT_MODE_ENABLED;
|
||||
} else {
|
||||
light_mode = PIPELINE_LIGHT_MODE_DISABLED;
|
||||
}
|
||||
|
||||
{
|
||||
//state uniform
|
||||
bool invalid_uniform = state_data->state_uniform_set.is_valid() && !RD::get_singleton()->uniform_set_is_valid(state_data->state_uniform_set);
|
||||
|
||||
if (state_data->state_uniform_set.is_null() || invalid_uniform) {
|
||||
if (state_data->state_uniform_set.is_valid() && !invalid_uniform) {
|
||||
RD::get_singleton()->free(state_data->state_uniform_set);
|
||||
}
|
||||
state_data->state_uniform_set = RID();
|
||||
|
||||
Vector<RD::Uniform> uniforms;
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
||||
u.binding = 0;
|
||||
u.ids.push_back(state.canvas_state_buffer);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
if (false && p_item->skeleton.is_valid()) {
|
||||
//bind skeleton stuff
|
||||
} else {
|
||||
//bind default
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
||||
u.binding = 0;
|
||||
u.ids.push_back(state.canvas_state_buffer);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.type = RD::UNIFORM_TYPE_TEXTURE_BUFFER;
|
||||
u.binding = 1;
|
||||
u.ids.push_back(shader.default_skeleton_texture_buffer);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
||||
u.binding = 2;
|
||||
u.ids.push_back(shader.default_skeleton_uniform_buffer);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
}
|
||||
|
||||
state_data->state_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader, 2);
|
||||
}
|
||||
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, state_data->state_uniform_set, 2);
|
||||
}
|
||||
|
||||
PipelineVariants *pipeline_variants = &shader.pipeline_variants;
|
||||
|
||||
bool reclip = false;
|
||||
|
@ -579,7 +720,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
|
|||
|
||||
//bind pipeline
|
||||
{
|
||||
RID pipeline = pipeline_variants->variants[p_render_target_format][PIPELINE_VARIANT_QUAD].get_render_pipeline(RD::INVALID_ID, p_samples);
|
||||
RID pipeline = pipeline_variants->variants[light_mode][PIPELINE_VARIANT_QUAD].get_render_pipeline(RD::INVALID_ID, p_framebuffer_format);
|
||||
RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline);
|
||||
}
|
||||
|
||||
|
@ -679,7 +820,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
|
|||
|
||||
//bind pipeline
|
||||
{
|
||||
RID pipeline = pipeline_variants->variants[p_render_target_format][PIPELINE_VARIANT_NINEPATCH].get_render_pipeline(RD::INVALID_ID, p_samples);
|
||||
RID pipeline = pipeline_variants->variants[light_mode][PIPELINE_VARIANT_NINEPATCH].get_render_pipeline(RD::INVALID_ID, p_framebuffer_format);
|
||||
RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline);
|
||||
}
|
||||
|
||||
|
@ -761,7 +902,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
|
|||
{
|
||||
static const PipelineVariant variant[VS::PRIMITIVE_MAX] = { PIPELINE_VARIANT_ATTRIBUTE_POINTS, PIPELINE_VARIANT_ATTRIBUTE_LINES, PIPELINE_VARIANT_ATTRIBUTE_TRIANGLES };
|
||||
ERR_CONTINUE(polygon->primitive < 0 || polygon->primitive >= VS::PRIMITIVE_MAX);
|
||||
RID pipeline = pipeline_variants->variants[p_render_target_format][variant[polygon->primitive]].get_render_pipeline(pb->vertex_format_id, p_samples);
|
||||
RID pipeline = pipeline_variants->variants[light_mode][variant[polygon->primitive]].get_render_pipeline(pb->vertex_format_id, p_framebuffer_format);
|
||||
RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline);
|
||||
}
|
||||
|
||||
|
@ -815,7 +956,7 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
|
|||
{
|
||||
static const PipelineVariant variant[4] = { PIPELINE_VARIANT_PRIMITIVE_POINTS, PIPELINE_VARIANT_PRIMITIVE_LINES, PIPELINE_VARIANT_PRIMITIVE_TRIANGLES, PIPELINE_VARIANT_PRIMITIVE_TRIANGLES };
|
||||
ERR_CONTINUE(primitive->point_count == 0 || primitive->point_count > 4);
|
||||
RID pipeline = pipeline_variants->variants[p_render_target_format][variant[primitive->point_count - 1]].get_render_pipeline(RD::INVALID_ID, p_samples);
|
||||
RID pipeline = pipeline_variants->variants[light_mode][variant[primitive->point_count - 1]].get_render_pipeline(RD::INVALID_ID, p_framebuffer_format);
|
||||
RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline);
|
||||
}
|
||||
|
||||
|
@ -1184,7 +1325,6 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count,
|
|||
|
||||
Item *current_clip = NULL;
|
||||
|
||||
RenderTargetFormat render_target_format = RENDER_TARGET_FORMAT_8_BIT_INT;
|
||||
Transform2D canvas_transform_inverse = p_canvas_transform_inverse;
|
||||
|
||||
RID framebuffer = storage->render_target_get_rd_framebuffer(p_to_render_target);
|
||||
|
@ -1197,10 +1337,9 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count,
|
|||
storage->render_target_disable_clear_request(p_to_render_target);
|
||||
}
|
||||
#warning TODO obtain from framebuffer format eventually when this is implemented
|
||||
RD::TextureSamples texture_samples = RD::TEXTURE_SAMPLES_1;
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, clear ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_KEEP_COLOR, RD::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH, clear_colors);
|
||||
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer);
|
||||
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, state.canvas_state_uniform_set, 3);
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, clear ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_KEEP_COLOR, RD::FINAL_ACTION_READ_COLOR_DISCARD_DEPTH, clear_colors);
|
||||
|
||||
for (int i = 0; i < p_item_count; i++) {
|
||||
|
||||
|
@ -1221,104 +1360,18 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count,
|
|||
}
|
||||
}
|
||||
|
||||
if (false) { //not skeleton
|
||||
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, shader.default_skeleton_uniform_set, 1);
|
||||
}
|
||||
|
||||
_render_item(draw_list, ci, render_target_format, texture_samples, canvas_transform_inverse, current_clip, p_lights);
|
||||
_render_item(draw_list, ci, fb_format, canvas_transform_inverse, current_clip, p_lights);
|
||||
}
|
||||
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
||||
void RasterizerCanvasRD::_update_canvas_state_uniform_set() {
|
||||
|
||||
if (state.canvas_state_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(state.canvas_state_uniform_set)) {
|
||||
return; //nothing to update
|
||||
}
|
||||
|
||||
Vector<RD::Uniform> uniforms;
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
||||
u.binding = 0;
|
||||
u.ids.push_back(state.canvas_state_buffer);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
||||
u.binding = 1;
|
||||
u.ids.push_back(state.lights_uniform_buffer);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
RD::Uniform u_lights;
|
||||
u_lights.type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
u_lights.binding = 2;
|
||||
|
||||
RD::Uniform u_shadows;
|
||||
u_shadows.type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
u_shadows.binding = 3;
|
||||
|
||||
//lights
|
||||
for (uint32_t i = 0; i < MAX_LIGHT_TEXTURES; i++) {
|
||||
if (i < canvas_light_owner.get_rid_count()) {
|
||||
CanvasLight *cl = canvas_light_owner.get_rid_by_index(i);
|
||||
cl->texture_index = i;
|
||||
RID rd_texture;
|
||||
|
||||
if (cl->texture.is_valid()) {
|
||||
rd_texture = storage->texture_get_rd_texture(cl->texture);
|
||||
}
|
||||
if (rd_texture.is_valid()) {
|
||||
u_lights.ids.push_back(rd_texture);
|
||||
} else {
|
||||
u_lights.ids.push_back(default_textures.white_texture);
|
||||
}
|
||||
if (cl->shadow.texture.is_valid()) {
|
||||
u_shadows.ids.push_back(cl->shadow.texture);
|
||||
} else {
|
||||
u_shadows.ids.push_back(default_textures.black_texture);
|
||||
}
|
||||
} else {
|
||||
u_lights.ids.push_back(default_textures.white_texture);
|
||||
u_shadows.ids.push_back(default_textures.black_texture);
|
||||
}
|
||||
}
|
||||
|
||||
//in case there are more
|
||||
for (uint32_t i = MAX_LIGHT_TEXTURES; i < canvas_light_owner.get_rid_count(); i++) {
|
||||
CanvasLight *cl = canvas_light_owner.get_rid_by_index(i);
|
||||
cl->texture_index = -1; //make invalid (no texture)
|
||||
}
|
||||
|
||||
uniforms.push_back(u_lights);
|
||||
uniforms.push_back(u_shadows);
|
||||
}
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.type = RD::UNIFORM_TYPE_SAMPLER;
|
||||
u.binding = 4;
|
||||
u.ids.push_back(state.shadow_sampler);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
state.canvas_state_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader, 3); // uses index 3
|
||||
}
|
||||
|
||||
void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform) {
|
||||
|
||||
int item_count = 0;
|
||||
|
||||
//setup canvas state uniforms if needed
|
||||
_update_canvas_state_uniform_set();
|
||||
|
||||
Transform2D canvas_transform_inverse = p_canvas_transform.affine_inverse();
|
||||
|
||||
{
|
||||
|
@ -1356,14 +1409,14 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
|
|||
|
||||
while (l) {
|
||||
|
||||
if (index == MAX_RENDER_LIGHTS) {
|
||||
if (index == state.max_lights_per_render) {
|
||||
l->render_index_cache = -1;
|
||||
l = l->next_ptr;
|
||||
continue;
|
||||
}
|
||||
|
||||
CanvasLight *clight = canvas_light_owner.getornull(l->light_internal);
|
||||
if (!clight || clight->texture_index < 0) { //unused or invalid texture
|
||||
if (!clight) { //unused or invalid texture
|
||||
l->render_index_cache = -1;
|
||||
l = l->next_ptr;
|
||||
ERR_CONTINUE(!clight);
|
||||
|
@ -1390,7 +1443,7 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
|
|||
} else {
|
||||
state.light_uniforms[index].shadow_pixel_size = 1.0;
|
||||
}
|
||||
state.light_uniforms[index].flags = clight->texture_index;
|
||||
|
||||
state.light_uniforms[index].flags |= l->mode << LIGHT_FLAGS_BLEND_SHIFT;
|
||||
state.light_uniforms[index].flags |= l->shadow_filter << LIGHT_FLAGS_FILTER_SHIFT;
|
||||
if (clight->shadow.texture.is_valid()) {
|
||||
|
@ -1439,7 +1492,6 @@ RID RasterizerCanvasRD::light_create() {
|
|||
|
||||
CanvasLight canvas_light;
|
||||
canvas_light.shadow.size = 0;
|
||||
canvas_light.texture_index = -1;
|
||||
return canvas_light_owner.make_rid(canvas_light);
|
||||
}
|
||||
|
||||
|
@ -1451,11 +1503,6 @@ void RasterizerCanvasRD::light_set_texture(RID p_rid, RID p_texture) {
|
|||
}
|
||||
|
||||
cl->texture = p_texture;
|
||||
|
||||
//canvas state uniform set needs updating
|
||||
if (state.canvas_state_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(state.canvas_state_uniform_set)) {
|
||||
RD::get_singleton()->free(state.canvas_state_uniform_set);
|
||||
}
|
||||
}
|
||||
void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable, int p_resolution) {
|
||||
CanvasLight *cl = canvas_light_owner.getornull(p_rid);
|
||||
|
@ -1506,11 +1553,6 @@ void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable, int p_re
|
|||
}
|
||||
|
||||
cl->shadow.size = p_resolution;
|
||||
|
||||
//canvas state uniform set needs updating
|
||||
if (state.canvas_state_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(state.canvas_state_uniform_set)) {
|
||||
RD::get_singleton()->free(state.canvas_state_uniform_set);
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerCanvasRD::light_update_shadow(RID p_rid, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) {
|
||||
|
@ -1831,35 +1873,58 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
|
|||
}
|
||||
|
||||
{ //shader variants
|
||||
|
||||
uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
|
||||
|
||||
String global_defines;
|
||||
if (textures_per_stage <= 16) {
|
||||
//ARM pretty much, and very old Intel GPUs under Linux
|
||||
state.max_lights_per_item = 4; //sad
|
||||
global_defines += "#define MAX_LIGHT_TEXTURES 4\n";
|
||||
} else if (textures_per_stage <= 32) {
|
||||
//Apple (Metal)
|
||||
state.max_lights_per_item = 8; //sad
|
||||
global_defines += "#define MAX_LIGHT_TEXTURES 8\n";
|
||||
} else {
|
||||
//Anything else (16 lights per item)
|
||||
state.max_lights_per_item = DEFAULT_MAX_LIGHTS_PER_ITEM;
|
||||
global_defines += "#define MAX_LIGHT_TEXTURES " + itos(DEFAULT_MAX_LIGHTS_PER_ITEM) + "\n";
|
||||
}
|
||||
|
||||
uint32_t uniform_max_size = RD::get_singleton()->limit_get(RD::LIMIT_MAX_UNIFORM_BUFFER_SIZE);
|
||||
if (uniform_max_size < 65536) {
|
||||
//Yes, you guessed right, ARM again
|
||||
state.max_lights_per_render = 64;
|
||||
global_defines += "#define MAX_LIGHTS 64\n";
|
||||
} else {
|
||||
state.max_lights_per_render = DEFAULT_MAX_LIGHTS_PER_RENDER;
|
||||
global_defines += "#define MAX_LIGHTS " + itos(DEFAULT_MAX_LIGHTS_PER_RENDER) + "\n";
|
||||
}
|
||||
|
||||
state.light_uniforms = memnew_arr(LightUniform, state.max_lights_per_render);
|
||||
Vector<String> variants;
|
||||
//non light variants
|
||||
variants.push_back(""); //none by default is first variant
|
||||
variants.push_back("#define USE_NINEPATCH\n"); //ninepatch is the second variant
|
||||
variants.push_back("#define USE_PRIMITIVE\n"); //primitve is the third
|
||||
variants.push_back("#define USE_PRIMITIVE\n#define USE_POINT_SIZE\n"); //points need point size
|
||||
variants.push_back("#define USE_ATTRIBUTES\n"); // attributes for vertex arrays
|
||||
variants.push_back("#define USE_ATTRIBUTES\n#define USE_POINT_SIZE\n"); //attributes with point size
|
||||
shader.canvas_shader.initialize(variants);
|
||||
//light variants
|
||||
variants.push_back("#define USE_LIGHTING\n"); //none by default is first variant
|
||||
variants.push_back("#define USE_LIGHTING\n#define USE_NINEPATCH\n"); //ninepatch is the second variant
|
||||
variants.push_back("#define USE_LIGHTING\n#define USE_PRIMITIVE\n"); //primitve is the third
|
||||
variants.push_back("#define USE_LIGHTING\n#define USE_PRIMITIVE\n#define USE_POINT_SIZE\n"); //points need point size
|
||||
variants.push_back("#define USE_LIGHTING\n#define USE_ATTRIBUTES\n"); // attributes for vertex arrays
|
||||
variants.push_back("#define USE_LIGHTING\n#define USE_ATTRIBUTES\n#define USE_POINT_SIZE\n"); //attributes with point size
|
||||
|
||||
shader.canvas_shader.initialize(variants, global_defines);
|
||||
|
||||
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);
|
||||
|
||||
{
|
||||
//framebuffer formats
|
||||
RD::AttachmentFormat af;
|
||||
af.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
|
||||
af.samples = RD::TEXTURE_SAMPLES_1;
|
||||
af.usage_flags = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_RETRIEVE_BIT;
|
||||
Vector<RD::AttachmentFormat> formats;
|
||||
formats.push_back(af);
|
||||
shader.framebuffer_formats[RENDER_TARGET_FORMAT_8_BIT_INT] = RD::get_singleton()->framebuffer_format_create(formats);
|
||||
|
||||
formats.clear();
|
||||
af.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
|
||||
formats.push_back(af);
|
||||
shader.framebuffer_formats[RENDER_TARGET_FORMAT_16_BIT_FLOAT] = RD::get_singleton()->framebuffer_format_create(formats);
|
||||
}
|
||||
|
||||
for (int i = 0; i < RENDER_TARGET_FORMAT_MAX; i++) {
|
||||
RD::FramebufferFormatID fb_format = shader.framebuffer_formats[i];
|
||||
for (int i = 0; i < PIPELINE_LIGHT_MODE_MAX; i++) {
|
||||
for (int j = 0; j < PIPELINE_VARIANT_MAX; j++) {
|
||||
RD::RenderPrimitive primitive[PIPELINE_VARIANT_MAX] = {
|
||||
RD::RENDER_PRIMITIVE_TRIANGLES,
|
||||
|
@ -1871,23 +1936,31 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
|
|||
RD::RENDER_PRIMITIVE_LINES,
|
||||
RD::RENDER_PRIMITIVE_POINTS,
|
||||
};
|
||||
ShaderVariant shader_variants[PIPELINE_VARIANT_MAX] = {
|
||||
SHADER_VARIANT_QUAD,
|
||||
SHADER_VARIANT_NINEPATCH,
|
||||
SHADER_VARIANT_PRIMITIVE,
|
||||
SHADER_VARIANT_PRIMITIVE,
|
||||
SHADER_VARIANT_PRIMITIVE_POINTS,
|
||||
SHADER_VARIANT_ATTRIBUTES,
|
||||
SHADER_VARIANT_ATTRIBUTES,
|
||||
SHADER_VARIANT_ATTRIBUTES_POINTS
|
||||
ShaderVariant shader_variants[PIPELINE_LIGHT_MODE_MAX][PIPELINE_VARIANT_MAX] = {
|
||||
{ //non lit
|
||||
SHADER_VARIANT_QUAD,
|
||||
SHADER_VARIANT_NINEPATCH,
|
||||
SHADER_VARIANT_PRIMITIVE,
|
||||
SHADER_VARIANT_PRIMITIVE,
|
||||
SHADER_VARIANT_PRIMITIVE_POINTS,
|
||||
SHADER_VARIANT_ATTRIBUTES,
|
||||
SHADER_VARIANT_ATTRIBUTES,
|
||||
SHADER_VARIANT_ATTRIBUTES_POINTS },
|
||||
{ //lit
|
||||
SHADER_VARIANT_QUAD_LIGHT,
|
||||
SHADER_VARIANT_NINEPATCH_LIGHT,
|
||||
SHADER_VARIANT_PRIMITIVE_LIGHT,
|
||||
SHADER_VARIANT_PRIMITIVE_LIGHT,
|
||||
SHADER_VARIANT_PRIMITIVE_POINTS_LIGHT,
|
||||
SHADER_VARIANT_ATTRIBUTES_LIGHT,
|
||||
SHADER_VARIANT_ATTRIBUTES_LIGHT,
|
||||
SHADER_VARIANT_ATTRIBUTES_POINTS_LIGHT },
|
||||
};
|
||||
|
||||
RID shader_variant = shader.canvas_shader.version_get_shader(shader.default_version, shader_variants[j]);
|
||||
shader.pipeline_variants.variants[i][j].setup(shader_variant, fb_format, primitive[j], RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_blend(), 0);
|
||||
RID shader_variant = shader.canvas_shader.version_get_shader(shader.default_version, shader_variants[i][j]);
|
||||
shader.pipeline_variants.variants[i][j].setup(shader_variant, primitive[j], RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_blend(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
shader.default_version_rd_shader = shader.canvas_shader.version_get_shader(shader.default_version, 0);
|
||||
}
|
||||
|
||||
{ //shadow rendering
|
||||
|
@ -1901,6 +1974,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
|
|||
RD::AttachmentFormat af_color;
|
||||
af_color.format = RD::DATA_FORMAT_R32_SFLOAT;
|
||||
af_color.usage_flags = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
af_color.samples = RenderingDevice::TEXTURE_SAMPLES_64;
|
||||
|
||||
attachments.push_back(af_color);
|
||||
|
||||
|
@ -1908,6 +1982,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
|
|||
af_depth.format = RD::DATA_FORMAT_D24_UNORM_S8_UINT;
|
||||
af_depth.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_X8_D24_UNORM_PACK32, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_X8_D24_UNORM_PACK32 : RD::DATA_FORMAT_D32_SFLOAT;
|
||||
af_depth.usage_flags = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
af_depth.samples = RenderingDevice::TEXTURE_SAMPLES_64;
|
||||
|
||||
attachments.push_back(af_depth);
|
||||
|
||||
|
@ -1944,7 +2019,7 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
|
|||
|
||||
{ //state allocate
|
||||
state.canvas_state_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(State::Buffer));
|
||||
state.lights_uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(LightUniform) * MAX_RENDER_LIGHTS);
|
||||
state.lights_uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(LightUniform) * state.max_lights_per_render);
|
||||
|
||||
RD::SamplerState shadow_sampler_state;
|
||||
shadow_sampler_state.mag_filter = RD::SAMPLER_FILTER_LINEAR;
|
||||
|
@ -1956,6 +2031,60 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
|
|||
}
|
||||
|
||||
{
|
||||
{
|
||||
PoolVector<uint8_t> colors;
|
||||
colors.resize(sizeof(float) * 4);
|
||||
{
|
||||
PoolVector<uint8_t>::Write w = colors.write();
|
||||
float *fptr = (float *)w.ptr();
|
||||
fptr[0] = 1.0;
|
||||
fptr[1] = 1.0;
|
||||
fptr[2] = 1.0;
|
||||
fptr[3] = 1.0;
|
||||
}
|
||||
polygon_buffers.default_color_buffer = RD::get_singleton()->vertex_buffer_create(colors.size(), colors);
|
||||
}
|
||||
|
||||
{
|
||||
PoolVector<uint8_t> uvs;
|
||||
uvs.resize(sizeof(float) * 2);
|
||||
{
|
||||
PoolVector<uint8_t>::Write w = uvs.write();
|
||||
float *fptr = (float *)w.ptr();
|
||||
fptr[0] = 0.0;
|
||||
fptr[1] = 0.0;
|
||||
}
|
||||
polygon_buffers.default_uv_buffer = RD::get_singleton()->vertex_buffer_create(uvs.size(), uvs);
|
||||
}
|
||||
|
||||
{
|
||||
PoolVector<uint8_t> bones;
|
||||
bones.resize(sizeof(uint32_t) * 4);
|
||||
{
|
||||
PoolVector<uint8_t>::Write w = bones.write();
|
||||
uint32_t *iptr = (uint32_t *)w.ptr();
|
||||
iptr[0] = 0;
|
||||
iptr[1] = 0;
|
||||
iptr[2] = 0;
|
||||
iptr[3] = 0;
|
||||
}
|
||||
polygon_buffers.default_bone_buffer = RD::get_singleton()->vertex_buffer_create(bones.size(), bones);
|
||||
}
|
||||
|
||||
{
|
||||
PoolVector<uint8_t> weights;
|
||||
weights.resize(sizeof(float) * 4);
|
||||
{
|
||||
PoolVector<uint8_t>::Write w = weights.write();
|
||||
float *fptr = (float *)w.ptr();
|
||||
fptr[0] = 0.0;
|
||||
fptr[1] = 0.0;
|
||||
fptr[2] = 0.0;
|
||||
fptr[3] = 0.0;
|
||||
}
|
||||
polygon_buffers.default_weight_buffer = RD::get_singleton()->vertex_buffer_create(weights.size(), weights);
|
||||
}
|
||||
|
||||
//polygon buffers
|
||||
polygon_buffers.last_id = 1;
|
||||
}
|
||||
|
@ -1987,28 +2116,13 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
|
|||
|
||||
{ //default skeleton buffer
|
||||
|
||||
shader.default_skeleton_uniform = RD::get_singleton()->uniform_buffer_create(sizeof(SkeletonUniform));
|
||||
shader.default_skeleton_uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SkeletonUniform));
|
||||
SkeletonUniform su;
|
||||
_update_transform_2d_to_mat4(Transform2D(), su.skeleton_inverse);
|
||||
_update_transform_2d_to_mat4(Transform2D(), su.skeleton_transform);
|
||||
RD::get_singleton()->buffer_update(shader.default_skeleton_uniform, 0, sizeof(SkeletonUniform), &su);
|
||||
}
|
||||
RD::get_singleton()->buffer_update(shader.default_skeleton_uniform_buffer, 0, sizeof(SkeletonUniform), &su);
|
||||
|
||||
{ //default material uniform set
|
||||
Vector<RD::Uniform> default_material_uniforms;
|
||||
RD::Uniform u;
|
||||
u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
||||
u.binding = 2;
|
||||
u.ids.push_back(shader.default_skeleton_uniform);
|
||||
default_material_uniforms.push_back(u);
|
||||
|
||||
u.ids.clear();
|
||||
u.type = RD::UNIFORM_TYPE_TEXTURE_BUFFER;
|
||||
u.binding = 1;
|
||||
u.ids.push_back(default_textures.default_multimesh_tb);
|
||||
default_material_uniforms.push_back(u);
|
||||
|
||||
shader.default_skeleton_uniform_set = RD::get_singleton()->uniform_set_create(default_material_uniforms, shader.canvas_shader.version_get_shader(shader.default_version, SHADER_VARIANT_ATTRIBUTES), 2);
|
||||
shader.default_skeleton_texture_buffer = RD::get_singleton()->texture_buffer_create(32, RD::DATA_FORMAT_R32G32B32A32_SFLOAT);
|
||||
}
|
||||
|
||||
ERR_FAIL_COND(sizeof(PushConstant) != 128);
|
||||
|
@ -2021,10 +2135,6 @@ bool RasterizerCanvasRD::free(RID p_rid) {
|
|||
ERR_FAIL_COND_V(!cl, false);
|
||||
light_set_use_shadow(p_rid, false, 64);
|
||||
canvas_light_owner.free(p_rid);
|
||||
//canvas state uniform set needs updating
|
||||
if (state.canvas_state_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(state.canvas_state_uniform_set)) {
|
||||
RD::get_singleton()->free(state.canvas_state_uniform_set);
|
||||
}
|
||||
} else if (occluder_polygon_owner.owns(p_rid)) {
|
||||
occluder_polygon_set_shape_as_lines(p_rid, PoolVector<Vector2>());
|
||||
occluder_polygon_owner.free(p_rid);
|
||||
|
@ -2043,10 +2153,6 @@ RasterizerCanvasRD::~RasterizerCanvasRD() {
|
|||
RD::get_singleton()->free(state.canvas_state_buffer);
|
||||
}
|
||||
|
||||
if (state.canvas_state_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(state.canvas_state_uniform_set)) {
|
||||
RD::get_singleton()->free(state.canvas_state_uniform_set);
|
||||
}
|
||||
|
||||
//bindings
|
||||
{
|
||||
|
||||
|
@ -2070,8 +2176,6 @@ RasterizerCanvasRD::~RasterizerCanvasRD() {
|
|||
|
||||
//shaders
|
||||
|
||||
RD::get_singleton()->free(shader.default_skeleton_uniform_set);
|
||||
RD::get_singleton()->free(shader.default_skeleton_uniform);
|
||||
shader.canvas_shader.version_free(shader.default_version);
|
||||
|
||||
//buffers
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "servers/visual/rasterizer/render_pipeline_vertex_format_cache_rd.h"
|
||||
#include "servers/visual/rasterizer/shaders/canvas.glsl.gen.h"
|
||||
#include "servers/visual/rasterizer/shaders/canvas_occlusion.glsl.gen.h"
|
||||
#include "servers/visual/rasterizer/shaders/canvas_occlusion_fix.glsl.gen.h"
|
||||
#include "servers/visual/rendering_device.h"
|
||||
|
||||
class RasterizerCanvasRD : public RasterizerCanvas {
|
||||
|
@ -20,15 +19,15 @@ class RasterizerCanvasRD : public RasterizerCanvas {
|
|||
SHADER_VARIANT_PRIMITIVE_POINTS,
|
||||
SHADER_VARIANT_ATTRIBUTES,
|
||||
SHADER_VARIANT_ATTRIBUTES_POINTS,
|
||||
SHADER_VARIANT_QUAD_LIGHT,
|
||||
SHADER_VARIANT_NINEPATCH_LIGHT,
|
||||
SHADER_VARIANT_PRIMITIVE_LIGHT,
|
||||
SHADER_VARIANT_PRIMITIVE_POINTS_LIGHT,
|
||||
SHADER_VARIANT_ATTRIBUTES_LIGHT,
|
||||
SHADER_VARIANT_ATTRIBUTES_POINTS_LIGHT,
|
||||
SHADER_VARIANT_MAX
|
||||
};
|
||||
|
||||
enum RenderTargetFormat {
|
||||
RENDER_TARGET_FORMAT_8_BIT_INT,
|
||||
RENDER_TARGET_FORMAT_16_BIT_FLOAT,
|
||||
RENDER_TARGET_FORMAT_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
FLAGS_INSTANCING_STRIDE_MASK = 0xF,
|
||||
FLAGS_INSTANCING_ENABLED = (1 << 4),
|
||||
|
@ -71,8 +70,8 @@ class RasterizerCanvasRD : public RasterizerCanvas {
|
|||
enum {
|
||||
MAX_RENDER_ITEMS = 256 * 1024,
|
||||
MAX_LIGHT_TEXTURES = 1024,
|
||||
MAX_LIGHTS_PER_ITEM = 16,
|
||||
MAX_RENDER_LIGHTS = 256
|
||||
DEFAULT_MAX_LIGHTS_PER_ITEM = 16,
|
||||
DEFAULT_MAX_LIGHTS_PER_RENDER = 256
|
||||
};
|
||||
|
||||
/****************/
|
||||
|
@ -90,22 +89,28 @@ class RasterizerCanvasRD : public RasterizerCanvas {
|
|||
PIPELINE_VARIANT_ATTRIBUTE_POINTS,
|
||||
PIPELINE_VARIANT_MAX
|
||||
};
|
||||
enum PipelineLightMode {
|
||||
PIPELINE_LIGHT_MODE_DISABLED,
|
||||
PIPELINE_LIGHT_MODE_ENABLED,
|
||||
PIPELINE_LIGHT_MODE_MAX
|
||||
};
|
||||
|
||||
struct PipelineVariants {
|
||||
RenderPipelineVertexFormatCacheRD variants[RENDER_TARGET_FORMAT_MAX][PIPELINE_VARIANT_MAX];
|
||||
RenderPipelineVertexFormatCacheRD variants[PIPELINE_LIGHT_MODE_MAX][PIPELINE_VARIANT_MAX];
|
||||
};
|
||||
|
||||
struct {
|
||||
CanvasShaderRD canvas_shader;
|
||||
RD::FramebufferFormatID framebuffer_formats[RENDER_TARGET_FORMAT_MAX];
|
||||
RID default_version;
|
||||
RID default_version_rd_shader;
|
||||
RID default_version_rd_shader_light;
|
||||
RID quad_index_buffer;
|
||||
RID quad_index_array;
|
||||
PipelineVariants pipeline_variants;
|
||||
|
||||
// default_skeleton uniform set
|
||||
RID default_skeleton_uniform;
|
||||
RID default_skeleton_uniform_set;
|
||||
RID default_skeleton_uniform_buffer;
|
||||
RID default_skeleton_texture_buffer;
|
||||
|
||||
} shader;
|
||||
|
||||
|
@ -194,6 +199,10 @@ class RasterizerCanvasRD : public RasterizerCanvas {
|
|||
struct {
|
||||
HashMap<PolygonID, PolygonBuffers> polygons;
|
||||
PolygonID last_id;
|
||||
RID default_color_buffer;
|
||||
RID default_uv_buffer;
|
||||
RID default_bone_buffer;
|
||||
RID default_weight_buffer;
|
||||
} polygon_buffers;
|
||||
|
||||
/********************/
|
||||
|
@ -214,7 +223,6 @@ class RasterizerCanvasRD : public RasterizerCanvas {
|
|||
|
||||
struct CanvasLight {
|
||||
|
||||
int32_t texture_index;
|
||||
RID texture;
|
||||
struct {
|
||||
int size;
|
||||
|
@ -256,9 +264,8 @@ class RasterizerCanvasRD : public RasterizerCanvas {
|
|||
float position[2];
|
||||
uint32_t flags; //index to light texture
|
||||
float height;
|
||||
float shadow_softness;
|
||||
float shadow_pixel_size;
|
||||
float pad[2];
|
||||
float pad[3];
|
||||
};
|
||||
|
||||
RID_Owner<OccluderPolygon> occluder_polygon_owner;
|
||||
|
@ -277,6 +284,36 @@ class RasterizerCanvasRD : public RasterizerCanvas {
|
|||
|
||||
//state that does not vary across rendering all items
|
||||
|
||||
struct ItemStateData : public Item::CustomData {
|
||||
|
||||
struct LightCache {
|
||||
uint64_t light_version;
|
||||
Light *light;
|
||||
};
|
||||
|
||||
LightCache light_cache[DEFAULT_MAX_LIGHTS_PER_ITEM];
|
||||
uint32_t light_cache_count;
|
||||
RID light_uniform_set;
|
||||
RID state_uniform_set;
|
||||
ItemStateData() {
|
||||
|
||||
for (int i = 0; i < DEFAULT_MAX_LIGHTS_PER_ITEM; i++) {
|
||||
light_cache[i].light_version = 0;
|
||||
light_cache[i].light = NULL;
|
||||
}
|
||||
light_cache_count = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
~ItemStateData() {
|
||||
if (light_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(light_uniform_set)) {
|
||||
RD::get_singleton()->free(light_uniform_set);
|
||||
}
|
||||
if (state_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(state_uniform_set)) {
|
||||
RD::get_singleton()->free(state_uniform_set);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct State {
|
||||
|
||||
//state buffer
|
||||
|
@ -289,14 +326,14 @@ class RasterizerCanvasRD : public RasterizerCanvas {
|
|||
//uint32_t pad[3];
|
||||
};
|
||||
|
||||
LightUniform light_uniforms[MAX_RENDER_LIGHTS];
|
||||
LightUniform *light_uniforms;
|
||||
|
||||
RID lights_uniform_buffer;
|
||||
RID canvas_state_buffer;
|
||||
RID shadow_sampler;
|
||||
|
||||
//uniform set for all the above
|
||||
RID canvas_state_uniform_set;
|
||||
uint32_t max_lights_per_render;
|
||||
uint32_t max_lights_per_item;
|
||||
} state;
|
||||
|
||||
struct PushConstant {
|
||||
|
@ -331,7 +368,7 @@ class RasterizerCanvasRD : public RasterizerCanvas {
|
|||
Item *items[MAX_RENDER_ITEMS];
|
||||
|
||||
Size2i _bind_texture_binding(TextureBindingID p_binding, RenderingDevice::DrawListID p_draw_list, uint32_t &flags);
|
||||
void _render_item(RenderingDevice::DrawListID p_draw_list, const Item *p_item, RenderTargetFormat p_render_target_format, RenderingDevice::TextureSamples p_samples, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights);
|
||||
void _render_item(RenderingDevice::DrawListID p_draw_list, const Item *p_item, RenderingDevice::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights);
|
||||
void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights);
|
||||
|
||||
_FORCE_INLINE_ void _update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4);
|
||||
|
@ -342,8 +379,6 @@ class RasterizerCanvasRD : public RasterizerCanvas {
|
|||
|
||||
_FORCE_INLINE_ void _update_specular_shininess(const Color &p_transform, uint32_t *r_ss);
|
||||
|
||||
void _update_canvas_state_uniform_set();
|
||||
|
||||
public:
|
||||
TextureBindingID request_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, VS::CanvasItemTextureFilter p_filter, VS::CanvasItemTextureRepeat p_repeat, RID p_multimesh);
|
||||
void free_texture_binding(TextureBindingID p_binding);
|
||||
|
|
|
@ -1,43 +1,39 @@
|
|||
#include "render_pipeline_vertex_format_cache_rd.h"
|
||||
#include "core/os/memory.h"
|
||||
|
||||
RID RenderPipelineVertexFormatCacheRD::_generate_version(RD::VertexFormatID p_format_id, RenderingDevice::TextureSamples p_samples) {
|
||||
RID RenderPipelineVertexFormatCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id) {
|
||||
|
||||
RD::PipelineMultisampleState multisample_state_version;
|
||||
if (p_samples != RD::TEXTURE_SAMPLES_1) {
|
||||
multisample_state_version = multisample_state;
|
||||
multisample_state_version.sample_count = p_samples;
|
||||
}
|
||||
RID pipeline = RD::get_singleton()->render_pipeline_create(shader, framebuffer_format, p_format_id, render_primitive, rasterization_state, multisample_state, depth_stencil_state, blend_state, dynamic_state_flags);
|
||||
RD::PipelineMultisampleState multisample_state_version = multisample_state;
|
||||
multisample_state_version.sample_count = RD::get_singleton()->framebuffer_format_get_texture_samples(p_framebuffer_format_id);
|
||||
|
||||
RID pipeline = RD::get_singleton()->render_pipeline_create(shader, p_framebuffer_format_id, p_vertex_format_id, render_primitive, rasterization_state, multisample_state_version, depth_stencil_state, blend_state, dynamic_state_flags);
|
||||
ERR_FAIL_COND_V(pipeline.is_null(), RID());
|
||||
versions[p_samples] = (Version *)memrealloc(versions[p_samples], sizeof(Version) * (version_count[p_samples] + 1));
|
||||
versions[p_samples][version_count[p_samples]].format_id = p_format_id;
|
||||
versions[p_samples][version_count[p_samples]].pipeline = pipeline;
|
||||
version_count[p_samples]++;
|
||||
versions = (Version *)memrealloc(versions, sizeof(Version) * (version_count + 1));
|
||||
versions[version_count].framebuffer_id = p_framebuffer_format_id;
|
||||
versions[version_count].vertex_id= p_vertex_format_id;
|
||||
versions[version_count].pipeline = pipeline;
|
||||
version_count++;
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
void RenderPipelineVertexFormatCacheRD::_clear() {
|
||||
|
||||
for (int v = 0; v < RD::TEXTURE_SAMPLES_MAX; v++) {
|
||||
if (versions[v]) {
|
||||
for (uint32_t i = 0; i < version_count[v]; i++) {
|
||||
//shader may be gone, so this may not be valid
|
||||
if (RD::get_singleton()->render_pipeline_is_valid(versions[v][i].pipeline)) {
|
||||
RD::get_singleton()->free(versions[v][i].pipeline);
|
||||
}
|
||||
if (versions) {
|
||||
for (uint32_t i = 0; i < version_count; i++) {
|
||||
//shader may be gone, so this may not be valid
|
||||
if (RD::get_singleton()->render_pipeline_is_valid(versions[i].pipeline)) {
|
||||
RD::get_singleton()->free(versions[i].pipeline);
|
||||
}
|
||||
version_count[v] = 0;
|
||||
memfree(versions[v]);
|
||||
versions[v] = NULL;
|
||||
}
|
||||
version_count = 0;
|
||||
memfree(versions);
|
||||
versions = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPipelineVertexFormatCacheRD::setup(RID p_shader, RD::FramebufferFormatID p_framebuffer_format, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags) {
|
||||
void RenderPipelineVertexFormatCacheRD::setup(RID p_shader, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags) {
|
||||
ERR_FAIL_COND(p_shader.is_null());
|
||||
shader = p_shader;
|
||||
framebuffer_format = p_framebuffer_format;
|
||||
render_primitive = p_primitive;
|
||||
rasterization_state = p_rasterization_state;
|
||||
multisample_state = p_multisample;
|
||||
|
@ -49,14 +45,12 @@ void RenderPipelineVertexFormatCacheRD::setup(RID p_shader, RD::FramebufferForma
|
|||
void RenderPipelineVertexFormatCacheRD::update_shader(RID p_shader) {
|
||||
ERR_FAIL_COND(p_shader.is_null());
|
||||
_clear();
|
||||
setup(p_shader, framebuffer_format, render_primitive, rasterization_state, multisample_state, depth_stencil_state, blend_state, dynamic_state_flags);
|
||||
setup(p_shader, render_primitive, rasterization_state, multisample_state, depth_stencil_state, blend_state, dynamic_state_flags);
|
||||
}
|
||||
|
||||
RenderPipelineVertexFormatCacheRD::RenderPipelineVertexFormatCacheRD() {
|
||||
for (int i = 0; i < RD::TEXTURE_SAMPLES_MAX; i++) {
|
||||
version_count[i] = 0;
|
||||
versions[i] = NULL;
|
||||
}
|
||||
version_count = 0;
|
||||
versions = NULL;
|
||||
}
|
||||
|
||||
RenderPipelineVertexFormatCacheRD::~RenderPipelineVertexFormatCacheRD() {
|
||||
|
|
|
@ -16,29 +16,29 @@ class RenderPipelineVertexFormatCacheRD {
|
|||
int dynamic_state_flags;
|
||||
|
||||
struct Version {
|
||||
RD::VertexFormatID format_id;
|
||||
RD::VertexFormatID vertex_id;
|
||||
RD::FramebufferFormatID framebuffer_id;
|
||||
RID pipeline;
|
||||
};
|
||||
|
||||
Version *versions[RD::TEXTURE_SAMPLES_MAX];
|
||||
uint32_t version_count[RD::TEXTURE_SAMPLES_MAX];
|
||||
Version *versions;
|
||||
uint32_t version_count;
|
||||
|
||||
RID _generate_version(RD::VertexFormatID p_format_id, RD::TextureSamples p_samples);
|
||||
RID _generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id);
|
||||
|
||||
void _clear();
|
||||
|
||||
public:
|
||||
void setup(RID p_shader, RD::FramebufferFormatID p_framebuffer_format, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0);
|
||||
void setup(RID p_shader, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0);
|
||||
void update_shader(RID p_shader);
|
||||
|
||||
_FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_format_id, RD::TextureSamples p_samples) {
|
||||
ERR_FAIL_INDEX_V(p_samples, RD::TEXTURE_SAMPLES_MAX, RID());
|
||||
for (uint32_t i = 0; i < version_count[p_samples]; i++) {
|
||||
if (versions[p_samples][i].format_id == p_format_id) {
|
||||
return versions[p_samples][i].pipeline;
|
||||
_FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id) {
|
||||
for (uint32_t i = 0; i < version_count; i++) {
|
||||
if (versions[i].vertex_id == p_vertex_format_id && versions[i].framebuffer_id == p_framebuffer_format_id) {
|
||||
return versions[i].pipeline;
|
||||
}
|
||||
}
|
||||
return _generate_version(p_format_id, p_samples);
|
||||
return _generate_version(p_vertex_format_id, p_framebuffer_format_id);
|
||||
}
|
||||
|
||||
RenderPipelineVertexFormatCacheRD();
|
||||
|
|
|
@ -180,7 +180,9 @@ void ShaderRD::_compile_version(Version *p_version) {
|
|||
|
||||
builder.append(vertex_codev.get_data()); // version info (if exists)
|
||||
builder.append("\n"); //make sure defines begin at newline
|
||||
builder.append(general_defines.get_data());
|
||||
builder.append(variant_defines[i].get_data());
|
||||
|
||||
for (int j = 0; j < p_version->custom_defines.size(); j++) {
|
||||
builder.append(p_version->custom_defines[j].get_data());
|
||||
}
|
||||
|
@ -214,6 +216,7 @@ void ShaderRD::_compile_version(Version *p_version) {
|
|||
builder.append(fragment_codev.get_data()); // version info (if exists)
|
||||
builder.append("\n"); //make sure defines begin at newline
|
||||
|
||||
builder.append(general_defines.get_data());
|
||||
builder.append(variant_defines[i].get_data());
|
||||
for (int j = 0; j < p_version->custom_defines.size(); j++) {
|
||||
builder.append(p_version->custom_defines[j].get_data());
|
||||
|
@ -307,9 +310,10 @@ bool ShaderRD::version_free(RID p_version) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void ShaderRD::initialize(const Vector<String> &p_variant_defines) {
|
||||
void ShaderRD::initialize(const Vector<String> &p_variant_defines, const String &p_general_defines) {
|
||||
ERR_FAIL_COND(variant_defines.size());
|
||||
ERR_FAIL_COND(p_variant_defines.size() == 0);
|
||||
general_defines = p_general_defines.utf8();
|
||||
for (int i = 0; i < p_variant_defines.size(); i++) {
|
||||
|
||||
variant_defines.push_back(p_variant_defines[i].utf8());
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
class ShaderRD {
|
||||
|
||||
//versions
|
||||
CharString general_defines;
|
||||
Vector<CharString> variant_defines;
|
||||
|
||||
int vertex_code_start;
|
||||
|
@ -114,7 +115,7 @@ public:
|
|||
|
||||
bool version_free(RID p_version);
|
||||
|
||||
void initialize(const Vector<String> &p_variant_defines);
|
||||
void initialize(const Vector<String> &p_variant_defines, const String &p_general_defines = "");
|
||||
virtual ~ShaderRD();
|
||||
};
|
||||
|
||||
|
|
|
@ -5,4 +5,3 @@ Import('env')
|
|||
if 'RD_GLSL' in env['BUILDERS']:
|
||||
env.RD_GLSL('canvas.glsl');
|
||||
env.RD_GLSL('canvas_occlusion.glsl');
|
||||
env.RD_GLSL('canvas_occlusion_fix.glsl');
|
||||
|
|
|
@ -426,8 +426,11 @@ FRAGMENT_SHADER_CODE
|
|||
}
|
||||
|
||||
color*=canvas_data.canvas_modulation;
|
||||
|
||||
for(uint i=0;i<light_count;i++) {
|
||||
#ifdef USE_LIGHTING
|
||||
for(uint i=0;i<MAX_LIGHT_TEXTURES;i++) {
|
||||
if (i>=light_count) {
|
||||
break;
|
||||
}
|
||||
uint light_base;
|
||||
if (i<8) {
|
||||
if (i<4) {
|
||||
|
@ -445,16 +448,8 @@ FRAGMENT_SHADER_CODE
|
|||
light_base>>=(i&3)*8;
|
||||
light_base&=0xFF;
|
||||
|
||||
#define LIGHT_FLAGS_BLEND_MASK (3<<16)
|
||||
#define LIGHT_FLAGS_BLEND_MODE_ADD (0<<16)
|
||||
#define LIGHT_FLAGS_BLEND_MODE_SUB (1<<16)
|
||||
#define LIGHT_FLAGS_BLEND_MODE_MIX (2<<16)
|
||||
#define LIGHT_FLAGS_BLEND_MODE_MASK (3<<16)
|
||||
|
||||
|
||||
vec2 tex_uv = (vec4(vertex,0.0,1.0) * mat4(light_array.data[light_base].matrix[0],light_array.data[light_base].matrix[1],vec4(0.0,0.0,1.0,0.0),vec4(0.0,0.0,0.0,1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations.
|
||||
uint texture_idx = light_array.data[light_base].flags&LIGHT_FLAGS_TEXTURE_MASK;
|
||||
vec4 light_color = texture(sampler2D(light_textures[texture_idx],texture_sampler),tex_uv);
|
||||
vec4 light_color = texture(sampler2D(light_textures[i],texture_sampler),tex_uv);
|
||||
vec4 light_base_color = light_array.data[light_base].color;
|
||||
light_color.rgb*=light_base_color.rgb*light_base_color.a;
|
||||
|
||||
|
@ -526,32 +521,32 @@ FRAGMENT_SHADER_CODE
|
|||
vec4 shadow_uv = vec4(tex_ofs,0.0,distance,1.0);
|
||||
|
||||
if (shadow_mode==LIGHT_FLAGS_SHADOW_NEAREST) {
|
||||
shadow = textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv).x;
|
||||
shadow = textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv).x;
|
||||
} else if (shadow_mode==LIGHT_FLAGS_SHADOW_PCF5) {
|
||||
vec4 shadow_pixel_size = vec4(light_array.data[light_base].shadow_pixel_size,0.0,0.0,0.0);
|
||||
shadow = 0.0;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*2.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*2.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*2.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*2.0).x;
|
||||
shadow/=5.0;
|
||||
} else if (shadow_mode==LIGHT_FLAGS_SHADOW_PCF13) {
|
||||
} else { //PCF13
|
||||
vec4 shadow_pixel_size = vec4(light_array.data[light_base].shadow_pixel_size,0.0,0.0,0.0);
|
||||
shadow = 0.0;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*6.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*5.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*4.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*3.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size*2.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv-shadow_pixel_size).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*2.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*3.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*4.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*5.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[texture_idx],shadow_sampler),shadow_uv+shadow_pixel_size*6.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*6.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*5.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*4.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*3.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size*2.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv-shadow_pixel_size).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*2.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*3.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*4.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*5.0).x;
|
||||
shadow += textureProj(sampler2DShadow(shadow_textures[i],shadow_sampler),shadow_uv+shadow_pixel_size*6.0).x;
|
||||
shadow/=13.0;
|
||||
}
|
||||
|
||||
|
@ -577,6 +572,7 @@ FRAGMENT_SHADER_CODE
|
|||
} break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
frag_color = color;
|
||||
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
/* clang-format off */
|
||||
[vertex]
|
||||
/* clang-format on */
|
||||
|
||||
#version 450
|
||||
|
||||
layout(location = 0) out highp float u;
|
||||
|
||||
void main() {
|
||||
|
||||
if (gl_VertexIndex==0) {
|
||||
u=0.0;
|
||||
gl_Position=vec4(-1.0,-1.0,0.0,1.0);
|
||||
} else if (gl_VertexIndex==1) {
|
||||
u=0.0;
|
||||
gl_Position=vec4(-1.0,1.0,0.0,1.0);
|
||||
} else if (gl_VertexIndex==2) {
|
||||
u=1.0;
|
||||
gl_Position=vec4(1.0,1.0,0.0,1.0);
|
||||
} else {
|
||||
u=1.0;
|
||||
gl_Position=vec4(1.0,-1.0,0.0,1.0);
|
||||
}
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
[fragment]
|
||||
/* clang-format on */
|
||||
|
||||
#version 450
|
||||
|
||||
#define PI 3.14159265359
|
||||
|
||||
layout(set=0, binding=0) uniform sampler2D textures[4];
|
||||
layout(location = 0) in highp float u;
|
||||
layout(location = 0) out highp float distance;
|
||||
|
||||
layout(push_constant, binding = 0, std430) uniform Constants {
|
||||
mat4 projection;
|
||||
float far;
|
||||
float pad[3];
|
||||
} constants;
|
||||
|
||||
void main() {
|
||||
|
||||
//0-1 in the texture we are writing to represents a circle, 0-2PI)
|
||||
//obtain the quarter circle from the source textures
|
||||
float angle=fract(u+1.0-0.125);
|
||||
|
||||
float depth;
|
||||
#if 0
|
||||
if (angle<0.25) {
|
||||
highp float sub_angle = ((angle/0.25)*2.0-1.0)*(PI/4.0);
|
||||
highp float x=tan(sub_angle)*0.5+0.5;
|
||||
depth=texture(textures[0],vec2(x,0.0)).x;
|
||||
} else if (angle<0.50) {
|
||||
highp float sub_angle = (((angle-0.25)/0.25)*2.0-1.0)*(PI/4.0);
|
||||
highp float x=tan(sub_angle)*0.5+0.5;
|
||||
depth=texture(textures[1],vec2(x,0.0)).x;
|
||||
} else if (angle<0.75) {
|
||||
highp float sub_angle = (((angle-0.5)/0.25)*2.0-1.0)*(PI/4.0);
|
||||
highp float x=tan(sub_angle)*0.5+0.5;
|
||||
depth=texture(textures[2],vec2(x,0.0)).x;
|
||||
} else {
|
||||
highp float sub_angle = (((angle-0.75)/0.25)*2.0-1.0)*(PI/4.0);
|
||||
highp float x=tan(sub_angle)*0.5+0.5;
|
||||
depth=texture(textures[3],vec2(x,0.0)).x;
|
||||
}
|
||||
#else
|
||||
if (angle<0.25) {
|
||||
highp float sub_angle = ((angle/0.25)*2.0-1.0)*(PI/4.0);
|
||||
vec2 pos = vec2(cos(sub_angle),sin(sub_angle))*constants.far;
|
||||
vec4 proj = constants.projection * vec4(pos,0.0,1.0);
|
||||
float coord = (proj.x/proj.w)*0.5+0.5;
|
||||
depth=texture(textures[0],vec2(coord,0.0)).x;
|
||||
} else if (angle<0.50) {
|
||||
highp float sub_angle = (((angle-0.25)/0.25)*2.0-1.0)*(PI/4.0);
|
||||
vec2 pos = vec2(cos(sub_angle),sin(sub_angle))*constants.far;
|
||||
vec4 proj = constants.projection * vec4(pos,0.0,1.0);
|
||||
float coord = (proj.x/proj.w)*0.5+0.5;
|
||||
depth=texture(textures[1],vec2(coord,0.0)).x;
|
||||
} else if (angle<0.75) {
|
||||
highp float sub_angle = (((angle-0.5)/0.25)*2.0-1.0)*(PI/4.0);
|
||||
vec2 pos = vec2(cos(sub_angle),sin(sub_angle))*constants.far;
|
||||
vec4 proj = constants.projection * vec4(pos,0.0,1.0);
|
||||
float coord = (proj.x/proj.w)*0.5+0.5;
|
||||
depth=texture(textures[2],vec2(coord,0.0)).x;
|
||||
} else {
|
||||
highp float sub_angle = (((angle-0.75)/0.25)*2.0-1.0)*(PI/4.0);
|
||||
vec2 pos = vec2(cos(sub_angle),sin(sub_angle))*constants.far;
|
||||
vec4 proj = constants.projection * vec4(pos,0.0,1.0);
|
||||
float coord = (proj.x/proj.w)*0.5+0.5;
|
||||
depth=texture(textures[3],vec2(coord,0.0)).x;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
distance=depth;
|
||||
}
|
|
@ -1,11 +1,8 @@
|
|||
|
||||
/* SET0: Per draw primitive settings */
|
||||
/* SET0: Draw Primitive */
|
||||
|
||||
#define M_PI 3.14159265359
|
||||
|
||||
#define MAX_LIGHT_TEXTURES 1024
|
||||
#define MAX_RENDER_LIGHTS 256
|
||||
|
||||
#define FLAGS_INSTANCING_STRIDE_MASK 0xF
|
||||
#define FLAGS_INSTANCING_ENABLED (1<<4)
|
||||
#define FLAGS_INSTANCING_HAS_COLORS (1 << 5)
|
||||
|
@ -64,22 +61,10 @@ layout(set = 0, binding = 5) uniform textureBuffer instancing_buffer;
|
|||
|
||||
//
|
||||
|
||||
/* SET2: Is the skeleton */
|
||||
/* SET2: Canvas Item State */
|
||||
|
||||
#ifdef USE_ATTRIBUTES
|
||||
|
||||
layout(set = 2, binding = 0) uniform textureBuffer skeleton_buffer;
|
||||
|
||||
layout(set = 2, binding = 1, std140) uniform SkeletonData {
|
||||
mat4 skeleton_transform; //in world coordinates
|
||||
mat4 skeleton_transform_inverse;
|
||||
} skeleton_data;
|
||||
|
||||
#endif
|
||||
|
||||
/* SET3: Per Scene settings */
|
||||
|
||||
layout(set = 3, binding = 0, std140) uniform CanvasData {
|
||||
layout(set = 2, binding = 0, std140) uniform CanvasData {
|
||||
mat4 canvas_transform;
|
||||
mat4 screen_transform;
|
||||
mat4 canvas_normal_transform;
|
||||
|
@ -87,7 +72,19 @@ layout(set = 3, binding = 0, std140) uniform CanvasData {
|
|||
//uint light_count;
|
||||
} canvas_data;
|
||||
|
||||
#define LIGHT_FLAGS_TEXTURE_MASK 0xFFFF
|
||||
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;
|
||||
|
||||
|
||||
|
||||
/* SET3: Lighting */
|
||||
|
||||
#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)
|
||||
|
@ -109,17 +106,19 @@ struct Light {
|
|||
vec2 position;
|
||||
uint flags; //index to light texture
|
||||
float height;
|
||||
float shadow_softness;
|
||||
float shadow_pixel_size;
|
||||
float pad0;
|
||||
float pad1;
|
||||
float pad2;
|
||||
};
|
||||
|
||||
layout(set = 3, binding = 1, std140) uniform LightData {
|
||||
Light data[MAX_RENDER_LIGHTS];
|
||||
layout(set = 3, binding = 0, std140) uniform LightData {
|
||||
Light data[MAX_LIGHTS];
|
||||
} light_array;
|
||||
|
||||
layout(set = 3, binding = 2) uniform texture2D light_textures[MAX_LIGHT_TEXTURES];
|
||||
layout(set = 3, binding = 3) uniform texture2D shadow_textures[MAX_LIGHT_TEXTURES];
|
||||
layout(set = 3, binding = 1) uniform texture2D light_textures[MAX_LIGHT_TEXTURES];
|
||||
layout(set = 3, binding = 2) uniform texture2D shadow_textures[MAX_LIGHT_TEXTURES];
|
||||
|
||||
layout(set = 3, binding = 4) uniform sampler shadow_sampler;
|
||||
layout(set = 3, binding = 3) uniform sampler shadow_sampler;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -334,6 +334,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
struct TextureView {
|
||||
DataFormat format_override;
|
||||
TextureSwizzle swizzle_r;
|
||||
|
@ -352,6 +353,8 @@ public:
|
|||
|
||||
virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<PoolVector<uint8_t> > &p_data = Vector<PoolVector<uint8_t> >()) = 0;
|
||||
virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture) = 0;
|
||||
virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture,int p_layer,int p_mipmap) = 0;
|
||||
|
||||
virtual Error texture_update(RID p_texture, uint32_t p_layer, const PoolVector<uint8_t> &p_data, bool p_sync_with_draw = false) = 0; //this function can be used from any thread and it takes effect at the begining of the frame, unless sync with draw is used, which is used to mix updates with draw calls
|
||||
virtual PoolVector<uint8_t> texture_get_data(RID p_texture, uint32_t p_layer) = 0; // CPU textures will return immediately, while GPU textures will most likely force a flush
|
||||
|
||||
|
@ -373,6 +376,7 @@ public:
|
|||
|
||||
// This ID is warranted to be unique for the same formats, does not need to be freed
|
||||
virtual FramebufferFormatID framebuffer_format_create(const Vector<AttachmentFormat> &p_format) = 0;
|
||||
virtual TextureSamples framebuffer_format_get_texture_samples(FramebufferFormatID p_format) =0;
|
||||
|
||||
virtual RID framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check = INVALID_ID) = 0;
|
||||
|
||||
|
@ -865,12 +869,49 @@ public:
|
|||
|
||||
virtual void draw_list_end() = 0;
|
||||
|
||||
|
||||
/***************/
|
||||
/**** FREE! ****/
|
||||
/***************/
|
||||
|
||||
virtual void free(RID p_id) = 0;
|
||||
|
||||
/****************/
|
||||
/**** LIMITS ****/
|
||||
/****************/
|
||||
|
||||
enum Limit {
|
||||
LIMIT_MAX_BOUND_UNIFORM_SETS,
|
||||
LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS,
|
||||
LIMIT_MAX_TEXTURES_PER_UNIFORM_SET,
|
||||
LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET,
|
||||
LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET,
|
||||
LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET,
|
||||
LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET,
|
||||
LIMIT_MAX_DRAW_INDEXED_INDEX,
|
||||
LIMIT_MAX_FRAMEBUFFER_HEIGHT,
|
||||
LIMIT_MAX_FRAMEBUFFER_WIDTH,
|
||||
LIMIT_MAX_TEXTURE_ARRAY_LAYERS,
|
||||
LIMIT_MAX_TEXTURE_SIZE_1D,
|
||||
LIMIT_MAX_TEXTURE_SIZE_2D,
|
||||
LIMIT_MAX_TEXTURE_SIZE_3D,
|
||||
LIMIT_MAX_TEXTURE_SIZE_CUBE,
|
||||
LIMIT_MAX_TEXTURES_PER_SHADER_STAGE,
|
||||
LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE,
|
||||
LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE,
|
||||
LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE,
|
||||
LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE,
|
||||
LIMIT_MAX_PUSH_CONSTANT_SIZE,
|
||||
LIMIT_MAX_UNIFORM_BUFFER_SIZE,
|
||||
LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET,
|
||||
LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES,
|
||||
LIMIT_MAX_VERTEX_INPUT_BINDINGS,
|
||||
LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE,
|
||||
LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT ,
|
||||
};
|
||||
|
||||
virtual int limit_get(Limit p_limit) =0;
|
||||
|
||||
//methods below not exposed, used by RenderingDeviceRD
|
||||
virtual void prepare_screen_for_drawing() =0;
|
||||
virtual void finalize_frame() = 0;
|
||||
|
|
|
@ -65,14 +65,13 @@ void VisualServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Canvas
|
|||
VSG::canvas_render->canvas_render_items(p_to_render_target, list, p_modulate, p_lights, p_transform);
|
||||
}
|
||||
|
||||
void _collect_ysort_children(VisualServerCanvas::Item *p_canvas_item, Transform2D p_transform, VisualServerCanvas::Item *p_material_owner, const Color p_modulate, VisualServerCanvas::Item **r_items, int &r_index) {
|
||||
void _collect_ysort_children(VisualServerCanvas::Item *p_canvas_item, Transform2D p_transform, VisualServerCanvas::Item *p_material_owner, VisualServerCanvas::Item **r_items, int &r_index) {
|
||||
int child_item_count = p_canvas_item->child_items.size();
|
||||
VisualServerCanvas::Item **child_items = p_canvas_item->child_items.ptrw();
|
||||
for (int i = 0; i < child_item_count; i++) {
|
||||
if (child_items[i]->visible) {
|
||||
if (r_items) {
|
||||
r_items[r_index] = child_items[i];
|
||||
child_items[i]->ysort_modulate = p_modulate;
|
||||
child_items[i]->ysort_xform = p_transform;
|
||||
child_items[i]->ysort_pos = p_transform.xform(child_items[i]->xform.elements[2]);
|
||||
child_items[i]->material_owner = child_items[i]->use_parent_material ? p_material_owner : NULL;
|
||||
|
@ -81,11 +80,7 @@ void _collect_ysort_children(VisualServerCanvas::Item *p_canvas_item, Transform2
|
|||
r_index++;
|
||||
|
||||
if (child_items[i]->sort_y)
|
||||
_collect_ysort_children(child_items[i],
|
||||
p_transform * child_items[i]->xform,
|
||||
child_items[i]->use_parent_material ? p_material_owner : child_items[i],
|
||||
p_modulate * child_items[i]->modulate,
|
||||
r_items, r_index);
|
||||
_collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, child_items[i]->use_parent_material ? p_material_owner : child_items[i], r_items, r_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -146,14 +141,14 @@ void VisualServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transform2
|
|||
|
||||
if (ci->ysort_children_count == -1) {
|
||||
ci->ysort_children_count = 0;
|
||||
_collect_ysort_children(ci, Transform2D(), p_material_owner, Color(1, 1, 1, 1), NULL, ci->ysort_children_count);
|
||||
_collect_ysort_children(ci, Transform2D(), p_material_owner, NULL, ci->ysort_children_count);
|
||||
}
|
||||
|
||||
child_item_count = ci->ysort_children_count;
|
||||
child_items = (Item **)alloca(child_item_count * sizeof(Item *));
|
||||
|
||||
int i = 0;
|
||||
_collect_ysort_children(ci, Transform2D(), p_material_owner, Color(1, 1, 1, 1), child_items, i);
|
||||
_collect_ysort_children(ci, Transform2D(), p_material_owner, child_items, i);
|
||||
|
||||
SortArray<Item *, ItemPtrSort> sorter;
|
||||
sorter.sort(child_items, child_item_count);
|
||||
|
@ -169,7 +164,7 @@ void VisualServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transform2
|
|||
if (!child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y))
|
||||
continue;
|
||||
if (ci->sort_y) {
|
||||
_cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate * child_items[i]->ysort_modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner);
|
||||
_cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner);
|
||||
} else {
|
||||
_cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner);
|
||||
}
|
||||
|
@ -213,7 +208,7 @@ void VisualServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transform2
|
|||
if (child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y))
|
||||
continue;
|
||||
if (ci->sort_y) {
|
||||
_cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate * child_items[i]->ysort_modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner);
|
||||
_cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner);
|
||||
} else {
|
||||
_cull_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner);
|
||||
}
|
||||
|
@ -835,7 +830,7 @@ void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector
|
|||
ERR_FAIL_COND(!p_bones.empty() && p_bones.size() != vertex_count * 4);
|
||||
ERR_FAIL_COND(!p_weights.empty() && p_weights.size() != vertex_count * 4);
|
||||
|
||||
const Vector<int> &indices = p_indices;
|
||||
Vector<int> indices = p_indices;
|
||||
|
||||
Item::CommandPolygon *polygon = canvas_item->alloc_command<Item::CommandPolygon>();
|
||||
ERR_FAIL_COND(!polygon);
|
||||
|
@ -1057,6 +1052,7 @@ void VisualServerCanvas::canvas_light_set_texture(RID p_light, RID p_texture) {
|
|||
ERR_FAIL_COND(!clight);
|
||||
|
||||
clight->texture = p_texture;
|
||||
clight->version++;
|
||||
VSG::canvas_render->light_set_texture(clight->light_internal, p_texture);
|
||||
}
|
||||
void VisualServerCanvas::canvas_light_set_texture_offset(RID p_light, const Vector2 &p_offset) {
|
||||
|
@ -1134,7 +1130,7 @@ void VisualServerCanvas::canvas_light_set_shadow_enabled(RID p_light, bool p_ena
|
|||
return;
|
||||
}
|
||||
clight->use_shadow = p_enabled;
|
||||
|
||||
clight->version++;
|
||||
VSG::canvas_render->light_set_use_shadow(clight->light_internal, clight->use_shadow, clight->shadow_buffer_size);
|
||||
}
|
||||
|
||||
|
@ -1150,19 +1146,11 @@ void VisualServerCanvas::canvas_light_set_shadow_buffer_size(RID p_light, int p_
|
|||
return;
|
||||
|
||||
clight->shadow_buffer_size = next_power_of_2(p_size);
|
||||
clight->version++;
|
||||
|
||||
VSG::canvas_render->light_set_use_shadow(clight->light_internal, clight->use_shadow, clight->shadow_buffer_size);
|
||||
}
|
||||
|
||||
void VisualServerCanvas::canvas_light_set_shadow_gradient_length(RID p_light, float p_length) {
|
||||
|
||||
ERR_FAIL_COND(p_length < 0);
|
||||
|
||||
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
|
||||
clight->shadow_gradient_length = p_length;
|
||||
}
|
||||
void VisualServerCanvas::canvas_light_set_shadow_filter(RID p_light, VS::CanvasLightShadowFilter p_filter) {
|
||||
|
||||
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
|
||||
|
|
|
@ -245,7 +245,6 @@ public:
|
|||
|
||||
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_gradient_length(RID p_light, float p_length);
|
||||
void canvas_light_set_shadow_filter(RID p_light, VS::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);
|
||||
|
|
|
@ -658,7 +658,6 @@ public:
|
|||
|
||||
BIND2(canvas_light_set_shadow_enabled, RID, bool)
|
||||
BIND2(canvas_light_set_shadow_buffer_size, RID, int)
|
||||
BIND2(canvas_light_set_shadow_gradient_length, RID, float)
|
||||
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)
|
||||
|
|
|
@ -571,7 +571,6 @@ public:
|
|||
|
||||
FUNC2(canvas_light_set_shadow_enabled, RID, bool)
|
||||
FUNC2(canvas_light_set_shadow_buffer_size, RID, int)
|
||||
FUNC2(canvas_light_set_shadow_gradient_length, RID, float)
|
||||
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)
|
||||
|
|
|
@ -1977,7 +1977,6 @@ void VisualServer::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("canvas_light_set_mode", "light", "mode"), &VisualServer::canvas_light_set_mode);
|
||||
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_enabled", "light", "enabled"), &VisualServer::canvas_light_set_shadow_enabled);
|
||||
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_buffer_size", "light", "size"), &VisualServer::canvas_light_set_shadow_buffer_size);
|
||||
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_gradient_length", "light", "length"), &VisualServer::canvas_light_set_shadow_gradient_length);
|
||||
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_filter", "light", "filter"), &VisualServer::canvas_light_set_shadow_filter);
|
||||
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_color", "light", "color"), &VisualServer::canvas_light_set_shadow_color);
|
||||
ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_smooth", "light", "smooth"), &VisualServer::canvas_light_set_shadow_smooth);
|
||||
|
|
|
@ -965,7 +965,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_gradient_length(RID p_light, float p_length) = 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;
|
||||
|
|
Loading…
Reference in a new issue