Merge pull request #44838 from reduz/renderer-reorganization
Reorganize renderer code + cache and threading optimizations.
This commit is contained in:
commit
d8a0dc9fcc
|
@ -40,30 +40,37 @@ class RID {
|
|||
uint64_t _id = 0;
|
||||
|
||||
public:
|
||||
_FORCE_INLINE_ bool operator==(const RID &p_rid) const {
|
||||
_ALWAYS_INLINE_ bool operator==(const RID &p_rid) const {
|
||||
return _id == p_rid._id;
|
||||
}
|
||||
_FORCE_INLINE_ bool operator<(const RID &p_rid) const {
|
||||
_ALWAYS_INLINE_ bool operator<(const RID &p_rid) const {
|
||||
return _id < p_rid._id;
|
||||
}
|
||||
_FORCE_INLINE_ bool operator<=(const RID &p_rid) const {
|
||||
_ALWAYS_INLINE_ bool operator<=(const RID &p_rid) const {
|
||||
return _id <= p_rid._id;
|
||||
}
|
||||
_FORCE_INLINE_ bool operator>(const RID &p_rid) const {
|
||||
_ALWAYS_INLINE_ bool operator>(const RID &p_rid) const {
|
||||
return _id > p_rid._id;
|
||||
}
|
||||
_FORCE_INLINE_ bool operator>=(const RID &p_rid) const {
|
||||
_ALWAYS_INLINE_ bool operator>=(const RID &p_rid) const {
|
||||
return _id >= p_rid._id;
|
||||
}
|
||||
_FORCE_INLINE_ bool operator!=(const RID &p_rid) const {
|
||||
_ALWAYS_INLINE_ bool operator!=(const RID &p_rid) const {
|
||||
return _id != p_rid._id;
|
||||
}
|
||||
_FORCE_INLINE_ bool is_valid() const { return _id != 0; }
|
||||
_FORCE_INLINE_ bool is_null() const { return _id == 0; }
|
||||
_ALWAYS_INLINE_ bool is_valid() const { return _id != 0; }
|
||||
_ALWAYS_INLINE_ bool is_null() const { return _id == 0; }
|
||||
|
||||
_FORCE_INLINE_ uint64_t get_id() const { return _id; }
|
||||
_ALWAYS_INLINE_ uint32_t get_local_index() const { return _id & 0xFFFFFFFF; }
|
||||
|
||||
_FORCE_INLINE_ RID() {}
|
||||
static _ALWAYS_INLINE_ RID from_uint64(uint64_t p_id) {
|
||||
RID _rid;
|
||||
_rid._id = p_id;
|
||||
return _rid;
|
||||
}
|
||||
_ALWAYS_INLINE_ uint64_t get_id() const { return _id; }
|
||||
|
||||
_ALWAYS_INLINE_ RID() {}
|
||||
};
|
||||
|
||||
#endif // RID_H
|
||||
|
|
|
@ -125,6 +125,7 @@ public:
|
|||
end_work();
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ int get_thread_count() const { return thread_count; }
|
||||
void init(int p_thread_count = -1);
|
||||
void finish();
|
||||
~ThreadWorkPool();
|
||||
|
|
|
@ -5638,7 +5638,7 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin_for_screen(Di
|
|||
|
||||
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
||||
|
||||
return ID_TYPE_DRAW_LIST;
|
||||
return int64_t(ID_TYPE_DRAW_LIST) << ID_BASE_SHIFT;
|
||||
}
|
||||
|
||||
Error RenderingDeviceVulkan::_draw_list_setup_framebuffer(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, VkFramebuffer *r_framebuffer, VkRenderPass *r_render_pass) {
|
||||
|
@ -5905,7 +5905,7 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu
|
|||
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
||||
|
||||
draw_list->viewport = Rect2i(viewport_offset, viewport_size);
|
||||
return ID_TYPE_DRAW_LIST;
|
||||
return int64_t(ID_TYPE_DRAW_LIST) << ID_BASE_SHIFT;
|
||||
}
|
||||
|
||||
Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, DrawListID *r_split_ids, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const Vector<RID> &p_storage_textures) {
|
||||
|
@ -6002,7 +6002,7 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p
|
|||
|
||||
for (uint32_t i = 0; i < p_splits; i++) {
|
||||
//take a command buffer and initialize it
|
||||
VkCommandBuffer command_buffer = split_draw_list_allocators[p_splits].command_buffers[frame];
|
||||
VkCommandBuffer command_buffer = split_draw_list_allocators[i].command_buffers[frame];
|
||||
|
||||
VkCommandBufferInheritanceInfo inheritance_info;
|
||||
inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
|
||||
|
@ -6060,7 +6060,7 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p
|
|||
scissor.extent.height = viewport_size.height;
|
||||
|
||||
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
||||
r_split_ids[i] = (DrawListID(1) << DrawListID(ID_TYPE_SPLIT_DRAW_LIST)) + i;
|
||||
r_split_ids[i] = (int64_t(ID_TYPE_SPLIT_DRAW_LIST) << ID_BASE_SHIFT) + i;
|
||||
|
||||
draw_list[i].viewport = Rect2i(viewport_offset, viewport_size);
|
||||
}
|
||||
|
@ -6075,7 +6075,7 @@ RenderingDeviceVulkan::DrawList *RenderingDeviceVulkan::_get_draw_list_ptr(DrawL
|
|||
|
||||
if (!draw_list) {
|
||||
return nullptr;
|
||||
} else if (p_id == ID_TYPE_DRAW_LIST) {
|
||||
} else if (p_id == (int64_t(ID_TYPE_DRAW_LIST) << ID_BASE_SHIFT)) {
|
||||
if (draw_list_split) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -6442,8 +6442,8 @@ void RenderingDeviceVulkan::draw_list_end() {
|
|||
//send all command buffers
|
||||
VkCommandBuffer *command_buffers = (VkCommandBuffer *)alloca(sizeof(VkCommandBuffer) * draw_list_count);
|
||||
for (uint32_t i = 0; i < draw_list_count; i++) {
|
||||
vkEndCommandBuffer(draw_list->command_buffer);
|
||||
command_buffers[i] = draw_list->command_buffer;
|
||||
vkEndCommandBuffer(draw_list[i].command_buffer);
|
||||
command_buffers[i] = draw_list[i].command_buffer;
|
||||
}
|
||||
|
||||
vkCmdExecuteCommands(frames[frame].draw_command_buffer, draw_list_count, command_buffers);
|
||||
|
|
|
@ -154,12 +154,9 @@ void RendererCompositorRD::initialize() {
|
|||
}
|
||||
}
|
||||
|
||||
ThreadWorkPool RendererCompositorRD::thread_work_pool;
|
||||
uint64_t RendererCompositorRD::frame = 1;
|
||||
|
||||
void RendererCompositorRD::finalize() {
|
||||
thread_work_pool.finish();
|
||||
|
||||
memdelete(scene);
|
||||
memdelete(canvas);
|
||||
memdelete(storage);
|
||||
|
@ -174,7 +171,6 @@ RendererCompositorRD *RendererCompositorRD::singleton = nullptr;
|
|||
|
||||
RendererCompositorRD::RendererCompositorRD() {
|
||||
singleton = this;
|
||||
thread_work_pool.init();
|
||||
time = 0;
|
||||
|
||||
storage = memnew(RendererStorageRD);
|
||||
|
|
|
@ -90,8 +90,6 @@ public:
|
|||
|
||||
virtual bool is_low_end() const { return false; }
|
||||
|
||||
static ThreadWorkPool thread_work_pool;
|
||||
|
||||
static RendererCompositorRD *singleton;
|
||||
RendererCompositorRD();
|
||||
~RendererCompositorRD() {}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -31,6 +31,7 @@
|
|||
#ifndef RENDERING_SERVER_SCENE_RENDER_FORWARD_H
|
||||
#define RENDERING_SERVER_SCENE_RENDER_FORWARD_H
|
||||
|
||||
#include "core/templates/paged_allocator.h"
|
||||
#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
|
||||
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
|
||||
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
|
||||
|
@ -46,7 +47,9 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
|
|||
|
||||
enum {
|
||||
SDFGI_MAX_CASCADES = 8,
|
||||
MAX_GI_PROBES = 8
|
||||
MAX_GI_PROBES = 8,
|
||||
MAX_LIGHTMAPS = 8,
|
||||
MAX_GI_PROBES_PER_INSTANCE = 2,
|
||||
};
|
||||
|
||||
/* Scene Shader */
|
||||
|
@ -197,14 +200,6 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
|
|||
return static_cast<RendererSceneRenderForward *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader));
|
||||
}
|
||||
|
||||
/* Push Constant */
|
||||
|
||||
struct PushConstant {
|
||||
uint32_t index;
|
||||
uint32_t pad;
|
||||
float bake_uv2_offset[2];
|
||||
};
|
||||
|
||||
/* Framebuffer */
|
||||
|
||||
struct RenderBufferDataForward : public RenderBufferData {
|
||||
|
@ -266,7 +261,7 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
|
|||
|
||||
void _update_render_base_uniform_set();
|
||||
RID _setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture);
|
||||
RID _setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, const PagedArray<RID> &p_gi_probes);
|
||||
RID _setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps);
|
||||
|
||||
struct LightmapData {
|
||||
float normal_xform[12];
|
||||
|
@ -292,16 +287,6 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
|
|||
INSTANCE_DATA_FLAG_SKELETON = 1 << 19,
|
||||
};
|
||||
|
||||
struct InstanceData {
|
||||
float transform[16];
|
||||
float normal_transform[16];
|
||||
uint32_t flags;
|
||||
uint32_t instance_uniforms_ofs; //instance_offset in instancing/skeleton buffer
|
||||
uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap)
|
||||
uint32_t mask;
|
||||
float lightmap_uv_scale[4];
|
||||
};
|
||||
|
||||
struct SceneState {
|
||||
struct UBO {
|
||||
float projection_matrix[16];
|
||||
|
@ -385,7 +370,10 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
|
|||
|
||||
RID uniform_buffer;
|
||||
|
||||
LightmapData *lightmaps;
|
||||
LightmapData lightmaps[MAX_LIGHTMAPS];
|
||||
RID lightmap_ids[MAX_LIGHTMAPS];
|
||||
bool lightmap_has_sh[MAX_LIGHTMAPS];
|
||||
uint32_t lightmaps_used = 0;
|
||||
uint32_t max_lightmaps;
|
||||
RID lightmap_buffer;
|
||||
|
||||
|
@ -393,151 +381,16 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
|
|||
uint32_t max_lightmap_captures;
|
||||
RID lightmap_capture_buffer;
|
||||
|
||||
RID instance_buffer;
|
||||
InstanceData *instances;
|
||||
uint32_t max_instances;
|
||||
RID giprobe_ids[MAX_GI_PROBES];
|
||||
uint32_t giprobes_used = 0;
|
||||
|
||||
bool used_screen_texture = false;
|
||||
bool used_normal_texture = false;
|
||||
bool used_depth_texture = false;
|
||||
bool used_sss = false;
|
||||
uint32_t current_shader_index = 0;
|
||||
uint32_t current_material_index = 0;
|
||||
|
||||
} scene_state;
|
||||
|
||||
/* Render List */
|
||||
|
||||
struct RenderList {
|
||||
int max_elements;
|
||||
|
||||
struct Element {
|
||||
RendererSceneRender::InstanceBase *instance;
|
||||
MaterialData *material;
|
||||
union {
|
||||
struct {
|
||||
//from least significant to most significant in sort, TODO: should be endian swapped on big endian
|
||||
uint64_t geometry_index : 20;
|
||||
uint64_t material_index : 15;
|
||||
uint64_t shader_index : 12;
|
||||
uint64_t uses_instancing : 1;
|
||||
uint64_t uses_forward_gi : 1;
|
||||
uint64_t uses_lightmap : 1;
|
||||
uint64_t depth_layer : 4;
|
||||
uint64_t priority : 8;
|
||||
};
|
||||
|
||||
uint64_t sort_key;
|
||||
};
|
||||
uint32_t surface_index;
|
||||
};
|
||||
|
||||
Element *base_elements;
|
||||
Element **elements;
|
||||
|
||||
int element_count;
|
||||
int alpha_element_count;
|
||||
|
||||
void clear() {
|
||||
element_count = 0;
|
||||
alpha_element_count = 0;
|
||||
}
|
||||
|
||||
//should eventually be replaced by radix
|
||||
|
||||
struct SortByKey {
|
||||
_FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
|
||||
return A->sort_key < B->sort_key;
|
||||
}
|
||||
};
|
||||
|
||||
void sort_by_key(bool p_alpha) {
|
||||
SortArray<Element *, SortByKey> sorter;
|
||||
if (p_alpha) {
|
||||
sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
|
||||
} else {
|
||||
sorter.sort(elements, element_count);
|
||||
}
|
||||
}
|
||||
|
||||
struct SortByDepth {
|
||||
_FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
|
||||
return A->instance->depth < B->instance->depth;
|
||||
}
|
||||
};
|
||||
|
||||
void sort_by_depth(bool p_alpha) { //used for shadows
|
||||
|
||||
SortArray<Element *, SortByDepth> sorter;
|
||||
if (p_alpha) {
|
||||
sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
|
||||
} else {
|
||||
sorter.sort(elements, element_count);
|
||||
}
|
||||
}
|
||||
|
||||
struct SortByReverseDepthAndPriority {
|
||||
_FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
|
||||
uint32_t layer_A = uint32_t(A->priority);
|
||||
uint32_t layer_B = uint32_t(B->priority);
|
||||
if (layer_A == layer_B) {
|
||||
return A->instance->depth > B->instance->depth;
|
||||
} else {
|
||||
return layer_A < layer_B;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void sort_by_reverse_depth_and_priority(bool p_alpha) { //used for alpha
|
||||
|
||||
SortArray<Element *, SortByReverseDepthAndPriority> sorter;
|
||||
if (p_alpha) {
|
||||
sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
|
||||
} else {
|
||||
sorter.sort(elements, element_count);
|
||||
}
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Element *add_element() {
|
||||
if (element_count + alpha_element_count >= max_elements) {
|
||||
return nullptr;
|
||||
}
|
||||
elements[element_count] = &base_elements[element_count];
|
||||
return elements[element_count++];
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Element *add_alpha_element() {
|
||||
if (element_count + alpha_element_count >= max_elements) {
|
||||
return nullptr;
|
||||
}
|
||||
int idx = max_elements - alpha_element_count - 1;
|
||||
elements[idx] = &base_elements[idx];
|
||||
alpha_element_count++;
|
||||
return elements[idx];
|
||||
}
|
||||
|
||||
void init() {
|
||||
element_count = 0;
|
||||
alpha_element_count = 0;
|
||||
elements = memnew_arr(Element *, max_elements);
|
||||
base_elements = memnew_arr(Element, max_elements);
|
||||
for (int i = 0; i < max_elements; i++) {
|
||||
elements[i] = &base_elements[i]; // assign elements
|
||||
}
|
||||
}
|
||||
|
||||
RenderList() {
|
||||
max_elements = 0;
|
||||
}
|
||||
|
||||
~RenderList() {
|
||||
memdelete_arr(elements);
|
||||
memdelete_arr(base_elements);
|
||||
}
|
||||
};
|
||||
|
||||
RenderList render_list;
|
||||
|
||||
static RendererSceneRenderForward *singleton;
|
||||
uint64_t render_pass;
|
||||
double time;
|
||||
|
@ -567,28 +420,319 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
|
|||
};
|
||||
|
||||
void _setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false);
|
||||
void _setup_lightmaps(const PagedArray<InstanceBase *> &p_lightmaps, const Transform &p_cam_transform);
|
||||
void _setup_giprobes(const PagedArray<RID> &p_giprobes);
|
||||
void _setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform);
|
||||
|
||||
void _fill_instances(RenderList::Element **p_elements, int p_element_count, bool p_for_depth, bool p_has_sdfgi = false, bool p_has_opaque_gi = false);
|
||||
void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0);
|
||||
_FORCE_INLINE_ void _add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi = false);
|
||||
_FORCE_INLINE_ void _add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi = false);
|
||||
struct GeometryInstanceSurfaceDataCache;
|
||||
|
||||
void _fill_render_list(const PagedArray<InstanceBase *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi = false);
|
||||
struct RenderListParameters {
|
||||
GeometryInstanceSurfaceDataCache **elements = nullptr;
|
||||
int element_count = 0;
|
||||
bool reverse_cull = false;
|
||||
PassMode pass_mode = PASS_MODE_COLOR;
|
||||
bool no_gi = false;
|
||||
RID render_pass_uniform_set;
|
||||
bool force_wireframe = false;
|
||||
Vector2 uv_offset;
|
||||
Plane lod_plane;
|
||||
float lod_distance_multiplier = 0.0;
|
||||
float screen_lod_threshold = 0.0;
|
||||
RD::FramebufferFormatID framebuffer_format = 0;
|
||||
RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0) {
|
||||
elements = p_elements;
|
||||
element_count = p_element_count;
|
||||
reverse_cull = p_reverse_cull;
|
||||
pass_mode = p_pass_mode;
|
||||
no_gi = p_no_gi;
|
||||
render_pass_uniform_set = p_render_pass_uniform_set;
|
||||
force_wireframe = p_force_wireframe;
|
||||
uv_offset = p_uv_offset;
|
||||
lod_plane = p_lod_plane;
|
||||
lod_distance_multiplier = p_lod_distance_multiplier;
|
||||
screen_lod_threshold = p_screen_lod_threshold;
|
||||
}
|
||||
};
|
||||
|
||||
template <PassMode p_pass_mode>
|
||||
_FORCE_INLINE_ void _render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element);
|
||||
|
||||
void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element);
|
||||
|
||||
LocalVector<RD::DrawListID> thread_draw_lists;
|
||||
void _render_list_thread_function(uint32_t p_thread, RenderListParameters *p_params);
|
||||
void _render_list_with_threads(RenderListParameters *p_params, RID p_framebuffer, RD::InitialAction p_initial_color_action, RD::FinalAction p_final_color_action, RD::InitialAction p_initial_depth_action, RD::FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const Vector<RID> &p_storage_textures = Vector<RID>());
|
||||
|
||||
uint32_t render_list_thread_threshold = 500;
|
||||
|
||||
void _fill_render_list(const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi = false, bool p_using_opaque_gi = false);
|
||||
|
||||
Map<Size2i, RID> sdfgi_framebuffer_size_cache;
|
||||
|
||||
struct GeometryInstanceData;
|
||||
struct GeometryInstanceForward;
|
||||
|
||||
struct GeometryInstanceLightmapSH {
|
||||
Color sh[9];
|
||||
};
|
||||
|
||||
// Cached data for drawing surfaces
|
||||
struct GeometryInstanceSurfaceDataCache {
|
||||
enum {
|
||||
FLAG_PASS_DEPTH = 1,
|
||||
FLAG_PASS_OPAQUE = 2,
|
||||
FLAG_PASS_ALPHA = 4,
|
||||
FLAG_PASS_SHADOW = 8,
|
||||
FLAG_USES_SHARED_SHADOW_MATERIAL = 128,
|
||||
FLAG_USES_SUBSURFACE_SCATTERING = 2048,
|
||||
FLAG_USES_SCREEN_TEXTURE = 4096,
|
||||
FLAG_USES_DEPTH_TEXTURE = 8192,
|
||||
FLAG_USES_NORMAL_TEXTURE = 16384,
|
||||
FLAG_USES_DOUBLE_SIDED_SHADOWS = 32768,
|
||||
};
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint32_t geometry_id;
|
||||
uint32_t material_id;
|
||||
uint32_t shader_id;
|
||||
uint32_t surface_type : 4;
|
||||
uint32_t uses_forward_gi : 1; //set during addition
|
||||
uint32_t uses_lightmap : 1; //set during addition
|
||||
uint32_t depth_layer : 4; //set during addition
|
||||
uint32_t priority : 8;
|
||||
};
|
||||
struct {
|
||||
uint64_t sort_key1;
|
||||
uint64_t sort_key2;
|
||||
};
|
||||
} sort;
|
||||
|
||||
RS::PrimitiveType primitive = RS::PRIMITIVE_MAX;
|
||||
uint32_t flags = 0;
|
||||
uint32_t surface_index = 0;
|
||||
|
||||
void *surface = nullptr;
|
||||
RID material_uniform_set;
|
||||
ShaderData *shader = nullptr;
|
||||
|
||||
void *surface_shadow = nullptr;
|
||||
RID material_uniform_set_shadow;
|
||||
ShaderData *shader_shadow = nullptr;
|
||||
|
||||
GeometryInstanceSurfaceDataCache *next = nullptr;
|
||||
GeometryInstanceForward *owner = nullptr;
|
||||
};
|
||||
|
||||
struct GeometryInstanceForward : public GeometryInstance {
|
||||
//used during rendering
|
||||
bool mirror = false;
|
||||
bool non_uniform_scale = false;
|
||||
float lod_bias = 0.0;
|
||||
float lod_model_scale = 1.0;
|
||||
AABB transformed_aabb; //needed for LOD
|
||||
float depth = 0;
|
||||
struct PushConstant {
|
||||
float transform[16];
|
||||
uint32_t flags;
|
||||
uint32_t instance_uniforms_ofs; //base offset in global buffer for instance variables
|
||||
uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap index)
|
||||
uint32_t layer_mask;
|
||||
float lightmap_uv_scale[4];
|
||||
} push_constant;
|
||||
RID transforms_uniform_set;
|
||||
uint32_t instance_count = 0;
|
||||
RID mesh_instance;
|
||||
bool can_sdfgi = false;
|
||||
//used during setup
|
||||
uint32_t base_flags = 0;
|
||||
RID gi_probes[MAX_GI_PROBES_PER_INSTANCE];
|
||||
RID lightmap_instance;
|
||||
GeometryInstanceLightmapSH *lightmap_sh = nullptr;
|
||||
GeometryInstanceSurfaceDataCache *surface_caches = nullptr;
|
||||
SelfList<GeometryInstanceForward> dirty_list_element;
|
||||
|
||||
struct Data {
|
||||
//data used less often goes into regular heap
|
||||
RID base;
|
||||
RS::InstanceType base_type;
|
||||
|
||||
RID skeleton;
|
||||
|
||||
uint32_t layer_mask = 1;
|
||||
|
||||
Vector<RID> surface_materials;
|
||||
RID material_override;
|
||||
Transform transform;
|
||||
AABB aabb;
|
||||
int32_t shader_parameters_offset = -1;
|
||||
|
||||
bool use_dynamic_gi = false;
|
||||
bool use_baked_light = false;
|
||||
bool cast_double_sided_shaodows = false;
|
||||
bool mirror = false;
|
||||
Rect2 lightmap_uv_scale;
|
||||
uint32_t lightmap_slice_index = 0;
|
||||
bool dirty_dependencies = false;
|
||||
|
||||
RendererStorage::DependencyTracker dependency_tracker;
|
||||
};
|
||||
|
||||
Data *data = nullptr;
|
||||
|
||||
GeometryInstanceForward() :
|
||||
dirty_list_element(this) {}
|
||||
};
|
||||
|
||||
static void _geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker);
|
||||
static void _geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker);
|
||||
|
||||
SelfList<GeometryInstanceForward>::List geometry_instance_dirty_list;
|
||||
|
||||
PagedAllocator<GeometryInstanceForward> geometry_instance_alloc;
|
||||
PagedAllocator<GeometryInstanceSurfaceDataCache> geometry_instance_surface_alloc;
|
||||
PagedAllocator<GeometryInstanceLightmapSH> geometry_instance_lightmap_sh;
|
||||
|
||||
void _geometry_instance_add_surface_with_material(GeometryInstanceForward *ginstance, uint32_t p_surface, MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh);
|
||||
void _geometry_instance_add_surface(GeometryInstanceForward *ginstance, uint32_t p_surface, RID p_material, RID p_mesh);
|
||||
void _geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance);
|
||||
void _geometry_instance_update(GeometryInstance *p_geometry_instance);
|
||||
void _update_dirty_geometry_instances();
|
||||
|
||||
bool low_end = false;
|
||||
|
||||
/* Render List */
|
||||
|
||||
struct RenderList {
|
||||
int max_elements;
|
||||
|
||||
GeometryInstanceSurfaceDataCache **elements = nullptr;
|
||||
|
||||
int element_count;
|
||||
int alpha_element_count;
|
||||
|
||||
void clear() {
|
||||
element_count = 0;
|
||||
alpha_element_count = 0;
|
||||
}
|
||||
|
||||
//should eventually be replaced by radix
|
||||
|
||||
struct SortByKey {
|
||||
_FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const {
|
||||
return (A->sort.sort_key2 == B->sort.sort_key2) ? (A->sort.sort_key1 < B->sort.sort_key1) : (A->sort.sort_key2 < B->sort.sort_key2);
|
||||
}
|
||||
};
|
||||
|
||||
void sort_by_key(bool p_alpha) {
|
||||
SortArray<GeometryInstanceSurfaceDataCache *, SortByKey> sorter;
|
||||
if (p_alpha) {
|
||||
sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
|
||||
} else {
|
||||
sorter.sort(elements, element_count);
|
||||
}
|
||||
}
|
||||
|
||||
struct SortByDepth {
|
||||
_FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const {
|
||||
return (A->owner->depth < B->owner->depth);
|
||||
}
|
||||
};
|
||||
|
||||
void sort_by_depth(bool p_alpha) { //used for shadows
|
||||
|
||||
SortArray<GeometryInstanceSurfaceDataCache *, SortByDepth> sorter;
|
||||
if (p_alpha) {
|
||||
sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
|
||||
} else {
|
||||
sorter.sort(elements, element_count);
|
||||
}
|
||||
}
|
||||
|
||||
struct SortByReverseDepthAndPriority {
|
||||
_FORCE_INLINE_ bool operator()(const GeometryInstanceSurfaceDataCache *A, const GeometryInstanceSurfaceDataCache *B) const {
|
||||
return (A->sort.priority == B->sort.priority) ? (A->owner->depth > B->owner->depth) : (A->sort.priority < B->sort.priority);
|
||||
}
|
||||
};
|
||||
|
||||
void sort_by_reverse_depth_and_priority(bool p_alpha) { //used for alpha
|
||||
|
||||
SortArray<GeometryInstanceSurfaceDataCache *, SortByReverseDepthAndPriority> sorter;
|
||||
if (p_alpha) {
|
||||
sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
|
||||
} else {
|
||||
sorter.sort(elements, element_count);
|
||||
}
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void add_element(GeometryInstanceSurfaceDataCache *p_element) {
|
||||
if (element_count + alpha_element_count >= max_elements) {
|
||||
return;
|
||||
}
|
||||
elements[element_count] = p_element;
|
||||
element_count++;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void add_alpha_element(GeometryInstanceSurfaceDataCache *p_element) {
|
||||
if (element_count + alpha_element_count >= max_elements) {
|
||||
return;
|
||||
}
|
||||
int idx = max_elements - alpha_element_count - 1;
|
||||
elements[idx] = p_element;
|
||||
alpha_element_count++;
|
||||
}
|
||||
|
||||
void init() {
|
||||
element_count = 0;
|
||||
alpha_element_count = 0;
|
||||
elements = memnew_arr(GeometryInstanceSurfaceDataCache *, max_elements);
|
||||
}
|
||||
|
||||
RenderList() {
|
||||
max_elements = 0;
|
||||
}
|
||||
|
||||
~RenderList() {
|
||||
memdelete_arr(elements);
|
||||
}
|
||||
};
|
||||
|
||||
RenderList render_list;
|
||||
|
||||
protected:
|
||||
virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_lod_threshold);
|
||||
virtual void _render_shadow(RID p_framebuffer, const PagedArray<InstanceBase *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0);
|
||||
virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
|
||||
virtual void _render_uv2(const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
|
||||
virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<InstanceBase *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture);
|
||||
virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<InstanceBase *> &p_instances);
|
||||
virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_lod_threshold);
|
||||
virtual void _render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0);
|
||||
virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
|
||||
virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
|
||||
virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture);
|
||||
virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances);
|
||||
|
||||
public:
|
||||
virtual GeometryInstance *geometry_instance_create(RID p_base);
|
||||
virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton);
|
||||
virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override);
|
||||
virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials);
|
||||
virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance);
|
||||
virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb);
|
||||
virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask);
|
||||
virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias);
|
||||
virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable);
|
||||
virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable);
|
||||
virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index);
|
||||
virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9);
|
||||
virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset);
|
||||
virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable);
|
||||
|
||||
virtual Transform geometry_instance_get_transform(GeometryInstance *p_instance);
|
||||
virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance);
|
||||
|
||||
virtual void geometry_instance_free(GeometryInstance *p_geometry_instance);
|
||||
|
||||
virtual uint32_t geometry_instance_get_pair_mask();
|
||||
virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count);
|
||||
virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count);
|
||||
virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count);
|
||||
virtual void geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count);
|
||||
|
||||
virtual void set_time(double p_time, double p_step);
|
||||
|
||||
virtual bool free(RID p_rid);
|
||||
|
|
|
@ -4035,6 +4035,19 @@ void RendererSceneRenderRD::decal_instance_set_transform(RID p_decal, const Tran
|
|||
|
||||
/////////////////////////////////
|
||||
|
||||
RID RendererSceneRenderRD::lightmap_instance_create(RID p_lightmap) {
|
||||
LightmapInstance li;
|
||||
li.lightmap = p_lightmap;
|
||||
return lightmap_instance_owner.make_rid(li);
|
||||
}
|
||||
void RendererSceneRenderRD::lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform) {
|
||||
LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap);
|
||||
ERR_FAIL_COND(!li);
|
||||
li->transform = p_transform;
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
|
||||
RID RendererSceneRenderRD::gi_probe_instance_create(RID p_base) {
|
||||
GIProbeInstance gi_probe;
|
||||
gi_probe.probe = p_base;
|
||||
|
@ -4061,7 +4074,7 @@ bool RendererSceneRenderRD::gi_probe_needs_update(RID p_probe) const {
|
|||
return gi_probe->last_probe_version != storage->gi_probe_get_version(gi_probe->probe);
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<InstanceBase *> &p_dynamic_objects) {
|
||||
void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) {
|
||||
GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe);
|
||||
ERR_FAIL_COND(!gi_probe);
|
||||
|
||||
|
@ -4578,13 +4591,10 @@ void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_ins
|
|||
|
||||
//this could probably be better parallelized in compute..
|
||||
for (int i = 0; i < (int)p_dynamic_objects.size(); i++) {
|
||||
InstanceBase *instance = p_dynamic_objects[i];
|
||||
//not used, so clear
|
||||
instance->depth_layer = 0;
|
||||
instance->depth = 0;
|
||||
GeometryInstance *instance = p_dynamic_objects[i];
|
||||
|
||||
//transform aabb to giprobe
|
||||
AABB aabb = (to_probe_xform * instance->transform).xform(instance->aabb);
|
||||
AABB aabb = (to_probe_xform * geometry_instance_get_transform(instance)).xform(geometry_instance_get_aabb(instance));
|
||||
|
||||
//this needs to wrap to grid resolution to avoid jitter
|
||||
//also extend margin a bit just in case
|
||||
|
@ -7101,7 +7111,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
|
|||
RD::get_singleton()->compute_list_end();
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) {
|
||||
void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) {
|
||||
Color clear_color;
|
||||
if (p_render_buffers.is_valid()) {
|
||||
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
||||
|
@ -7177,7 +7187,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
|
|||
}
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<InstanceBase *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold) {
|
||||
void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold) {
|
||||
LightInstance *light_instance = light_instance_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light_instance);
|
||||
|
||||
|
@ -7353,11 +7363,11 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
|||
}
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
|
||||
void RendererSceneRenderRD::render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
|
||||
_render_material(p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, p_framebuffer, p_region);
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<InstanceBase *> &p_instances) {
|
||||
void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances) {
|
||||
//print_line("rendering region " + itos(p_region));
|
||||
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
||||
ERR_FAIL_COND(!rb);
|
||||
|
@ -7694,7 +7704,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con
|
|||
}
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<InstanceBase *> &p_instances) {
|
||||
void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances) {
|
||||
ERR_FAIL_COND(!storage->particles_collision_is_heightfield(p_collider));
|
||||
Vector3 extents = storage->particles_collision_get_extents(p_collider) * p_transform.basis.get_scale();
|
||||
CameraMatrix cm;
|
||||
|
@ -7844,6 +7854,8 @@ bool RendererSceneRenderRD::free(RID p_rid) {
|
|||
reflection_probe_instance_owner.free(p_rid);
|
||||
} else if (decal_instance_owner.owns(p_rid)) {
|
||||
decal_instance_owner.free(p_rid);
|
||||
} else if (lightmap_instance_owner.owns(p_rid)) {
|
||||
lightmap_instance_owner.free(p_rid);
|
||||
} else if (gi_probe_instance_owner.owns(p_rid)) {
|
||||
GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_rid);
|
||||
if (gi_probe->texture.is_valid()) {
|
||||
|
@ -7979,23 +7991,28 @@ TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Vecto
|
|||
|
||||
//RID sampled_light;
|
||||
|
||||
InstanceBase ins;
|
||||
GeometryInstance *gi = geometry_instance_create(p_base);
|
||||
|
||||
ins.base_type = RSG::storage->get_base_type(p_base);
|
||||
ins.base = p_base;
|
||||
ins.materials.resize(RSG::storage->mesh_get_surface_count(p_base));
|
||||
for (int i = 0; i < ins.materials.size(); i++) {
|
||||
if (i < p_material_overrides.size()) {
|
||||
ins.materials.write[i] = p_material_overrides[i];
|
||||
uint32_t sc = RSG::storage->mesh_get_surface_count(p_base);
|
||||
Vector<RID> materials;
|
||||
materials.resize(sc);
|
||||
|
||||
for (uint32_t i = 0; i < sc; i++) {
|
||||
if (i < (uint32_t)p_material_overrides.size()) {
|
||||
materials.write[i] = p_material_overrides[i];
|
||||
}
|
||||
}
|
||||
|
||||
geometry_instance_set_surface_materials(gi, materials);
|
||||
|
||||
if (cull_argument.size() == 0) {
|
||||
cull_argument.push_back(nullptr);
|
||||
}
|
||||
cull_argument[0] = &ins;
|
||||
cull_argument[0] = gi;
|
||||
_render_uv2(cull_argument, fb, Rect2i(0, 0, p_image_size.width, p_image_size.height));
|
||||
|
||||
geometry_instance_free(gi);
|
||||
|
||||
TypedArray<Image> ret;
|
||||
|
||||
{
|
||||
|
|
|
@ -109,12 +109,12 @@ protected:
|
|||
void _setup_reflections(const PagedArray<RID> &p_reflections, const Transform &p_camera_inverse_transform, RID p_environment);
|
||||
void _setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, uint32_t &r_gi_probes_used);
|
||||
|
||||
virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color, float p_screen_lod_threshold) = 0;
|
||||
virtual void _render_shadow(RID p_framebuffer, const PagedArray<InstanceBase *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0) = 0;
|
||||
virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
|
||||
virtual void _render_uv2(const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
|
||||
virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<InstanceBase *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0;
|
||||
virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<InstanceBase *> &p_instances) = 0;
|
||||
virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color, float p_screen_lod_threshold) = 0;
|
||||
virtual void _render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0) = 0;
|
||||
virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
|
||||
virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
|
||||
virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0;
|
||||
virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) = 0;
|
||||
|
||||
virtual void _debug_giprobe(RID p_gi_probe, RenderingDevice::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha);
|
||||
void _debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform);
|
||||
|
@ -137,8 +137,8 @@ protected:
|
|||
void _process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_ambient_buffer, RID p_reflection_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes);
|
||||
|
||||
// needed for a single argument calls (material and uv2)
|
||||
PagedArrayPool<InstanceBase *> cull_argument_pool;
|
||||
PagedArray<InstanceBase *> cull_argument; //need this to exist
|
||||
PagedArrayPool<GeometryInstance *> cull_argument_pool;
|
||||
PagedArray<GeometryInstance *> cull_argument; //need this to exist
|
||||
private:
|
||||
RS::ViewportDebugDraw debug_draw = RS::VIEWPORT_DEBUG_DRAW_DISABLED;
|
||||
double time_step = 0;
|
||||
|
@ -374,6 +374,15 @@ private:
|
|||
|
||||
mutable RID_Owner<DecalInstance> decal_instance_owner;
|
||||
|
||||
/* LIGHTMAP INSTANCE */
|
||||
|
||||
struct LightmapInstance {
|
||||
RID lightmap;
|
||||
Transform transform;
|
||||
};
|
||||
|
||||
mutable RID_Owner<LightmapInstance> lightmap_instance_owner;
|
||||
|
||||
/* GIPROBE INSTANCE */
|
||||
|
||||
struct GIProbeLight {
|
||||
|
@ -1473,6 +1482,9 @@ private:
|
|||
bool low_end = false;
|
||||
|
||||
public:
|
||||
virtual Transform geometry_instance_get_transform(GeometryInstance *p_instance) = 0;
|
||||
virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) = 0;
|
||||
|
||||
/* SHADOW ATLAS API */
|
||||
|
||||
RID shadow_atlas_create();
|
||||
|
@ -1822,10 +1834,25 @@ public:
|
|||
return decal->transform;
|
||||
}
|
||||
|
||||
virtual RID lightmap_instance_create(RID p_lightmap);
|
||||
virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform);
|
||||
_FORCE_INLINE_ bool lightmap_instance_is_valid(RID p_lightmap_instance) {
|
||||
return lightmap_instance_owner.getornull(p_lightmap_instance) != nullptr;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RID lightmap_instance_get_lightmap(RID p_lightmap_instance) {
|
||||
LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap_instance);
|
||||
return li->lightmap;
|
||||
}
|
||||
_FORCE_INLINE_ Transform lightmap_instance_get_transform(RID p_lightmap_instance) {
|
||||
LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap_instance);
|
||||
return li->transform;
|
||||
}
|
||||
|
||||
RID gi_probe_instance_create(RID p_base);
|
||||
void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform);
|
||||
bool gi_probe_needs_update(RID p_probe) const;
|
||||
void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::InstanceBase *> &p_dynamic_objects);
|
||||
void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects);
|
||||
|
||||
void gi_probe_set_quality(RS::GIProbeQuality p_quality) { gi_probe_quality = p_quality; }
|
||||
|
||||
|
@ -1900,16 +1927,16 @@ public:
|
|||
float render_buffers_get_volumetric_fog_end(RID p_render_buffers);
|
||||
float render_buffers_get_volumetric_fog_detail_spread(RID p_render_buffers);
|
||||
|
||||
void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold);
|
||||
void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold);
|
||||
|
||||
void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<InstanceBase *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0);
|
||||
void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0);
|
||||
|
||||
void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
|
||||
void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
|
||||
|
||||
void render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<InstanceBase *> &p_instances);
|
||||
void render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances);
|
||||
void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result);
|
||||
|
||||
void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<InstanceBase *> &p_instances);
|
||||
void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances);
|
||||
|
||||
virtual void set_scene_pass(uint64_t p_pass) {
|
||||
scene_pass = p_pass;
|
||||
|
|
|
@ -1438,7 +1438,7 @@ void RendererStorageRD::shader_set_code(RID p_shader, const String &p_code) {
|
|||
|
||||
for (Set<Material *>::Element *E = shader->owners.front(); E; E = E->next()) {
|
||||
Material *material = E->get();
|
||||
material->instance_dependency.instance_notify_changed(false, true);
|
||||
material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL);
|
||||
_material_queue_update(material, true, true);
|
||||
}
|
||||
}
|
||||
|
@ -1547,7 +1547,8 @@ void RendererStorageRD::material_set_shader(RID p_material, RID p_shader) {
|
|||
}
|
||||
|
||||
if (p_shader.is_null()) {
|
||||
material->instance_dependency.instance_notify_changed(false, true);
|
||||
material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL);
|
||||
material->shader_id = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1555,6 +1556,7 @@ void RendererStorageRD::material_set_shader(RID p_material, RID p_shader) {
|
|||
ERR_FAIL_COND(!shader);
|
||||
material->shader = shader;
|
||||
material->shader_type = shader->type;
|
||||
material->shader_id = p_shader.get_local_index();
|
||||
shader->owners.insert(material);
|
||||
|
||||
if (shader->type == SHADER_TYPE_MAX) {
|
||||
|
@ -1568,7 +1570,7 @@ void RendererStorageRD::material_set_shader(RID p_material, RID p_shader) {
|
|||
material->data->set_next_pass(material->next_pass);
|
||||
material->data->set_render_priority(material->priority);
|
||||
//updating happens later
|
||||
material->instance_dependency.instance_notify_changed(false, true);
|
||||
material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL);
|
||||
_material_queue_update(material, true, true);
|
||||
}
|
||||
|
||||
|
@ -1613,7 +1615,7 @@ void RendererStorageRD::material_set_next_pass(RID p_material, RID p_next_materi
|
|||
material->data->set_next_pass(p_next_material);
|
||||
}
|
||||
|
||||
material->instance_dependency.instance_notify_changed(false, true);
|
||||
material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL);
|
||||
}
|
||||
|
||||
void RendererStorageRD::material_set_render_priority(RID p_material, int priority) {
|
||||
|
@ -1663,10 +1665,10 @@ void RendererStorageRD::material_get_instance_shader_parameters(RID p_material,
|
|||
}
|
||||
}
|
||||
|
||||
void RendererStorageRD::material_update_dependency(RID p_material, InstanceBaseDependency *p_instance) {
|
||||
void RendererStorageRD::material_update_dependency(RID p_material, DependencyTracker *p_instance) {
|
||||
Material *material = material_owner.getornull(p_material);
|
||||
ERR_FAIL_COND(!material);
|
||||
p_instance->update_dependency(&material->instance_dependency);
|
||||
p_instance->update_dependency(&material->dependency);
|
||||
if (material->next_pass.is_valid()) {
|
||||
material_update_dependency(material->next_pass, p_instance);
|
||||
}
|
||||
|
@ -2596,7 +2598,7 @@ void RendererStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_su
|
|||
_mesh_instance_add_surface(mi, mesh, mesh->surface_count - 1);
|
||||
}
|
||||
|
||||
mesh->instance_dependency.instance_notify_changed(true, true);
|
||||
mesh->dependency.changed_notify(DEPENDENCY_CHANGED_MESH);
|
||||
|
||||
mesh->material_cache.clear();
|
||||
}
|
||||
|
@ -2638,7 +2640,7 @@ void RendererStorageRD::mesh_surface_set_material(RID p_mesh, int p_surface, RID
|
|||
ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);
|
||||
mesh->surfaces[p_surface]->material = p_material;
|
||||
|
||||
mesh->instance_dependency.instance_notify_changed(false, true);
|
||||
mesh->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL);
|
||||
mesh->material_cache.clear();
|
||||
}
|
||||
|
||||
|
@ -2858,8 +2860,8 @@ void RendererStorageRD::mesh_clear(RID p_mesh) {
|
|||
MeshInstance *mi = E->get();
|
||||
_mesh_instance_clear(mi);
|
||||
}
|
||||
mesh->instance_dependency.instance_notify_changed(true, true);
|
||||
mesh->has_bone_weights = false;
|
||||
mesh->dependency.changed_notify(DEPENDENCY_CHANGED_MESH);
|
||||
}
|
||||
|
||||
bool RendererStorageRD::mesh_needs_instance(RID p_mesh, bool p_has_skeleton) {
|
||||
|
@ -3298,6 +3300,8 @@ void RendererStorageRD::multimesh_allocate(RID p_multimesh, int p_instances, RS:
|
|||
if (multimesh->instances) {
|
||||
multimesh->buffer = RD::get_singleton()->storage_buffer_create(multimesh->instances * multimesh->stride_cache * 4);
|
||||
}
|
||||
|
||||
multimesh->dependency.changed_notify(DEPENDENCY_CHANGED_MULTIMESH);
|
||||
}
|
||||
|
||||
int RendererStorageRD::multimesh_get_instance_count(RID p_multimesh) const {
|
||||
|
@ -3331,7 +3335,7 @@ void RendererStorageRD::multimesh_set_mesh(RID p_multimesh, RID p_mesh) {
|
|||
}
|
||||
}
|
||||
|
||||
multimesh->instance_dependency.instance_notify_changed(true, true);
|
||||
multimesh->dependency.changed_notify(DEPENDENCY_CHANGED_MESH);
|
||||
}
|
||||
|
||||
#define MULTIMESH_DIRTY_REGION_SIZE 512
|
||||
|
@ -3690,7 +3694,7 @@ void RendererStorageRD::multimesh_set_buffer(RID p_multimesh, const Vector<float
|
|||
const float *data = p_buffer.ptr();
|
||||
|
||||
_multimesh_re_create_aabb(multimesh, data, multimesh->instances);
|
||||
multimesh->instance_dependency.instance_notify_changed(true, false);
|
||||
multimesh->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3731,6 +3735,8 @@ void RendererStorageRD::multimesh_set_visible_instances(RID p_multimesh, int p_v
|
|||
}
|
||||
|
||||
multimesh->visible_instances = p_visible;
|
||||
|
||||
multimesh->dependency.changed_notify(DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES);
|
||||
}
|
||||
|
||||
int RendererStorageRD::multimesh_get_visible_instances(RID p_multimesh) const {
|
||||
|
@ -3788,7 +3794,7 @@ void RendererStorageRD::_update_dirty_multimeshes() {
|
|||
//aabb is dirty..
|
||||
_multimesh_re_create_aabb(multimesh, data, visible_instances);
|
||||
multimesh->aabb_dirty = false;
|
||||
multimesh->instance_dependency.instance_notify_changed(true, false);
|
||||
multimesh->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3926,7 +3932,7 @@ void RendererStorageRD::particles_set_custom_aabb(RID p_particles, const AABB &p
|
|||
Particles *particles = particles_owner.getornull(p_particles);
|
||||
ERR_FAIL_COND(!particles);
|
||||
particles->custom_aabb = p_aabb;
|
||||
particles->instance_dependency.instance_notify_changed(true, false);
|
||||
particles->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
|
||||
}
|
||||
|
||||
void RendererStorageRD::particles_set_speed_scale(RID p_particles, float p_scale) {
|
||||
|
@ -4155,24 +4161,18 @@ RID RendererStorageRD::particles_get_draw_pass_mesh(RID p_particles, int p_pass)
|
|||
return particles->draw_passes[p_pass];
|
||||
}
|
||||
|
||||
void RendererStorageRD::particles_add_collision(RID p_particles, InstanceBaseDependency *p_instance) {
|
||||
RendererSceneRender::InstanceBase *instance = static_cast<RendererSceneRender::InstanceBase *>(p_instance);
|
||||
|
||||
void RendererStorageRD::particles_add_collision(RID p_particles, RID p_particles_collision_instance) {
|
||||
Particles *particles = particles_owner.getornull(p_particles);
|
||||
ERR_FAIL_COND(!particles);
|
||||
|
||||
ERR_FAIL_COND(instance->base_type != RS::INSTANCE_PARTICLES_COLLISION);
|
||||
|
||||
particles->collisions.insert(instance);
|
||||
particles->collisions.insert(p_particles_collision_instance);
|
||||
}
|
||||
|
||||
void RendererStorageRD::particles_remove_collision(RID p_particles, InstanceBaseDependency *p_instance) {
|
||||
RendererSceneRender::InstanceBase *instance = static_cast<RendererSceneRender::InstanceBase *>(p_instance);
|
||||
|
||||
void RendererStorageRD::particles_remove_collision(RID p_particles, RID p_particles_collision_instance) {
|
||||
Particles *particles = particles_owner.getornull(p_particles);
|
||||
ERR_FAIL_COND(!particles);
|
||||
|
||||
particles->collisions.erase(instance);
|
||||
particles->collisions.erase(p_particles_collision_instance);
|
||||
}
|
||||
|
||||
void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta) {
|
||||
|
@ -4272,9 +4272,15 @@ void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta
|
|||
to_particles = p_particles->emission_transform.affine_inverse();
|
||||
}
|
||||
uint32_t collision_3d_textures_used = 0;
|
||||
for (const Set<RendererSceneRender::InstanceBase *>::Element *E = p_particles->collisions.front(); E; E = E->next()) {
|
||||
ParticlesCollision *pc = particles_collision_owner.getornull(E->get()->base);
|
||||
Transform to_collider = E->get()->transform;
|
||||
for (const Set<RID>::Element *E = p_particles->collisions.front(); E; E = E->next()) {
|
||||
ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(E->get());
|
||||
if (!pci || !pci->active) {
|
||||
continue;
|
||||
}
|
||||
ParticlesCollision *pc = particles_collision_owner.getornull(pci->collision);
|
||||
ERR_CONTINUE(!pc);
|
||||
|
||||
Transform to_collider = pci->transform;
|
||||
if (p_particles->use_local_coords) {
|
||||
to_collider = to_particles * to_collider;
|
||||
}
|
||||
|
@ -4687,7 +4693,7 @@ void RendererStorageRD::update_particles() {
|
|||
RD::get_singleton()->compute_list_end();
|
||||
}
|
||||
|
||||
particles->instance_dependency.instance_notify_changed(true, false); //make sure shadows are updated
|
||||
particles->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4986,7 +4992,7 @@ void RendererStorageRD::particles_collision_set_collision_type(RID p_particles_c
|
|||
particles_collision->heightfield_texture = RID();
|
||||
}
|
||||
particles_collision->type = p_type;
|
||||
particles_collision->instance_dependency.instance_notify_changed(true, false);
|
||||
particles_collision->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
|
||||
}
|
||||
|
||||
void RendererStorageRD::particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) {
|
||||
|
@ -5000,7 +5006,7 @@ void RendererStorageRD::particles_collision_set_sphere_radius(RID p_particles_co
|
|||
ERR_FAIL_COND(!particles_collision);
|
||||
|
||||
particles_collision->radius = p_radius;
|
||||
particles_collision->instance_dependency.instance_notify_changed(true, false);
|
||||
particles_collision->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
|
||||
}
|
||||
|
||||
void RendererStorageRD::particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) {
|
||||
|
@ -5008,7 +5014,7 @@ void RendererStorageRD::particles_collision_set_box_extents(RID p_particles_coll
|
|||
ERR_FAIL_COND(!particles_collision);
|
||||
|
||||
particles_collision->extents = p_extents;
|
||||
particles_collision->instance_dependency.instance_notify_changed(true, false);
|
||||
particles_collision->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
|
||||
}
|
||||
|
||||
void RendererStorageRD::particles_collision_set_attractor_strength(RID p_particles_collision, float p_strength) {
|
||||
|
@ -5042,7 +5048,7 @@ void RendererStorageRD::particles_collision_set_field_texture(RID p_particles_co
|
|||
void RendererStorageRD::particles_collision_height_field_update(RID p_particles_collision) {
|
||||
ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_particles_collision);
|
||||
ERR_FAIL_COND(!particles_collision);
|
||||
particles_collision->instance_dependency.instance_notify_changed(true, false);
|
||||
particles_collision->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
|
||||
}
|
||||
|
||||
void RendererStorageRD::particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) {
|
||||
|
@ -5096,6 +5102,22 @@ bool RendererStorageRD::particles_collision_is_heightfield(RID p_particles_colli
|
|||
return particles_collision->type == RS::PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE;
|
||||
}
|
||||
|
||||
RID RendererStorageRD::particles_collision_instance_create(RID p_collision) {
|
||||
ParticlesCollisionInstance pci;
|
||||
pci.collision = p_collision;
|
||||
return particles_collision_instance_owner.make_rid(pci);
|
||||
}
|
||||
void RendererStorageRD::particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform) {
|
||||
ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(p_collision_instance);
|
||||
ERR_FAIL_COND(!pci);
|
||||
pci->transform = p_transform;
|
||||
}
|
||||
void RendererStorageRD::particles_collision_instance_set_active(RID p_collision_instance, bool p_active) {
|
||||
ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(p_collision_instance);
|
||||
ERR_FAIL_COND(!pci);
|
||||
pci->active = p_active;
|
||||
}
|
||||
|
||||
/* SKELETON API */
|
||||
|
||||
RID RendererStorageRD::skeleton_create() {
|
||||
|
@ -5149,6 +5171,8 @@ void RendererStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d
|
|||
skeleton->uniform_set_mi = RD::get_singleton()->uniform_set_create(uniforms, skeleton_shader.version_shader[0], SkeletonShader::UNIFORM_SET_SKELETON);
|
||||
}
|
||||
}
|
||||
|
||||
skeleton->dependency.changed_notify(DEPENDENCY_CHANGED_SKELETON_DATA);
|
||||
}
|
||||
|
||||
int RendererStorageRD::skeleton_get_bone_count(RID p_skeleton) const {
|
||||
|
@ -5269,7 +5293,8 @@ void RendererStorageRD::_update_dirty_skeletons() {
|
|||
|
||||
skeleton_dirty_list = skeleton->dirty_list;
|
||||
|
||||
skeleton->instance_dependency.instance_notify_changed(true, false);
|
||||
skeleton->dependency.changed_notify(DEPENDENCY_CHANGED_SKELETON_BONES);
|
||||
|
||||
skeleton->version++;
|
||||
|
||||
skeleton->dirty = false;
|
||||
|
@ -5290,17 +5315,20 @@ RID RendererStorageRD::light_create(RS::LightType p_type) {
|
|||
light.param[RS::LIGHT_PARAM_SPECULAR] = 0.5;
|
||||
light.param[RS::LIGHT_PARAM_RANGE] = 1.0;
|
||||
light.param[RS::LIGHT_PARAM_SIZE] = 0.0;
|
||||
light.param[RS::LIGHT_PARAM_ATTENUATION] = 1.0;
|
||||
light.param[RS::LIGHT_PARAM_SPOT_ANGLE] = 45;
|
||||
light.param[RS::LIGHT_PARAM_SPOT_ATTENUATION] = 1.0;
|
||||
light.param[RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE] = 0;
|
||||
light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET] = 0.1;
|
||||
light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET] = 0.3;
|
||||
light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET] = 0.6;
|
||||
light.param[RS::LIGHT_PARAM_SHADOW_FADE_START] = 0.8;
|
||||
light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02;
|
||||
light.param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 1.0;
|
||||
light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02;
|
||||
light.param[RS::LIGHT_PARAM_SHADOW_BLUR] = 0;
|
||||
light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0;
|
||||
light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05;
|
||||
light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 1.0;
|
||||
light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05;
|
||||
|
||||
return light_owner.make_rid(light);
|
||||
}
|
||||
|
@ -5328,7 +5356,7 @@ void RendererStorageRD::light_set_param(RID p_light, RS::LightParam p_param, flo
|
|||
case RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE:
|
||||
case RS::LIGHT_PARAM_SHADOW_BIAS: {
|
||||
light->version++;
|
||||
light->instance_dependency.instance_notify_changed(true, false);
|
||||
light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
|
||||
} break;
|
||||
default: {
|
||||
}
|
||||
|
@ -5343,7 +5371,7 @@ void RendererStorageRD::light_set_shadow(RID p_light, bool p_enabled) {
|
|||
light->shadow = p_enabled;
|
||||
|
||||
light->version++;
|
||||
light->instance_dependency.instance_notify_changed(true, false);
|
||||
light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
|
||||
}
|
||||
|
||||
void RendererStorageRD::light_set_shadow_color(RID p_light, const Color &p_color) {
|
||||
|
@ -5385,7 +5413,7 @@ void RendererStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) {
|
|||
light->cull_mask = p_mask;
|
||||
|
||||
light->version++;
|
||||
light->instance_dependency.instance_notify_changed(true, false);
|
||||
light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
|
||||
}
|
||||
|
||||
void RendererStorageRD::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) {
|
||||
|
@ -5395,7 +5423,7 @@ void RendererStorageRD::light_set_reverse_cull_face_mode(RID p_light, bool p_ena
|
|||
light->reverse_cull = p_enabled;
|
||||
|
||||
light->version++;
|
||||
light->instance_dependency.instance_notify_changed(true, false);
|
||||
light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
|
||||
}
|
||||
|
||||
void RendererStorageRD::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) {
|
||||
|
@ -5405,7 +5433,7 @@ void RendererStorageRD::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bak
|
|||
light->bake_mode = p_bake_mode;
|
||||
|
||||
light->version++;
|
||||
light->instance_dependency.instance_notify_changed(true, false);
|
||||
light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
|
||||
}
|
||||
|
||||
void RendererStorageRD::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) {
|
||||
|
@ -5415,7 +5443,7 @@ void RendererStorageRD::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_casc
|
|||
light->max_sdfgi_cascade = p_cascade;
|
||||
|
||||
light->version++;
|
||||
light->instance_dependency.instance_notify_changed(true, false);
|
||||
light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
|
||||
}
|
||||
|
||||
void RendererStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) {
|
||||
|
@ -5425,7 +5453,7 @@ void RendererStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniSha
|
|||
light->omni_shadow_mode = p_mode;
|
||||
|
||||
light->version++;
|
||||
light->instance_dependency.instance_notify_changed(true, false);
|
||||
light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
|
||||
}
|
||||
|
||||
RS::LightOmniShadowMode RendererStorageRD::light_omni_get_shadow_mode(RID p_light) {
|
||||
|
@ -5441,7 +5469,7 @@ void RendererStorageRD::light_directional_set_shadow_mode(RID p_light, RS::Light
|
|||
|
||||
light->directional_shadow_mode = p_mode;
|
||||
light->version++;
|
||||
light->instance_dependency.instance_notify_changed(true, false);
|
||||
light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
|
||||
}
|
||||
|
||||
void RendererStorageRD::light_directional_set_blend_splits(RID p_light, bool p_enable) {
|
||||
|
@ -5450,7 +5478,7 @@ void RendererStorageRD::light_directional_set_blend_splits(RID p_light, bool p_e
|
|||
|
||||
light->directional_blend_splits = p_enable;
|
||||
light->version++;
|
||||
light->instance_dependency.instance_notify_changed(true, false);
|
||||
light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT);
|
||||
}
|
||||
|
||||
bool RendererStorageRD::light_directional_get_blend_splits(RID p_light) const {
|
||||
|
@ -5549,7 +5577,7 @@ void RendererStorageRD::reflection_probe_set_update_mode(RID p_probe, RS::Reflec
|
|||
ERR_FAIL_COND(!reflection_probe);
|
||||
|
||||
reflection_probe->update_mode = p_mode;
|
||||
reflection_probe->instance_dependency.instance_notify_changed(true, false);
|
||||
reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
|
||||
}
|
||||
|
||||
void RendererStorageRD::reflection_probe_set_intensity(RID p_probe, float p_intensity) {
|
||||
|
@ -5586,7 +5614,7 @@ void RendererStorageRD::reflection_probe_set_max_distance(RID p_probe, float p_d
|
|||
|
||||
reflection_probe->max_distance = p_distance;
|
||||
|
||||
reflection_probe->instance_dependency.instance_notify_changed(true, false);
|
||||
reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
|
||||
}
|
||||
|
||||
void RendererStorageRD::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {
|
||||
|
@ -5597,7 +5625,7 @@ void RendererStorageRD::reflection_probe_set_extents(RID p_probe, const Vector3
|
|||
return;
|
||||
}
|
||||
reflection_probe->extents = p_extents;
|
||||
reflection_probe->instance_dependency.instance_notify_changed(true, false);
|
||||
reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
|
||||
}
|
||||
|
||||
void RendererStorageRD::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {
|
||||
|
@ -5605,7 +5633,7 @@ void RendererStorageRD::reflection_probe_set_origin_offset(RID p_probe, const Ve
|
|||
ERR_FAIL_COND(!reflection_probe);
|
||||
|
||||
reflection_probe->origin_offset = p_offset;
|
||||
reflection_probe->instance_dependency.instance_notify_changed(true, false);
|
||||
reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
|
||||
}
|
||||
|
||||
void RendererStorageRD::reflection_probe_set_as_interior(RID p_probe, bool p_enable) {
|
||||
|
@ -5613,7 +5641,7 @@ void RendererStorageRD::reflection_probe_set_as_interior(RID p_probe, bool p_ena
|
|||
ERR_FAIL_COND(!reflection_probe);
|
||||
|
||||
reflection_probe->interior = p_enable;
|
||||
reflection_probe->instance_dependency.instance_notify_changed(true, false);
|
||||
reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
|
||||
}
|
||||
|
||||
void RendererStorageRD::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {
|
||||
|
@ -5628,7 +5656,7 @@ void RendererStorageRD::reflection_probe_set_enable_shadows(RID p_probe, bool p_
|
|||
ERR_FAIL_COND(!reflection_probe);
|
||||
|
||||
reflection_probe->enable_shadows = p_enable;
|
||||
reflection_probe->instance_dependency.instance_notify_changed(true, false);
|
||||
reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
|
||||
}
|
||||
|
||||
void RendererStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {
|
||||
|
@ -5636,7 +5664,7 @@ void RendererStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_l
|
|||
ERR_FAIL_COND(!reflection_probe);
|
||||
|
||||
reflection_probe->cull_mask = p_layers;
|
||||
reflection_probe->instance_dependency.instance_notify_changed(true, false);
|
||||
reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
|
||||
}
|
||||
|
||||
void RendererStorageRD::reflection_probe_set_resolution(RID p_probe, int p_resolution) {
|
||||
|
@ -5653,7 +5681,7 @@ void RendererStorageRD::reflection_probe_set_lod_threshold(RID p_probe, float p_
|
|||
|
||||
reflection_probe->lod_threshold = p_ratio;
|
||||
|
||||
reflection_probe->instance_dependency.instance_notify_changed(true, false);
|
||||
reflection_probe->dependency.changed_notify(DEPENDENCY_CHANGED_REFLECTION_PROBE);
|
||||
}
|
||||
|
||||
AABB RendererStorageRD::reflection_probe_get_aabb(RID p_probe) const {
|
||||
|
@ -5771,7 +5799,7 @@ void RendererStorageRD::decal_set_extents(RID p_decal, const Vector3 &p_extents)
|
|||
Decal *decal = decal_owner.getornull(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->extents = p_extents;
|
||||
decal->instance_dependency.instance_notify_changed(true, false);
|
||||
decal->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
|
||||
}
|
||||
|
||||
void RendererStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
|
||||
|
@ -5795,7 +5823,7 @@ void RendererStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type,
|
|||
texture_add_to_decal_atlas(decal->textures[p_type]);
|
||||
}
|
||||
|
||||
decal->instance_dependency.instance_notify_changed(false, true);
|
||||
decal->dependency.changed_notify(DEPENDENCY_CHANGED_DECAL);
|
||||
}
|
||||
|
||||
void RendererStorageRD::decal_set_emission_energy(RID p_decal, float p_energy) {
|
||||
|
@ -5820,7 +5848,7 @@ void RendererStorageRD::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
|
|||
Decal *decal = decal_owner.getornull(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->cull_mask = p_layers;
|
||||
decal->instance_dependency.instance_notify_changed(true, false);
|
||||
decal->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
|
||||
}
|
||||
|
||||
void RendererStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
|
||||
|
@ -5977,7 +6005,7 @@ void RendererStorageRD::gi_probe_allocate(RID p_gi_probe, const Transform &p_to_
|
|||
gi_probe->version++;
|
||||
gi_probe->data_version++;
|
||||
|
||||
gi_probe->instance_dependency.instance_notify_changed(true, false);
|
||||
gi_probe->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
|
||||
}
|
||||
|
||||
AABB RendererStorageRD::gi_probe_get_bounds(RID p_gi_probe) const {
|
||||
|
@ -7055,45 +7083,45 @@ void RendererStorageRD::render_target_set_backbuffer_uniform_set(RID p_render_ta
|
|||
rt->backbuffer_uniform_set = p_uniform_set;
|
||||
}
|
||||
|
||||
void RendererStorageRD::base_update_dependency(RID p_base, InstanceBaseDependency *p_instance) {
|
||||
void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_instance) {
|
||||
if (mesh_owner.owns(p_base)) {
|
||||
Mesh *mesh = mesh_owner.getornull(p_base);
|
||||
p_instance->update_dependency(&mesh->instance_dependency);
|
||||
p_instance->update_dependency(&mesh->dependency);
|
||||
} else if (multimesh_owner.owns(p_base)) {
|
||||
MultiMesh *multimesh = multimesh_owner.getornull(p_base);
|
||||
p_instance->update_dependency(&multimesh->instance_dependency);
|
||||
p_instance->update_dependency(&multimesh->dependency);
|
||||
if (multimesh->mesh.is_valid()) {
|
||||
base_update_dependency(multimesh->mesh, p_instance);
|
||||
}
|
||||
} else if (reflection_probe_owner.owns(p_base)) {
|
||||
ReflectionProbe *rp = reflection_probe_owner.getornull(p_base);
|
||||
p_instance->update_dependency(&rp->instance_dependency);
|
||||
p_instance->update_dependency(&rp->dependency);
|
||||
} else if (decal_owner.owns(p_base)) {
|
||||
Decal *decal = decal_owner.getornull(p_base);
|
||||
p_instance->update_dependency(&decal->instance_dependency);
|
||||
p_instance->update_dependency(&decal->dependency);
|
||||
} else if (gi_probe_owner.owns(p_base)) {
|
||||
GIProbe *gip = gi_probe_owner.getornull(p_base);
|
||||
p_instance->update_dependency(&gip->instance_dependency);
|
||||
p_instance->update_dependency(&gip->dependency);
|
||||
} else if (lightmap_owner.owns(p_base)) {
|
||||
Lightmap *lm = lightmap_owner.getornull(p_base);
|
||||
p_instance->update_dependency(&lm->instance_dependency);
|
||||
p_instance->update_dependency(&lm->dependency);
|
||||
} else if (light_owner.owns(p_base)) {
|
||||
Light *l = light_owner.getornull(p_base);
|
||||
p_instance->update_dependency(&l->instance_dependency);
|
||||
p_instance->update_dependency(&l->dependency);
|
||||
} else if (particles_owner.owns(p_base)) {
|
||||
Particles *p = particles_owner.getornull(p_base);
|
||||
p_instance->update_dependency(&p->instance_dependency);
|
||||
p_instance->update_dependency(&p->dependency);
|
||||
} else if (particles_collision_owner.owns(p_base)) {
|
||||
ParticlesCollision *pc = particles_collision_owner.getornull(p_base);
|
||||
p_instance->update_dependency(&pc->instance_dependency);
|
||||
p_instance->update_dependency(&pc->dependency);
|
||||
}
|
||||
}
|
||||
|
||||
void RendererStorageRD::skeleton_update_dependency(RID p_skeleton, InstanceBaseDependency *p_instance) {
|
||||
void RendererStorageRD::skeleton_update_dependency(RID p_skeleton, DependencyTracker *p_instance) {
|
||||
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
|
||||
ERR_FAIL_COND(!skeleton);
|
||||
|
||||
p_instance->update_dependency(&skeleton->instance_dependency);
|
||||
p_instance->update_dependency(&skeleton->dependency);
|
||||
}
|
||||
|
||||
RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const {
|
||||
|
@ -8114,12 +8142,13 @@ bool RendererStorageRD::free(RID p_rid) {
|
|||
_update_queued_materials();
|
||||
}
|
||||
material_set_shader(p_rid, RID()); //clean up shader
|
||||
material->instance_dependency.instance_notify_deleted(p_rid);
|
||||
material->dependency.deleted_notify(p_rid);
|
||||
|
||||
material_owner.free(p_rid);
|
||||
} else if (mesh_owner.owns(p_rid)) {
|
||||
mesh_clear(p_rid);
|
||||
Mesh *mesh = mesh_owner.getornull(p_rid);
|
||||
mesh->instance_dependency.instance_notify_deleted(p_rid);
|
||||
mesh->dependency.deleted_notify(p_rid);
|
||||
if (mesh->instances.size()) {
|
||||
ERR_PRINT("deleting mesh with active instances");
|
||||
}
|
||||
|
@ -8136,17 +8165,17 @@ bool RendererStorageRD::free(RID p_rid) {
|
|||
_update_dirty_multimeshes();
|
||||
multimesh_allocate(p_rid, 0, RS::MULTIMESH_TRANSFORM_2D);
|
||||
MultiMesh *multimesh = multimesh_owner.getornull(p_rid);
|
||||
multimesh->instance_dependency.instance_notify_deleted(p_rid);
|
||||
multimesh->dependency.deleted_notify(p_rid);
|
||||
multimesh_owner.free(p_rid);
|
||||
} else if (skeleton_owner.owns(p_rid)) {
|
||||
_update_dirty_skeletons();
|
||||
skeleton_allocate(p_rid, 0);
|
||||
Skeleton *skeleton = skeleton_owner.getornull(p_rid);
|
||||
skeleton->instance_dependency.instance_notify_deleted(p_rid);
|
||||
skeleton->dependency.deleted_notify(p_rid);
|
||||
skeleton_owner.free(p_rid);
|
||||
} else if (reflection_probe_owner.owns(p_rid)) {
|
||||
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_rid);
|
||||
reflection_probe->instance_dependency.instance_notify_deleted(p_rid);
|
||||
reflection_probe->dependency.deleted_notify(p_rid);
|
||||
reflection_probe_owner.free(p_rid);
|
||||
} else if (decal_owner.owns(p_rid)) {
|
||||
Decal *decal = decal_owner.getornull(p_rid);
|
||||
|
@ -8155,30 +8184,30 @@ bool RendererStorageRD::free(RID p_rid) {
|
|||
texture_remove_from_decal_atlas(decal->textures[i]);
|
||||
}
|
||||
}
|
||||
decal->instance_dependency.instance_notify_deleted(p_rid);
|
||||
decal->dependency.deleted_notify(p_rid);
|
||||
decal_owner.free(p_rid);
|
||||
} else if (gi_probe_owner.owns(p_rid)) {
|
||||
gi_probe_allocate(p_rid, Transform(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate
|
||||
GIProbe *gi_probe = gi_probe_owner.getornull(p_rid);
|
||||
gi_probe->instance_dependency.instance_notify_deleted(p_rid);
|
||||
gi_probe->dependency.deleted_notify(p_rid);
|
||||
gi_probe_owner.free(p_rid);
|
||||
} else if (lightmap_owner.owns(p_rid)) {
|
||||
lightmap_set_textures(p_rid, RID(), false);
|
||||
Lightmap *lightmap = lightmap_owner.getornull(p_rid);
|
||||
lightmap->instance_dependency.instance_notify_deleted(p_rid);
|
||||
lightmap->dependency.deleted_notify(p_rid);
|
||||
lightmap_owner.free(p_rid);
|
||||
|
||||
} else if (light_owner.owns(p_rid)) {
|
||||
light_set_projector(p_rid, RID()); //clear projector
|
||||
// delete the texture
|
||||
Light *light = light_owner.getornull(p_rid);
|
||||
light->instance_dependency.instance_notify_deleted(p_rid);
|
||||
light->dependency.deleted_notify(p_rid);
|
||||
light_owner.free(p_rid);
|
||||
|
||||
} else if (particles_owner.owns(p_rid)) {
|
||||
Particles *particles = particles_owner.getornull(p_rid);
|
||||
_particles_free_data(particles);
|
||||
particles->instance_dependency.instance_notify_deleted(p_rid);
|
||||
particles->dependency.deleted_notify(p_rid);
|
||||
particles_owner.free(p_rid);
|
||||
} else if (particles_collision_owner.owns(p_rid)) {
|
||||
ParticlesCollision *particles_collision = particles_collision_owner.getornull(p_rid);
|
||||
|
@ -8186,8 +8215,10 @@ bool RendererStorageRD::free(RID p_rid) {
|
|||
if (particles_collision->heightfield_texture.is_valid()) {
|
||||
RD::get_singleton()->free(particles_collision->heightfield_texture);
|
||||
}
|
||||
particles_collision->instance_dependency.instance_notify_deleted(p_rid);
|
||||
particles_collision->dependency.deleted_notify(p_rid);
|
||||
particles_collision_owner.free(p_rid);
|
||||
} else if (particles_collision_instance_owner.owns(p_rid)) {
|
||||
particles_collision_instance_owner.free(p_rid);
|
||||
} else if (render_target_owner.owns(p_rid)) {
|
||||
RenderTarget *rt = render_target_owner.getornull(p_rid);
|
||||
|
||||
|
|
|
@ -360,6 +360,7 @@ private:
|
|||
Shader *shader;
|
||||
//shortcut to shader data and type
|
||||
ShaderType shader_type;
|
||||
uint32_t shader_id = 0;
|
||||
bool update_requested;
|
||||
bool uniform_dirty;
|
||||
bool texture_dirty;
|
||||
|
@ -367,7 +368,7 @@ private:
|
|||
Map<StringName, Variant> params;
|
||||
int32_t priority;
|
||||
RID next_pass;
|
||||
RendererStorage::InstanceDependency instance_dependency;
|
||||
Dependency dependency;
|
||||
};
|
||||
|
||||
MaterialDataRequestFunction material_data_request_func[SHADER_TYPE_MAX];
|
||||
|
@ -460,7 +461,7 @@ private:
|
|||
|
||||
List<MeshInstance *> instances;
|
||||
|
||||
RendererStorage::InstanceDependency instance_dependency;
|
||||
Dependency dependency;
|
||||
};
|
||||
|
||||
mutable RID_Owner<Mesh> mesh_owner;
|
||||
|
@ -563,7 +564,7 @@ private:
|
|||
bool dirty = false;
|
||||
MultiMesh *dirty_list = nullptr;
|
||||
|
||||
RendererStorage::InstanceDependency instance_dependency;
|
||||
Dependency dependency;
|
||||
};
|
||||
|
||||
mutable RID_Owner<MultiMesh> multimesh_owner;
|
||||
|
@ -734,7 +735,7 @@ private:
|
|||
ParticleEmissionBuffer *emission_buffer = nullptr;
|
||||
RID emission_storage_buffer;
|
||||
|
||||
Set<RendererSceneRender::InstanceBase *> collisions;
|
||||
Set<RID> collisions;
|
||||
|
||||
Particles() :
|
||||
inactive(true),
|
||||
|
@ -761,7 +762,7 @@ private:
|
|||
clear(true) {
|
||||
}
|
||||
|
||||
RendererStorage::InstanceDependency instance_dependency;
|
||||
Dependency dependency;
|
||||
|
||||
ParticlesFrameParams frame_params;
|
||||
};
|
||||
|
@ -889,11 +890,19 @@ private:
|
|||
|
||||
RS::ParticlesCollisionHeightfieldResolution heightfield_resolution = RS::PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_1024;
|
||||
|
||||
RendererStorage::InstanceDependency instance_dependency;
|
||||
Dependency dependency;
|
||||
};
|
||||
|
||||
mutable RID_Owner<ParticlesCollision> particles_collision_owner;
|
||||
|
||||
struct ParticlesCollisionInstance {
|
||||
RID collision;
|
||||
Transform transform;
|
||||
bool active = false;
|
||||
};
|
||||
|
||||
mutable RID_Owner<ParticlesCollisionInstance> particles_collision_instance_owner;
|
||||
|
||||
/* Skeleton */
|
||||
|
||||
struct Skeleton {
|
||||
|
@ -911,7 +920,7 @@ private:
|
|||
|
||||
uint64_t version = 1;
|
||||
|
||||
RendererStorage::InstanceDependency instance_dependency;
|
||||
Dependency dependency;
|
||||
};
|
||||
|
||||
mutable RID_Owner<Skeleton> skeleton_owner;
|
||||
|
@ -943,7 +952,7 @@ private:
|
|||
bool directional_sky_only = false;
|
||||
uint64_t version = 0;
|
||||
|
||||
RendererStorage::InstanceDependency instance_dependency;
|
||||
Dependency dependency;
|
||||
};
|
||||
|
||||
mutable RID_Owner<Light> light_owner;
|
||||
|
@ -966,7 +975,7 @@ private:
|
|||
uint32_t cull_mask = (1 << 20) - 1;
|
||||
float lod_threshold = 0.01;
|
||||
|
||||
RendererStorage::InstanceDependency instance_dependency;
|
||||
Dependency dependency;
|
||||
};
|
||||
|
||||
mutable RID_Owner<ReflectionProbe> reflection_probe_owner;
|
||||
|
@ -987,7 +996,7 @@ private:
|
|||
float distance_fade_length = 1;
|
||||
float normal_fade = 0.0;
|
||||
|
||||
RendererStorage::InstanceDependency instance_dependency;
|
||||
Dependency dependency;
|
||||
};
|
||||
|
||||
mutable RID_Owner<Decal> decal_owner;
|
||||
|
@ -1025,7 +1034,7 @@ private:
|
|||
uint32_t version = 1;
|
||||
uint32_t data_version = 1;
|
||||
|
||||
RendererStorage::InstanceDependency instance_dependency;
|
||||
Dependency dependency;
|
||||
};
|
||||
|
||||
GiprobeSdfShaderRD giprobe_sdf_shader;
|
||||
|
@ -1054,7 +1063,7 @@ private:
|
|||
int32_t over = EMPTY_LEAF, under = EMPTY_LEAF;
|
||||
};
|
||||
|
||||
RendererStorage::InstanceDependency instance_dependency;
|
||||
Dependency dependency;
|
||||
};
|
||||
|
||||
bool using_lightmap_array; //high end uses this
|
||||
|
@ -1347,11 +1356,16 @@ public:
|
|||
|
||||
void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters);
|
||||
|
||||
void material_update_dependency(RID p_material, InstanceBaseDependency *p_instance);
|
||||
void material_update_dependency(RID p_material, DependencyTracker *p_instance);
|
||||
void material_force_update_textures(RID p_material, ShaderType p_shader_type);
|
||||
|
||||
void material_set_data_request_function(ShaderType p_shader_type, MaterialDataRequestFunction p_function);
|
||||
|
||||
_FORCE_INLINE_ uint32_t material_get_shader_id(RID p_material) {
|
||||
Material *material = material_owner.getornull(p_material);
|
||||
return material->shader_id;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ MaterialData *material_get_data(RID p_material, ShaderType p_shader_type) {
|
||||
Material *material = material_owner.getornull(p_material);
|
||||
if (!material || material->shader_type != p_shader_type) {
|
||||
|
@ -1664,6 +1678,10 @@ public:
|
|||
void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform);
|
||||
Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const;
|
||||
|
||||
_FORCE_INLINE_ bool skeleton_is_valid(RID p_skeleton) {
|
||||
return skeleton_owner.getornull(p_skeleton) != nullptr;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RID skeleton_get_3d_uniform_set(RID p_skeleton, RID p_shader, uint32_t p_set) const {
|
||||
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
|
||||
ERR_FAIL_COND_V(!skeleton, RID());
|
||||
|
@ -1827,8 +1845,8 @@ public:
|
|||
Color reflection_probe_get_ambient_color(RID p_probe) const;
|
||||
float reflection_probe_get_ambient_color_energy(RID p_probe) const;
|
||||
|
||||
void base_update_dependency(RID p_base, InstanceBaseDependency *p_instance);
|
||||
void skeleton_update_dependency(RID p_skeleton, InstanceBaseDependency *p_instance);
|
||||
void base_update_dependency(RID p_base, DependencyTracker *p_instance);
|
||||
void skeleton_update_dependency(RID p_skeleton, DependencyTracker *p_instance);
|
||||
|
||||
/* DECAL API */
|
||||
|
||||
|
@ -1977,7 +1995,11 @@ public:
|
|||
_FORCE_INLINE_ float lightmap_get_probe_capture_update_speed() const {
|
||||
return lightmap_probe_capture_update_speed;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RID lightmap_get_texture(RID p_lightmap) const {
|
||||
const Lightmap *lm = lightmap_owner.getornull(p_lightmap);
|
||||
ERR_FAIL_COND_V(!lm, RID());
|
||||
return lm->light_texture;
|
||||
}
|
||||
_FORCE_INLINE_ int32_t lightmap_get_array_index(RID p_lightmap) const {
|
||||
ERR_FAIL_COND_V(!using_lightmap_array, -1); //only for arrays
|
||||
const Lightmap *lm = lightmap_owner.getornull(p_lightmap);
|
||||
|
@ -2078,8 +2100,8 @@ public:
|
|||
return particles->particles_transforms_buffer_uniform_set;
|
||||
}
|
||||
|
||||
virtual void particles_add_collision(RID p_particles, InstanceBaseDependency *p_instance);
|
||||
virtual void particles_remove_collision(RID p_particles, InstanceBaseDependency *p_instance);
|
||||
virtual void particles_add_collision(RID p_particles, RID p_particles_collision_instance);
|
||||
virtual void particles_remove_collision(RID p_particles, RID p_particles_collision_instance);
|
||||
|
||||
/* PARTICLES COLLISION */
|
||||
|
||||
|
@ -2099,6 +2121,11 @@ public:
|
|||
virtual bool particles_collision_is_heightfield(RID p_particles_collision) const;
|
||||
RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const;
|
||||
|
||||
//used from 2D and 3D
|
||||
virtual RID particles_collision_instance_create(RID p_collision);
|
||||
virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform);
|
||||
virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active);
|
||||
|
||||
/* GLOBAL VARIABLES API */
|
||||
|
||||
virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value);
|
||||
|
|
|
@ -360,7 +360,7 @@ void ShaderRD::_compile_version(Version *p_version) {
|
|||
p_version->variants = memnew_arr(RID, variant_defines.size());
|
||||
#if 1
|
||||
|
||||
RendererCompositorRD::thread_work_pool.do_work(variant_defines.size(), this, &ShaderRD::_compile_variant, p_version);
|
||||
RendererThreadPool::singleton->thread_work_pool.do_work(variant_defines.size(), this, &ShaderRD::_compile_variant, p_version);
|
||||
#else
|
||||
for (int i = 0; i < variant_defines.size(); i++) {
|
||||
_compile_variant(i, p_version);
|
||||
|
|
|
@ -97,8 +97,6 @@ VERTEX_SHADER_GLOBALS
|
|||
|
||||
invariant gl_Position;
|
||||
|
||||
layout(location = 7) flat out uint instance_index;
|
||||
|
||||
#ifdef MODE_DUAL_PARABOLOID
|
||||
|
||||
layout(location = 8) out float dp_clip;
|
||||
|
@ -106,22 +104,27 @@ layout(location = 8) out float dp_clip;
|
|||
#endif
|
||||
|
||||
void main() {
|
||||
instance_index = draw_call.instance_index;
|
||||
vec4 instance_custom = vec4(0.0);
|
||||
#if defined(COLOR_USED)
|
||||
color_interp = color_attrib;
|
||||
#endif
|
||||
|
||||
mat4 world_matrix = instances.data[instance_index].transform;
|
||||
mat3 world_normal_matrix = mat3(instances.data[instance_index].normal_transform);
|
||||
mat4 world_matrix = draw_call.transform;
|
||||
|
||||
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH)) {
|
||||
mat3 world_normal_matrix;
|
||||
if (bool(draw_call.flags & INSTANCE_FLAGS_NON_UNIFORM_SCALE)) {
|
||||
world_normal_matrix = inverse(mat3(world_matrix));
|
||||
} else {
|
||||
world_normal_matrix = mat3(world_matrix);
|
||||
}
|
||||
|
||||
if (bool(draw_call.flags & INSTANCE_FLAGS_MULTIMESH)) {
|
||||
//multimesh, instances are for it
|
||||
uint offset = (instances.data[instance_index].flags >> INSTANCE_FLAGS_MULTIMESH_STRIDE_SHIFT) & INSTANCE_FLAGS_MULTIMESH_STRIDE_MASK;
|
||||
uint offset = (draw_call.flags >> INSTANCE_FLAGS_MULTIMESH_STRIDE_SHIFT) & INSTANCE_FLAGS_MULTIMESH_STRIDE_MASK;
|
||||
offset *= gl_InstanceIndex;
|
||||
|
||||
mat4 matrix;
|
||||
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) {
|
||||
if (bool(draw_call.flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) {
|
||||
matrix = mat4(transforms.data[offset + 0], transforms.data[offset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));
|
||||
offset += 2;
|
||||
} else {
|
||||
|
@ -129,14 +132,14 @@ void main() {
|
|||
offset += 3;
|
||||
}
|
||||
|
||||
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) {
|
||||
if (bool(draw_call.flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) {
|
||||
#ifdef COLOR_USED
|
||||
color_interp *= transforms.data[offset];
|
||||
#endif
|
||||
offset += 1;
|
||||
}
|
||||
|
||||
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) {
|
||||
if (bool(draw_call.flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) {
|
||||
instance_custom = transforms.data[offset];
|
||||
}
|
||||
|
||||
|
@ -144,10 +147,6 @@ void main() {
|
|||
matrix = transpose(matrix);
|
||||
world_matrix = world_matrix * matrix;
|
||||
world_normal_matrix = world_normal_matrix * mat3(matrix);
|
||||
|
||||
} else {
|
||||
//not a multimesh, instances are for multiple draw calls
|
||||
instance_index += gl_InstanceIndex;
|
||||
}
|
||||
|
||||
vec3 vertex = vertex_attrib;
|
||||
|
@ -162,7 +161,7 @@ void main() {
|
|||
#endif
|
||||
|
||||
#if 0
|
||||
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_SKELETON)) {
|
||||
if (bool(draw_call.flags & INSTANCE_FLAGS_SKELETON)) {
|
||||
//multimesh, instances are for it
|
||||
|
||||
uvec2 bones_01 = uvec2(bone_attrib.x & 0xFFFF, bone_attrib.x >> 16) * 3;
|
||||
|
@ -305,7 +304,7 @@ VERTEX_SHADER_CODE
|
|||
#endif
|
||||
#ifdef MODE_RENDER_MATERIAL
|
||||
if (scene_data.material_uv2_mode) {
|
||||
gl_Position.xy = (uv2_attrib.xy + draw_call.bake_uv2_offset) * 2.0 - 1.0;
|
||||
gl_Position.xy = (uv2_attrib.xy + draw_call.lightmap_uv_scale.xy) * 2.0 - 1.0;
|
||||
gl_Position.z = 0.00001;
|
||||
gl_Position.w = 1.0;
|
||||
}
|
||||
|
@ -345,8 +344,6 @@ layout(location = 5) in vec3 tangent_interp;
|
|||
layout(location = 6) in vec3 binormal_interp;
|
||||
#endif
|
||||
|
||||
layout(location = 7) flat in uint instance_index;
|
||||
|
||||
#ifdef MODE_DUAL_PARABOLOID
|
||||
|
||||
layout(location = 8) in float dp_clip;
|
||||
|
@ -355,8 +352,7 @@ layout(location = 8) in float dp_clip;
|
|||
|
||||
//defines to keep compatibility with vertex
|
||||
|
||||
#define world_matrix instances.data[instance_index].transform
|
||||
#define world_normal_matrix instances.data[instance_index].normal_transform
|
||||
#define world_matrix draw_call.transform
|
||||
#define projection_matrix scene_data.projection_matrix
|
||||
|
||||
#if defined(ENABLE_SSS) && defined(ENABLE_TRANSMITTANCE)
|
||||
|
@ -1971,7 +1967,7 @@ FRAGMENT_SHADER_CODE
|
|||
|
||||
for (uint i = 0; i < decal_count; i++) {
|
||||
uint decal_index = cluster_data.indices[decal_pointer + i];
|
||||
if (!bool(decals.data[decal_index].mask & instances.data[instance_index].layer_mask)) {
|
||||
if (!bool(decals.data[decal_index].mask & draw_call.layer_mask)) {
|
||||
continue; //not masked
|
||||
}
|
||||
|
||||
|
@ -2102,8 +2098,8 @@ FRAGMENT_SHADER_CODE
|
|||
#ifdef USE_LIGHTMAP
|
||||
|
||||
//lightmap
|
||||
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE)) { //has lightmap capture
|
||||
uint index = instances.data[instance_index].gi_offset;
|
||||
if (bool(draw_call.flags & INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE)) { //has lightmap capture
|
||||
uint index = draw_call.gi_offset;
|
||||
|
||||
vec3 wnormal = mat3(scene_data.camera_matrix) * normal;
|
||||
const float c1 = 0.429043;
|
||||
|
@ -2122,12 +2118,12 @@ FRAGMENT_SHADER_CODE
|
|||
2.0 * c2 * lightmap_captures.data[index].sh[1].rgb * wnormal.y +
|
||||
2.0 * c2 * lightmap_captures.data[index].sh[2].rgb * wnormal.z);
|
||||
|
||||
} else if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { // has actual lightmap
|
||||
bool uses_sh = bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_SH_LIGHTMAP);
|
||||
uint ofs = instances.data[instance_index].gi_offset & 0xFFF;
|
||||
} else if (bool(draw_call.flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { // has actual lightmap
|
||||
bool uses_sh = bool(draw_call.flags & INSTANCE_FLAGS_USE_SH_LIGHTMAP);
|
||||
uint ofs = draw_call.gi_offset & 0xFFFF;
|
||||
vec3 uvw;
|
||||
uvw.xy = uv2 * instances.data[instance_index].lightmap_uv_scale.zw + instances.data[instance_index].lightmap_uv_scale.xy;
|
||||
uvw.z = float((instances.data[instance_index].gi_offset >> 12) & 0xFF);
|
||||
uvw.xy = uv2 * draw_call.lightmap_uv_scale.zw + draw_call.lightmap_uv_scale.xy;
|
||||
uvw.z = float((draw_call.gi_offset >> 16) & 0xFFFF);
|
||||
|
||||
if (uses_sh) {
|
||||
uvw.z *= 4.0; //SH textures use 4 times more data
|
||||
|
@ -2136,7 +2132,7 @@ FRAGMENT_SHADER_CODE
|
|||
vec3 lm_light_l1_0 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 2.0), 0.0).rgb;
|
||||
vec3 lm_light_l1p1 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 3.0), 0.0).rgb;
|
||||
|
||||
uint idx = instances.data[instance_index].gi_offset >> 20;
|
||||
uint idx = draw_call.gi_offset >> 20;
|
||||
vec3 n = normalize(lightmaps.data[idx].normal_xform * normal);
|
||||
|
||||
ambient_light += lm_light_l0 * 0.282095f;
|
||||
|
@ -2156,7 +2152,7 @@ FRAGMENT_SHADER_CODE
|
|||
}
|
||||
#elif defined(USE_FORWARD_GI)
|
||||
|
||||
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_SDFGI)) { //has lightmap capture
|
||||
if (bool(draw_call.flags & INSTANCE_FLAGS_USE_SDFGI)) { //has lightmap capture
|
||||
|
||||
//make vertex orientation the world one, but still align to camera
|
||||
vec3 cam_pos = mat3(scene_data.camera_matrix) * vertex;
|
||||
|
@ -2228,9 +2224,9 @@ FRAGMENT_SHADER_CODE
|
|||
}
|
||||
}
|
||||
|
||||
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes
|
||||
if (bool(draw_call.flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes
|
||||
|
||||
uint index1 = instances.data[instance_index].gi_offset & 0xFFFF;
|
||||
uint index1 = draw_call.gi_offset & 0xFFFF;
|
||||
vec3 ref_vec = normalize(reflect(normalize(vertex), normal));
|
||||
//find arbitrary tangent and bitangent, then build a matrix
|
||||
vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);
|
||||
|
@ -2242,7 +2238,7 @@ FRAGMENT_SHADER_CODE
|
|||
vec4 spec_accum = vec4(0.0);
|
||||
gi_probe_compute(index1, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum);
|
||||
|
||||
uint index2 = instances.data[instance_index].gi_offset >> 16;
|
||||
uint index2 = draw_call.gi_offset >> 16;
|
||||
|
||||
if (index2 != 0xFFFF) {
|
||||
gi_probe_compute(index2, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum);
|
||||
|
@ -2261,7 +2257,7 @@ FRAGMENT_SHADER_CODE
|
|||
}
|
||||
#elif !defined(LOW_END_MODE)
|
||||
|
||||
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GI_BUFFERS)) { //use GI buffers
|
||||
if (bool(draw_call.flags & INSTANCE_FLAGS_USE_GI_BUFFERS)) { //use GI buffers
|
||||
|
||||
ivec2 coord;
|
||||
|
||||
|
@ -2343,7 +2339,7 @@ FRAGMENT_SHADER_CODE
|
|||
{ //directional light
|
||||
|
||||
for (uint i = 0; i < scene_data.directional_light_count; i++) {
|
||||
if (!bool(directional_lights.data[i].mask & instances.data[instance_index].layer_mask)) {
|
||||
if (!bool(directional_lights.data[i].mask & draw_call.layer_mask)) {
|
||||
continue; //not masked
|
||||
}
|
||||
|
||||
|
@ -2613,7 +2609,7 @@ FRAGMENT_SHADER_CODE
|
|||
for (uint i = 0; i < omni_light_count; i++) {
|
||||
uint light_index = cluster_data.indices[omni_light_pointer + i];
|
||||
|
||||
if (!bool(lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
|
||||
if (!bool(lights.data[light_index].mask & draw_call.layer_mask)) {
|
||||
continue; //not masked
|
||||
}
|
||||
|
||||
|
@ -2651,7 +2647,7 @@ FRAGMENT_SHADER_CODE
|
|||
for (uint i = 0; i < spot_light_count; i++) {
|
||||
uint light_index = cluster_data.indices[spot_light_pointer + i];
|
||||
|
||||
if (!bool(lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
|
||||
if (!bool(lights.data[light_index].mask & draw_call.layer_mask)) {
|
||||
continue; //not masked
|
||||
}
|
||||
|
||||
|
@ -2822,9 +2818,9 @@ FRAGMENT_SHADER_CODE
|
|||
normal_roughness_output_buffer = vec4(normal * 0.5 + 0.5, roughness);
|
||||
|
||||
#ifdef MODE_RENDER_GIPROBE
|
||||
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes
|
||||
uint index1 = instances.data[instance_index].gi_offset & 0xFFFF;
|
||||
uint index2 = instances.data[instance_index].gi_offset >> 16;
|
||||
if (bool(draw_call.flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes
|
||||
uint index1 = draw_call.gi_offset & 0xFFFF;
|
||||
uint index2 = draw_call.gi_offset >> 16;
|
||||
giprobe_buffer.x = index1 & 0xFF;
|
||||
giprobe_buffer.y = index2 & 0xFF;
|
||||
} else {
|
||||
|
|
|
@ -12,9 +12,12 @@
|
|||
#endif
|
||||
|
||||
layout(push_constant, binding = 0, std430) uniform DrawCall {
|
||||
uint instance_index;
|
||||
uint pad; //16 bits minimum size
|
||||
vec2 bake_uv2_offset; //used for bake to uv2, ignored otherwise
|
||||
mat4 transform;
|
||||
uint flags;
|
||||
uint instance_uniforms_ofs; //base offset in global buffer for instance variables
|
||||
uint gi_offset; //GI information when using lightmapping (VCT or lightmap index)
|
||||
uint layer_mask;
|
||||
vec4 lightmap_uv_scale;
|
||||
}
|
||||
draw_call;
|
||||
|
||||
|
@ -134,21 +137,7 @@ scene_data;
|
|||
#define INSTANCE_FLAGS_MULTIMESH_STRIDE_MASK 0x7
|
||||
|
||||
#define INSTANCE_FLAGS_SKELETON (1 << 19)
|
||||
|
||||
struct InstanceData {
|
||||
mat4 transform;
|
||||
mat4 normal_transform;
|
||||
uint flags;
|
||||
uint instance_uniforms_ofs; //base offset in global buffer for instance variables
|
||||
uint gi_offset; //GI information when using lightmapping (VCT or lightmap index)
|
||||
uint layer_mask;
|
||||
vec4 lightmap_uv_scale;
|
||||
};
|
||||
|
||||
layout(set = 0, binding = 4, std430) restrict readonly buffer Instances {
|
||||
InstanceData data[];
|
||||
}
|
||||
instances;
|
||||
#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 20)
|
||||
|
||||
layout(set = 0, binding = 5, std430) restrict readonly buffer Lights {
|
||||
LightData data[];
|
||||
|
@ -177,35 +166,33 @@ layout(set = 0, binding = 10, std140) restrict readonly buffer Lightmaps {
|
|||
}
|
||||
lightmaps;
|
||||
|
||||
layout(set = 0, binding = 11) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES];
|
||||
|
||||
struct LightmapCapture {
|
||||
vec4 sh[9];
|
||||
};
|
||||
|
||||
layout(set = 0, binding = 12, std140) restrict readonly buffer LightmapCaptures {
|
||||
layout(set = 0, binding = 11, std140) restrict readonly buffer LightmapCaptures {
|
||||
LightmapCapture data[];
|
||||
}
|
||||
lightmap_captures;
|
||||
|
||||
layout(set = 0, binding = 13) uniform texture2D decal_atlas;
|
||||
layout(set = 0, binding = 14) uniform texture2D decal_atlas_srgb;
|
||||
layout(set = 0, binding = 12) uniform texture2D decal_atlas;
|
||||
layout(set = 0, binding = 13) uniform texture2D decal_atlas_srgb;
|
||||
|
||||
layout(set = 0, binding = 15, std430) restrict readonly buffer Decals {
|
||||
layout(set = 0, binding = 14, std430) restrict readonly buffer Decals {
|
||||
DecalData data[];
|
||||
}
|
||||
decals;
|
||||
|
||||
layout(set = 0, binding = 16) uniform utexture3D cluster_texture;
|
||||
layout(set = 0, binding = 15) uniform utexture3D cluster_texture;
|
||||
|
||||
layout(set = 0, binding = 17, std430) restrict readonly buffer ClusterData {
|
||||
layout(set = 0, binding = 16, std430) restrict readonly buffer ClusterData {
|
||||
uint indices[];
|
||||
}
|
||||
cluster_data;
|
||||
|
||||
layout(set = 0, binding = 18) uniform texture2D directional_shadow_atlas;
|
||||
layout(set = 0, binding = 17) uniform texture2D directional_shadow_atlas;
|
||||
|
||||
layout(set = 0, binding = 19, std430) restrict readonly buffer GlobalVariableData {
|
||||
layout(set = 0, binding = 18, std430) restrict readonly buffer GlobalVariableData {
|
||||
vec4 data[];
|
||||
}
|
||||
global_variables;
|
||||
|
@ -219,7 +206,7 @@ struct SDFGIProbeCascadeData {
|
|||
float to_cell; // 1/bounds * grid_size
|
||||
};
|
||||
|
||||
layout(set = 0, binding = 20, std140) uniform SDFGI {
|
||||
layout(set = 0, binding = 19, std140) uniform SDFGI {
|
||||
vec3 grid_size;
|
||||
uint max_cascades;
|
||||
|
||||
|
@ -269,18 +256,20 @@ layout(set = 1, binding = 1) uniform textureCubeArray reflection_atlas;
|
|||
|
||||
layout(set = 1, binding = 2) uniform texture2D shadow_atlas;
|
||||
|
||||
layout(set = 1, binding = 3) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES];
|
||||
|
||||
#ifndef LOW_END_MODE
|
||||
layout(set = 1, binding = 3) uniform texture3D gi_probe_textures[MAX_GI_PROBES];
|
||||
layout(set = 1, binding = 4) uniform texture3D gi_probe_textures[MAX_GI_PROBES];
|
||||
#endif
|
||||
|
||||
/* Set 3, Render Buffers */
|
||||
|
||||
#ifdef MODE_RENDER_SDF
|
||||
|
||||
layout(r16ui, set = 1, binding = 4) uniform restrict writeonly uimage3D albedo_volume_grid;
|
||||
layout(r32ui, set = 1, binding = 5) uniform restrict writeonly uimage3D emission_grid;
|
||||
layout(r32ui, set = 1, binding = 6) uniform restrict writeonly uimage3D emission_aniso_grid;
|
||||
layout(r32ui, set = 1, binding = 7) uniform restrict uimage3D geom_facing_grid;
|
||||
layout(r16ui, set = 1, binding = 5) uniform restrict writeonly uimage3D albedo_volume_grid;
|
||||
layout(r32ui, set = 1, binding = 6) uniform restrict writeonly uimage3D emission_grid;
|
||||
layout(r32ui, set = 1, binding = 7) uniform restrict writeonly uimage3D emission_aniso_grid;
|
||||
layout(r32ui, set = 1, binding = 8) uniform restrict uimage3D geom_facing_grid;
|
||||
|
||||
//still need to be present for shaders that use it, so remap them to something
|
||||
#define depth_buffer shadow_atlas
|
||||
|
@ -289,17 +278,17 @@ layout(r32ui, set = 1, binding = 7) uniform restrict uimage3D geom_facing_grid;
|
|||
|
||||
#else
|
||||
|
||||
layout(set = 1, binding = 4) uniform texture2D depth_buffer;
|
||||
layout(set = 1, binding = 5) uniform texture2D color_buffer;
|
||||
layout(set = 1, binding = 5) uniform texture2D depth_buffer;
|
||||
layout(set = 1, binding = 6) uniform texture2D color_buffer;
|
||||
|
||||
#ifndef LOW_END_MODE
|
||||
|
||||
layout(set = 1, binding = 6) uniform texture2D normal_roughness_buffer;
|
||||
layout(set = 1, binding = 7) uniform texture2D ao_buffer;
|
||||
layout(set = 1, binding = 8) uniform texture2D ambient_buffer;
|
||||
layout(set = 1, binding = 9) uniform texture2D reflection_buffer;
|
||||
layout(set = 1, binding = 10) uniform texture2DArray sdfgi_lightprobe_texture;
|
||||
layout(set = 1, binding = 11) uniform texture3D sdfgi_occlusion_cascades;
|
||||
layout(set = 1, binding = 7) uniform texture2D normal_roughness_buffer;
|
||||
layout(set = 1, binding = 8) uniform texture2D ao_buffer;
|
||||
layout(set = 1, binding = 9) uniform texture2D ambient_buffer;
|
||||
layout(set = 1, binding = 10) uniform texture2D reflection_buffer;
|
||||
layout(set = 1, binding = 11) uniform texture2DArray sdfgi_lightprobe_texture;
|
||||
layout(set = 1, binding = 12) uniform texture3D sdfgi_occlusion_cascades;
|
||||
|
||||
struct GIProbeData {
|
||||
mat4 xform;
|
||||
|
@ -317,12 +306,12 @@ struct GIProbeData {
|
|||
uint mipmaps;
|
||||
};
|
||||
|
||||
layout(set = 1, binding = 12, std140) uniform GIProbes {
|
||||
layout(set = 1, binding = 13, std140) uniform GIProbes {
|
||||
GIProbeData data[MAX_GI_PROBES];
|
||||
}
|
||||
gi_probes;
|
||||
|
||||
layout(set = 1, binding = 13) uniform texture3D volumetric_fog_texture;
|
||||
layout(set = 1, binding = 14) uniform texture3D volumetric_fog_texture;
|
||||
|
||||
#endif // LOW_END_MODE
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -53,7 +53,8 @@ public:
|
|||
|
||||
enum {
|
||||
SDFGI_MAX_CASCADES = 8,
|
||||
SDFGI_MAX_REGIONS_PER_CASCADE = 3
|
||||
SDFGI_MAX_REGIONS_PER_CASCADE = 3,
|
||||
MAX_INSTANCE_PAIRS = 32
|
||||
};
|
||||
|
||||
uint64_t render_pass;
|
||||
|
@ -249,7 +250,10 @@ public:
|
|||
uint32_t flags = 0;
|
||||
uint32_t layer_mask = 0; //for fast layer-mask discard
|
||||
RID base_rid;
|
||||
RID instance_data_rid;
|
||||
union {
|
||||
uint64_t instance_data_rid;
|
||||
RendererSceneRender::GeometryInstance *instance_geometry;
|
||||
};
|
||||
Instance *instance = nullptr;
|
||||
};
|
||||
|
||||
|
@ -296,7 +300,7 @@ public:
|
|||
static void _instance_pair(Instance *p_A, Instance *p_B);
|
||||
static void _instance_unpair(Instance *p_A, Instance *p_B);
|
||||
|
||||
static void _instance_update_mesh_instance(Instance *p_instance);
|
||||
void _instance_update_mesh_instance(Instance *p_instance);
|
||||
|
||||
virtual RID scenario_create();
|
||||
|
||||
|
@ -325,7 +329,55 @@ public:
|
|||
virtual ~InstanceBaseData() {}
|
||||
};
|
||||
|
||||
struct Instance : RendererSceneRender::InstanceBase {
|
||||
struct Instance {
|
||||
RS::InstanceType base_type;
|
||||
RID base;
|
||||
|
||||
RID skeleton;
|
||||
RID material_override;
|
||||
|
||||
RID mesh_instance; //only used for meshes and when skeleton/blendshapes exist
|
||||
|
||||
Transform transform;
|
||||
|
||||
float lod_bias;
|
||||
|
||||
Vector<RID> materials;
|
||||
|
||||
RS::ShadowCastingSetting cast_shadows;
|
||||
|
||||
uint32_t layer_mask;
|
||||
//fit in 32 bits
|
||||
bool mirror : 8;
|
||||
bool receive_shadows : 8;
|
||||
bool visible : 8;
|
||||
bool baked_light : 2; //this flag is only to know if it actually did use baked light
|
||||
bool dynamic_gi : 2; //same above for dynamic objects
|
||||
bool redraw_if_visible : 4;
|
||||
|
||||
Instance *lightmap;
|
||||
Rect2 lightmap_uv_scale;
|
||||
int lightmap_slice_index;
|
||||
uint32_t lightmap_cull_index;
|
||||
Vector<Color> lightmap_sh; //spherical harmonic
|
||||
|
||||
AABB aabb;
|
||||
AABB transformed_aabb;
|
||||
AABB prev_transformed_aabb;
|
||||
|
||||
struct InstanceShaderParameter {
|
||||
int32_t index = -1;
|
||||
Variant value;
|
||||
Variant default_value;
|
||||
PropertyInfo info;
|
||||
};
|
||||
|
||||
Map<StringName, InstanceShaderParameter> instance_shader_parameters;
|
||||
bool instance_allocated_shader_parameters = false;
|
||||
int32_t instance_allocated_shader_parameters_offset = -1;
|
||||
|
||||
//
|
||||
|
||||
RID self;
|
||||
//scenario stuff
|
||||
DynamicBVH::ID indexer_id;
|
||||
|
@ -360,23 +412,61 @@ public:
|
|||
SelfList<InstancePair>::List pairs;
|
||||
uint64_t pair_check;
|
||||
|
||||
virtual void dependency_deleted(RID p_dependency) {
|
||||
if (p_dependency == base) {
|
||||
singleton->instance_set_base(self, RID());
|
||||
} else if (p_dependency == skeleton) {
|
||||
singleton->instance_attach_skeleton(self, RID());
|
||||
} else {
|
||||
singleton->_instance_queue_update(this, false, true);
|
||||
RendererStorage::DependencyTracker dependency_tracker;
|
||||
|
||||
static void dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *tracker) {
|
||||
Instance *instance = (Instance *)tracker->userdata;
|
||||
switch (p_notification) {
|
||||
case RendererStorage::DEPENDENCY_CHANGED_SKELETON_DATA:
|
||||
case RendererStorage::DEPENDENCY_CHANGED_AABB: {
|
||||
singleton->_instance_queue_update(instance, true, false);
|
||||
|
||||
} break;
|
||||
case RendererStorage::DEPENDENCY_CHANGED_MATERIAL: {
|
||||
singleton->_instance_queue_update(instance, false, true);
|
||||
} break;
|
||||
case RendererStorage::DEPENDENCY_CHANGED_MESH:
|
||||
case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH:
|
||||
case RendererStorage::DEPENDENCY_CHANGED_DECAL:
|
||||
case RendererStorage::DEPENDENCY_CHANGED_LIGHT:
|
||||
case RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE: {
|
||||
singleton->_instance_queue_update(instance, true, true);
|
||||
} break;
|
||||
case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES:
|
||||
case RendererStorage::DEPENDENCY_CHANGED_SKELETON_BONES: {
|
||||
//ignored
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void dependency_changed(bool p_aabb, bool p_dependencies) {
|
||||
singleton->_instance_queue_update(this, p_aabb, p_dependencies);
|
||||
static void dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *tracker) {
|
||||
Instance *instance = (Instance *)tracker->userdata;
|
||||
|
||||
if (p_dependency == instance->base) {
|
||||
singleton->instance_set_base(instance->self, RID());
|
||||
} else if (p_dependency == instance->skeleton) {
|
||||
singleton->instance_attach_skeleton(instance->self, RID());
|
||||
} else {
|
||||
singleton->_instance_queue_update(instance, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
Instance() :
|
||||
scenario_item(this),
|
||||
update_item(this) {
|
||||
base_type = RS::INSTANCE_NONE;
|
||||
cast_shadows = RS::SHADOW_CASTING_SETTING_ON;
|
||||
receive_shadows = true;
|
||||
visible = true;
|
||||
layer_mask = 1;
|
||||
baked_light = false;
|
||||
dynamic_gi = false;
|
||||
redraw_if_visible = false;
|
||||
lightmap_slice_index = 0;
|
||||
lightmap = nullptr;
|
||||
lightmap_cull_index = 0;
|
||||
lod_bias = 1.0;
|
||||
|
||||
scenario = nullptr;
|
||||
|
||||
update_aabb = false;
|
||||
|
@ -399,6 +489,10 @@ public:
|
|||
|
||||
pair_check = 0;
|
||||
array_index = -1;
|
||||
|
||||
dependency_tracker.userdata = this;
|
||||
dependency_tracker.changed_callback = dependency_changed;
|
||||
dependency_tracker.deleted_callback = dependency_deleted;
|
||||
}
|
||||
|
||||
~Instance() {
|
||||
|
@ -415,6 +509,7 @@ public:
|
|||
void _instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies = false);
|
||||
|
||||
struct InstanceGeometryData : public InstanceBaseData {
|
||||
RendererSceneRender::GeometryInstance *geometry_instance = nullptr;
|
||||
Set<Instance *> lights;
|
||||
bool can_cast_shadows;
|
||||
bool material_is_animated;
|
||||
|
@ -458,6 +553,10 @@ public:
|
|||
|
||||
SelfList<InstanceReflectionProbeData>::List reflection_probe_render_list;
|
||||
|
||||
struct InstanceParticlesCollisionData : public InstanceBaseData {
|
||||
RID instance;
|
||||
};
|
||||
|
||||
struct InstanceLightData : public InstanceBaseData {
|
||||
RID instance;
|
||||
uint64_t last_version;
|
||||
|
@ -523,6 +622,7 @@ public:
|
|||
SelfList<InstanceGIProbeData>::List gi_probe_update_list;
|
||||
|
||||
struct InstanceLightmapData : public InstanceBaseData {
|
||||
RID instance;
|
||||
Set<Instance *> geometries;
|
||||
Set<Instance *> users;
|
||||
|
||||
|
@ -588,38 +688,138 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
struct CullResult {
|
||||
PagedArray<Instance *> *result;
|
||||
_FORCE_INLINE_ bool operator()(void *p_data) {
|
||||
Instance *p_instance = (Instance *)p_data;
|
||||
result->push_back(p_instance);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
Set<Instance *> heightfield_particle_colliders_update_list;
|
||||
|
||||
PagedArrayPool<Instance *> instance_cull_page_pool;
|
||||
PagedArrayPool<RendererSceneRender::InstanceBase *> base_instance_cull_page_pool;
|
||||
PagedArrayPool<RendererSceneRender::GeometryInstance *> geometry_instance_cull_page_pool;
|
||||
PagedArrayPool<RID> rid_cull_page_pool;
|
||||
|
||||
PagedArray<Instance *> instance_cull_result;
|
||||
PagedArray<RID> mesh_instance_cull_result;
|
||||
PagedArray<RendererSceneRender::InstanceBase *> geometry_instances_to_render;
|
||||
PagedArray<Instance *> instance_shadow_cull_result;
|
||||
PagedArray<RendererSceneRender::InstanceBase *> geometry_instances_to_shadow_render;
|
||||
PagedArray<Instance *> instance_sdfgi_cull_result;
|
||||
PagedArray<Instance *> light_cull_result;
|
||||
PagedArray<RendererSceneRender::InstanceBase *> lightmap_cull_result;
|
||||
PagedArray<RID> reflection_probe_instance_cull_result;
|
||||
PagedArray<RID> light_instance_cull_result;
|
||||
PagedArray<RendererSceneRender::GeometryInstance *> geometry_instances_to_shadow_render;
|
||||
|
||||
PagedArray<RID> gi_probe_instance_cull_result;
|
||||
PagedArray<RID> decal_instance_cull_result;
|
||||
struct FrustumCullResult {
|
||||
PagedArray<RendererSceneRender::GeometryInstance *> geometry_instances;
|
||||
PagedArray<Instance *> lights;
|
||||
PagedArray<RID> light_instances;
|
||||
PagedArray<RID> lightmaps;
|
||||
PagedArray<RID> reflections;
|
||||
PagedArray<RID> decals;
|
||||
PagedArray<RID> gi_probes;
|
||||
PagedArray<RID> mesh_instances;
|
||||
|
||||
struct DirectionalShadow {
|
||||
PagedArray<RendererSceneRender::GeometryInstance *> cascade_geometry_instances[RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES];
|
||||
} directional_shadows[RendererSceneRender::MAX_DIRECTIONAL_LIGHTS];
|
||||
|
||||
PagedArray<RendererSceneRender::GeometryInstance *> sdfgi_region_geometry_instances[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE];
|
||||
PagedArray<RID> sdfgi_cascade_lights[SDFGI_MAX_CASCADES];
|
||||
|
||||
void clear() {
|
||||
geometry_instances.clear();
|
||||
lights.clear();
|
||||
light_instances.clear();
|
||||
lightmaps.clear();
|
||||
reflections.clear();
|
||||
decals.clear();
|
||||
gi_probes.clear();
|
||||
mesh_instances.clear();
|
||||
for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) {
|
||||
for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) {
|
||||
directional_shadows[i].cascade_geometry_instances[j].clear();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) {
|
||||
sdfgi_region_geometry_instances[i].clear();
|
||||
}
|
||||
|
||||
for (int i = 0; i < SDFGI_MAX_CASCADES; i++) {
|
||||
sdfgi_cascade_lights[i].clear();
|
||||
}
|
||||
}
|
||||
|
||||
void reset() {
|
||||
geometry_instances.reset();
|
||||
lights.reset();
|
||||
light_instances.reset();
|
||||
lightmaps.reset();
|
||||
reflections.reset();
|
||||
decals.reset();
|
||||
gi_probes.reset();
|
||||
mesh_instances.reset();
|
||||
for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) {
|
||||
for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) {
|
||||
directional_shadows[i].cascade_geometry_instances[j].reset();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) {
|
||||
sdfgi_region_geometry_instances[i].reset();
|
||||
}
|
||||
|
||||
for (int i = 0; i < SDFGI_MAX_CASCADES; i++) {
|
||||
sdfgi_cascade_lights[i].reset();
|
||||
}
|
||||
}
|
||||
|
||||
void append_from(FrustumCullResult &p_cull_result) {
|
||||
geometry_instances.merge_unordered(p_cull_result.geometry_instances);
|
||||
lights.merge_unordered(p_cull_result.lights);
|
||||
light_instances.merge_unordered(p_cull_result.light_instances);
|
||||
lightmaps.merge_unordered(p_cull_result.lightmaps);
|
||||
reflections.merge_unordered(p_cull_result.reflections);
|
||||
decals.merge_unordered(p_cull_result.decals);
|
||||
gi_probes.merge_unordered(p_cull_result.gi_probes);
|
||||
mesh_instances.merge_unordered(p_cull_result.mesh_instances);
|
||||
|
||||
for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) {
|
||||
for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) {
|
||||
directional_shadows[i].cascade_geometry_instances[j].merge_unordered(p_cull_result.directional_shadows[i].cascade_geometry_instances[j]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) {
|
||||
sdfgi_region_geometry_instances[i].merge_unordered(p_cull_result.sdfgi_region_geometry_instances[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < SDFGI_MAX_CASCADES; i++) {
|
||||
sdfgi_cascade_lights[i].merge_unordered(p_cull_result.sdfgi_cascade_lights[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void init(PagedArrayPool<RID> *p_rid_pool, PagedArrayPool<RendererSceneRender::GeometryInstance *> *p_geometry_instance_pool, PagedArrayPool<Instance *> *p_instance_pool) {
|
||||
geometry_instances.set_page_pool(p_geometry_instance_pool);
|
||||
light_instances.set_page_pool(p_rid_pool);
|
||||
lights.set_page_pool(p_instance_pool);
|
||||
lightmaps.set_page_pool(p_rid_pool);
|
||||
reflections.set_page_pool(p_rid_pool);
|
||||
decals.set_page_pool(p_rid_pool);
|
||||
mesh_instances.set_page_pool(p_rid_pool);
|
||||
for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) {
|
||||
for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) {
|
||||
directional_shadows[i].cascade_geometry_instances[j].set_page_pool(p_geometry_instance_pool);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) {
|
||||
sdfgi_region_geometry_instances[i].set_page_pool(p_geometry_instance_pool);
|
||||
}
|
||||
|
||||
for (int i = 0; i < SDFGI_MAX_CASCADES; i++) {
|
||||
sdfgi_cascade_lights[i].set_page_pool(p_rid_pool);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
FrustumCullResult frustum_cull_result;
|
||||
LocalVector<FrustumCullResult> frustum_cull_result_threads;
|
||||
|
||||
uint32_t thread_cull_threshold = 200;
|
||||
|
||||
RID_PtrOwner<Instance> instance_owner;
|
||||
|
||||
bool pair_volumes_to_mesh; // used in traditional forward, unnecesary on clustered
|
||||
uint32_t geometry_instance_pair_mask; // used in traditional forward, unnecesary on clustered
|
||||
|
||||
virtual RID instance_create();
|
||||
|
||||
|
@ -653,7 +853,7 @@ public:
|
|||
virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index);
|
||||
virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias);
|
||||
|
||||
void _update_instance_shader_parameters_from_material(Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material);
|
||||
void _update_instance_shader_parameters_from_material(Map<StringName, Instance::InstanceShaderParameter> &isparams, const Map<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material);
|
||||
|
||||
virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value);
|
||||
virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const;
|
||||
|
@ -687,8 +887,6 @@ public:
|
|||
real_t range_begin;
|
||||
Vector2 uv_scale;
|
||||
|
||||
PagedArray<RendererSceneRender::InstanceBase *> cull_result;
|
||||
|
||||
} cascades[RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES]; //max 4 cascades
|
||||
uint32_t cascade_count;
|
||||
|
||||
|
@ -698,12 +896,10 @@ public:
|
|||
|
||||
struct SDFGI {
|
||||
//have arrays here because SDFGI functions expects this, plus regions can have areas
|
||||
PagedArray<RendererSceneRender::InstanceBase *> region_cull_result[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE];
|
||||
AABB region_aabb[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; //max 3 regions per cascade
|
||||
uint32_t region_cascade[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; //max 3 regions per cascade
|
||||
uint32_t region_count = 0;
|
||||
|
||||
PagedArray<RID> cascade_lights[SDFGI_MAX_CASCADES];
|
||||
uint32_t cascade_light_index[SDFGI_MAX_CASCADES];
|
||||
uint32_t cascade_light_count = 0;
|
||||
|
||||
|
@ -714,6 +910,18 @@ public:
|
|||
Frustum frustum;
|
||||
} cull;
|
||||
|
||||
struct FrustumCullData {
|
||||
Cull *cull;
|
||||
Scenario *scenario;
|
||||
RID shadow_atlas;
|
||||
Transform cam_transform;
|
||||
uint32_t visible_layers;
|
||||
Instance *render_reflection_probe;
|
||||
};
|
||||
|
||||
void _frustum_cull_threaded(uint32_t p_thread, FrustumCullData *cull_data);
|
||||
void _frustum_cull(FrustumCullData &cull_data, FrustumCullResult &cull_result, uint64_t p_from, uint64_t p_to);
|
||||
|
||||
bool _render_reflection_probe_step(Instance *p_instance, int p_step);
|
||||
void _prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_render_buffers, RID p_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, float p_screen_lod_threshold, bool p_using_shadows = true);
|
||||
void _render_scene(RID p_render_buffers, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_environment, RID p_force_camera_effects, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold);
|
||||
|
@ -828,6 +1036,8 @@ public:
|
|||
|
||||
bool free(RID p_rid);
|
||||
|
||||
void set_scene_render(RendererSceneRender *p_scene_render);
|
||||
|
||||
RendererSceneCull();
|
||||
virtual ~RendererSceneCull();
|
||||
};
|
||||
|
|
|
@ -41,6 +41,34 @@ public:
|
|||
MAX_DIRECTIONAL_LIGHTS = 8,
|
||||
MAX_DIRECTIONAL_LIGHT_CASCADES = 4
|
||||
};
|
||||
|
||||
struct GeometryInstance {
|
||||
virtual ~GeometryInstance() {}
|
||||
};
|
||||
|
||||
virtual GeometryInstance *geometry_instance_create(RID p_base) = 0;
|
||||
virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) = 0;
|
||||
virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) = 0;
|
||||
virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) = 0;
|
||||
virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) = 0;
|
||||
virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) = 0;
|
||||
virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) = 0;
|
||||
virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) = 0;
|
||||
virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) = 0;
|
||||
virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) = 0;
|
||||
virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) = 0;
|
||||
virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) = 0;
|
||||
virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) = 0;
|
||||
virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) = 0;
|
||||
|
||||
virtual uint32_t geometry_instance_get_pair_mask() = 0;
|
||||
virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) = 0;
|
||||
virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) = 0;
|
||||
virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) = 0;
|
||||
virtual void geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count) = 0;
|
||||
|
||||
virtual void geometry_instance_free(GeometryInstance *p_geometry_instance) = 0;
|
||||
|
||||
/* SHADOW ATLAS API */
|
||||
|
||||
virtual RID
|
||||
|
@ -55,8 +83,6 @@ public:
|
|||
|
||||
/* SDFGI UPDATE */
|
||||
|
||||
struct InstanceBase;
|
||||
|
||||
virtual void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) = 0;
|
||||
virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const = 0;
|
||||
virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const = 0;
|
||||
|
@ -134,83 +160,6 @@ public:
|
|||
virtual void shadows_quality_set(RS::ShadowQuality p_quality) = 0;
|
||||
virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0;
|
||||
|
||||
struct InstanceBase : public RendererStorage::InstanceBaseDependency {
|
||||
RS::InstanceType base_type;
|
||||
RID base;
|
||||
|
||||
RID skeleton;
|
||||
RID material_override;
|
||||
|
||||
RID mesh_instance; //only used for meshes and when skeleton/blendshapes exist
|
||||
|
||||
Transform transform;
|
||||
|
||||
float lod_bias;
|
||||
|
||||
int depth_layer;
|
||||
uint32_t layer_mask;
|
||||
|
||||
//RID sampled_light;
|
||||
|
||||
Vector<RID> materials;
|
||||
Vector<RID> light_instances;
|
||||
Vector<RID> reflection_probe_instances;
|
||||
Vector<RID> gi_probe_instances;
|
||||
|
||||
RS::ShadowCastingSetting cast_shadows;
|
||||
|
||||
//fit in 32 bits
|
||||
bool mirror : 8;
|
||||
bool receive_shadows : 8;
|
||||
bool visible : 8;
|
||||
bool baked_light : 2; //this flag is only to know if it actually did use baked light
|
||||
bool dynamic_gi : 2; //this flag is only to know if it actually did use baked light
|
||||
bool redraw_if_visible : 4;
|
||||
|
||||
float depth; //used for sorting
|
||||
|
||||
InstanceBase *lightmap;
|
||||
Rect2 lightmap_uv_scale;
|
||||
int lightmap_slice_index;
|
||||
uint32_t lightmap_cull_index;
|
||||
Vector<Color> lightmap_sh; //spherical harmonic
|
||||
|
||||
AABB aabb;
|
||||
AABB transformed_aabb;
|
||||
AABB prev_transformed_aabb;
|
||||
|
||||
struct InstanceShaderParameter {
|
||||
int32_t index = -1;
|
||||
Variant value;
|
||||
Variant default_value;
|
||||
PropertyInfo info;
|
||||
};
|
||||
|
||||
Map<StringName, InstanceShaderParameter> instance_shader_parameters;
|
||||
bool instance_allocated_shader_parameters = false;
|
||||
int32_t instance_allocated_shader_parameters_offset = -1;
|
||||
|
||||
InstanceBase() {
|
||||
base_type = RS::INSTANCE_NONE;
|
||||
cast_shadows = RS::SHADOW_CASTING_SETTING_ON;
|
||||
receive_shadows = true;
|
||||
visible = true;
|
||||
depth_layer = 0;
|
||||
layer_mask = 1;
|
||||
instance_version = 0;
|
||||
baked_light = false;
|
||||
dynamic_gi = false;
|
||||
redraw_if_visible = false;
|
||||
lightmap_slice_index = 0;
|
||||
lightmap = nullptr;
|
||||
lightmap_cull_index = 0;
|
||||
lod_bias = 1.0;
|
||||
}
|
||||
|
||||
virtual ~InstanceBase() {
|
||||
}
|
||||
};
|
||||
|
||||
virtual RID light_instance_create(RID p_light) = 0;
|
||||
virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) = 0;
|
||||
virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) = 0;
|
||||
|
@ -235,20 +184,23 @@ public:
|
|||
virtual RID decal_instance_create(RID p_decal) = 0;
|
||||
virtual void decal_instance_set_transform(RID p_decal, const Transform &p_transform) = 0;
|
||||
|
||||
virtual RID lightmap_instance_create(RID p_lightmap) = 0;
|
||||
virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform) = 0;
|
||||
|
||||
virtual RID gi_probe_instance_create(RID p_gi_probe) = 0;
|
||||
virtual void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) = 0;
|
||||
virtual bool gi_probe_needs_update(RID p_probe) const = 0;
|
||||
virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::InstanceBase *> &p_dynamic_objects) = 0;
|
||||
virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) = 0;
|
||||
|
||||
virtual void gi_probe_set_quality(RS::GIProbeQuality) = 0;
|
||||
|
||||
virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) = 0;
|
||||
virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) = 0;
|
||||
|
||||
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<InstanceBase *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0) = 0;
|
||||
virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
|
||||
virtual void render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<InstanceBase *> &p_instances) = 0;
|
||||
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0) = 0;
|
||||
virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
|
||||
virtual void render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances) = 0;
|
||||
virtual void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_lights) = 0;
|
||||
virtual void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<InstanceBase *> &p_instances) = 0;
|
||||
virtual void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances) = 0;
|
||||
|
||||
virtual void set_scene_pass(uint64_t p_pass) = 0;
|
||||
virtual void set_time(double p_time, double p_step) = 0;
|
||||
|
|
|
@ -32,28 +32,31 @@
|
|||
|
||||
RendererStorage *RendererStorage::base_singleton = nullptr;
|
||||
|
||||
void RendererStorage::InstanceDependency::instance_notify_changed(bool p_aabb, bool p_dependencies) {
|
||||
for (Map<InstanceBaseDependency *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
|
||||
E->key()->dependency_changed(p_aabb, p_dependencies);
|
||||
void RendererStorage::Dependency::changed_notify(DependencyChangedNotification p_notification) {
|
||||
for (Map<DependencyTracker *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
|
||||
if (E->key()->changed_callback) {
|
||||
E->key()->changed_callback(p_notification, E->key());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RendererStorage::InstanceDependency::instance_notify_deleted(RID p_deleted) {
|
||||
for (Map<InstanceBaseDependency *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
|
||||
E->key()->dependency_deleted(p_deleted);
|
||||
void RendererStorage::Dependency::deleted_notify(const RID &p_rid) {
|
||||
for (Map<DependencyTracker *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
|
||||
if (E->key()->deleted_callback) {
|
||||
E->key()->deleted_callback(p_rid, E->key());
|
||||
}
|
||||
for (Map<InstanceBaseDependency *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
|
||||
}
|
||||
for (Map<DependencyTracker *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
|
||||
E->key()->dependencies.erase(this);
|
||||
}
|
||||
|
||||
instances.clear();
|
||||
}
|
||||
|
||||
RendererStorage::InstanceDependency::~InstanceDependency() {
|
||||
RendererStorage::Dependency::~Dependency() {
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (instances.size()) {
|
||||
WARN_PRINT("Leaked instance dependency: Bug - did not call instance_notify_deleted when freeing.");
|
||||
for (Map<InstanceBaseDependency *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
|
||||
for (Map<DependencyTracker *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
|
||||
E->key()->dependencies.erase(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,43 +37,59 @@ class RendererStorage {
|
|||
Color default_clear_color;
|
||||
|
||||
public:
|
||||
struct InstanceBaseDependency;
|
||||
|
||||
struct InstanceDependency {
|
||||
void instance_notify_changed(bool p_aabb, bool p_dependencies);
|
||||
void instance_notify_deleted(RID p_deleted);
|
||||
|
||||
~InstanceDependency();
|
||||
|
||||
private:
|
||||
friend struct InstanceBaseDependency;
|
||||
Map<InstanceBaseDependency *, uint32_t> instances;
|
||||
enum DependencyChangedNotification {
|
||||
DEPENDENCY_CHANGED_AABB,
|
||||
DEPENDENCY_CHANGED_MATERIAL,
|
||||
DEPENDENCY_CHANGED_MESH,
|
||||
DEPENDENCY_CHANGED_MULTIMESH,
|
||||
DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES,
|
||||
DEPENDENCY_CHANGED_DECAL,
|
||||
DEPENDENCY_CHANGED_SKELETON_DATA,
|
||||
DEPENDENCY_CHANGED_SKELETON_BONES,
|
||||
DEPENDENCY_CHANGED_LIGHT,
|
||||
DEPENDENCY_CHANGED_REFLECTION_PROBE,
|
||||
};
|
||||
|
||||
struct InstanceBaseDependency {
|
||||
uint32_t instance_version;
|
||||
Set<InstanceDependency *> dependencies;
|
||||
struct DependencyTracker;
|
||||
|
||||
virtual void dependency_deleted(RID p_dependency) {}
|
||||
virtual void dependency_changed(bool p_aabb, bool p_dependencies) {}
|
||||
protected:
|
||||
struct Dependency {
|
||||
void changed_notify(DependencyChangedNotification p_notification);
|
||||
void deleted_notify(const RID &p_rid);
|
||||
|
||||
void instance_increase_version() {
|
||||
~Dependency();
|
||||
|
||||
private:
|
||||
friend struct DependencyTracker;
|
||||
Map<DependencyTracker *, uint32_t> instances;
|
||||
};
|
||||
|
||||
public:
|
||||
struct DependencyTracker {
|
||||
void *userdata = nullptr;
|
||||
typedef void (*ChangedCallback)(DependencyChangedNotification, DependencyTracker *);
|
||||
typedef void (*DeletedCallback)(const RID &, DependencyTracker *);
|
||||
|
||||
ChangedCallback changed_callback = nullptr;
|
||||
DeletedCallback deleted_callback = nullptr;
|
||||
|
||||
void update_begin() { // call before updating dependencies
|
||||
instance_version++;
|
||||
}
|
||||
|
||||
void update_dependency(InstanceDependency *p_dependency) {
|
||||
void update_dependency(Dependency *p_dependency) { //called internally, can't be used directly, use update functions in Storage
|
||||
dependencies.insert(p_dependency);
|
||||
p_dependency->instances[this] = instance_version;
|
||||
}
|
||||
|
||||
void clean_up_dependencies() {
|
||||
List<Pair<InstanceDependency *, Map<InstanceBaseDependency *, uint32_t>::Element *>> to_clean_up;
|
||||
for (Set<InstanceDependency *>::Element *E = dependencies.front(); E; E = E->next()) {
|
||||
InstanceDependency *dep = E->get();
|
||||
Map<InstanceBaseDependency *, uint32_t>::Element *F = dep->instances.find(this);
|
||||
void update_end() { //call after updating dependencies
|
||||
List<Pair<Dependency *, Map<DependencyTracker *, uint32_t>::Element *>> to_clean_up;
|
||||
for (Set<Dependency *>::Element *E = dependencies.front(); E; E = E->next()) {
|
||||
Dependency *dep = E->get();
|
||||
Map<DependencyTracker *, uint32_t>::Element *F = dep->instances.find(this);
|
||||
ERR_CONTINUE(!F);
|
||||
if (F->get() != instance_version) {
|
||||
Pair<InstanceDependency *, Map<InstanceBaseDependency *, uint32_t>::Element *> p;
|
||||
Pair<Dependency *, Map<DependencyTracker *, uint32_t>::Element *> p;
|
||||
p.first = dep;
|
||||
p.second = F;
|
||||
to_clean_up.push_back(p);
|
||||
|
@ -86,15 +102,20 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void clear_dependencies() {
|
||||
for (Set<InstanceDependency *>::Element *E = dependencies.front(); E; E = E->next()) {
|
||||
InstanceDependency *dep = E->get();
|
||||
void clear() { // clear all dependencies
|
||||
for (Set<Dependency *>::Element *E = dependencies.front(); E; E = E->next()) {
|
||||
Dependency *dep = E->get();
|
||||
dep->instances.erase(this);
|
||||
}
|
||||
dependencies.clear();
|
||||
}
|
||||
|
||||
virtual ~InstanceBaseDependency() { clear_dependencies(); }
|
||||
~DependencyTracker() { clear(); }
|
||||
|
||||
private:
|
||||
friend struct Dependency;
|
||||
uint32_t instance_version = 0;
|
||||
Set<Dependency *> dependencies;
|
||||
};
|
||||
|
||||
/* TEXTURE API */
|
||||
|
@ -181,7 +202,7 @@ public:
|
|||
|
||||
virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) = 0;
|
||||
|
||||
virtual void material_update_dependency(RID p_material, InstanceBaseDependency *p_instance) = 0;
|
||||
virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) = 0;
|
||||
|
||||
/* MESH API */
|
||||
|
||||
|
@ -349,8 +370,8 @@ public:
|
|||
virtual bool reflection_probe_renders_shadows(RID p_probe) const = 0;
|
||||
virtual float reflection_probe_get_lod_threshold(RID p_probe) const = 0;
|
||||
|
||||
virtual void base_update_dependency(RID p_base, InstanceBaseDependency *p_instance) = 0;
|
||||
virtual void skeleton_update_dependency(RID p_base, InstanceBaseDependency *p_instance) = 0;
|
||||
virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) = 0;
|
||||
virtual void skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) = 0;
|
||||
|
||||
/* DECAL API */
|
||||
|
||||
|
@ -474,8 +495,8 @@ public:
|
|||
|
||||
virtual void particles_set_view_axis(RID p_particles, const Vector3 &p_axis) = 0;
|
||||
|
||||
virtual void particles_add_collision(RID p_particles, InstanceBaseDependency *p_instance) = 0;
|
||||
virtual void particles_remove_collision(RID p_particles, InstanceBaseDependency *p_instance) = 0;
|
||||
virtual void particles_add_collision(RID p_particles, RID p_particles_collision_instance) = 0;
|
||||
virtual void particles_remove_collision(RID p_particles, RID p_particles_collision_instance) = 0;
|
||||
|
||||
virtual void update_particles() = 0;
|
||||
|
||||
|
@ -496,6 +517,11 @@ public:
|
|||
virtual bool particles_collision_is_heightfield(RID p_particles_collision) const = 0;
|
||||
virtual RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const = 0;
|
||||
|
||||
//used from 2D and 3D
|
||||
virtual RID particles_collision_instance_create(RID p_collision) = 0;
|
||||
virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform) = 0;
|
||||
virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active) = 0;
|
||||
|
||||
/* GLOBAL VARIABLES */
|
||||
|
||||
virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) = 0;
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*************************************************************************/
|
||||
/* renderer_thread_pool.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "renderer_thread_pool.h"
|
||||
|
||||
RendererThreadPool *RendererThreadPool::singleton = nullptr;
|
||||
|
||||
RendererThreadPool::RendererThreadPool() {
|
||||
singleton = this;
|
||||
thread_work_pool.init();
|
||||
}
|
||||
|
||||
RendererThreadPool::~RendererThreadPool() {
|
||||
thread_work_pool.finish();
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*************************************************************************/
|
||||
/* renderer_thread_pool.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef RENDERERTHREADPOOL_H
|
||||
#define RENDERERTHREADPOOL_H
|
||||
|
||||
#include "core/templates/thread_work_pool.h"
|
||||
|
||||
class RendererThreadPool {
|
||||
public:
|
||||
ThreadWorkPool thread_work_pool;
|
||||
|
||||
static RendererThreadPool *singleton;
|
||||
RendererThreadPool();
|
||||
~RendererThreadPool();
|
||||
};
|
||||
|
||||
#endif // RENDERERTHREADPOOL_H
|
|
@ -267,7 +267,7 @@ RenderingServerDefault::RenderingServerDefault() {
|
|||
RSG::rasterizer = RendererCompositor::create();
|
||||
RSG::storage = RSG::rasterizer->get_storage();
|
||||
RSG::canvas_render = RSG::rasterizer->get_canvas();
|
||||
sr->scene_render = RSG::rasterizer->get_scene();
|
||||
sr->set_scene_render(RSG::rasterizer->get_scene());
|
||||
|
||||
frame_profile_frame = 0;
|
||||
|
||||
|
|
|
@ -2253,6 +2253,8 @@ void RenderingServer::set_render_loop_enabled(bool p_enabled) {
|
|||
|
||||
RenderingServer::RenderingServer() {
|
||||
//ERR_FAIL_COND(singleton);
|
||||
|
||||
thread_pool = memnew(RendererThreadPool);
|
||||
singleton = this;
|
||||
|
||||
GLOBAL_DEF_RST("rendering/vram_compression/import_bptc", false);
|
||||
|
@ -2383,8 +2385,13 @@ RenderingServer::RenderingServer() {
|
|||
|
||||
GLOBAL_DEF("rendering/spatial_indexer/update_iterations_per_frame", 10);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/spatial_indexer/update_iterations_per_frame", PropertyInfo(Variant::INT, "rendering/spatial_indexer/update_iterations_per_frame", PROPERTY_HINT_RANGE, "0,1024,1"));
|
||||
GLOBAL_DEF("rendering/spatial_indexer/threaded_cull_minimum_instances", 1000);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/spatial_indexer/threaded_cull_minimum_instances", PropertyInfo(Variant::INT, "rendering/spatial_indexer/threaded_cull_minimum_instances", PROPERTY_HINT_RANGE, "32,65536,1"));
|
||||
GLOBAL_DEF("rendering/forward_renderer/threaded_render_minimum_instances", 500);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/forward_renderer/threaded_render_minimum_instances", PropertyInfo(Variant::INT, "rendering/forward_renderer/threaded_render_minimum_instances", PROPERTY_HINT_RANGE, "32,65536,1"));
|
||||
}
|
||||
|
||||
RenderingServer::~RenderingServer() {
|
||||
memdelete(thread_pool);
|
||||
singleton = nullptr;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "core/variant/typed_array.h"
|
||||
#include "core/variant/variant.h"
|
||||
#include "servers/display_server.h"
|
||||
#include "servers/rendering/renderer_thread_pool.h"
|
||||
#include "servers/rendering/rendering_device.h"
|
||||
#include "servers/rendering/shader_language.h"
|
||||
|
||||
|
@ -52,6 +53,8 @@ class RenderingServer : public Object {
|
|||
|
||||
Array _get_array_from_surface(uint32_t p_format, Vector<uint8_t> p_vertex_data, Vector<uint8_t> p_attrib_data, Vector<uint8_t> p_skin_data, int p_vertex_len, Vector<uint8_t> p_index_data, int p_index_len) const;
|
||||
|
||||
RendererThreadPool *thread_pool = nullptr;
|
||||
|
||||
protected:
|
||||
RID _make_test_cube();
|
||||
void _free_internal_rids();
|
||||
|
|
Loading…
Reference in New Issue