summaryrefslogtreecommitdiff
path: root/servers/rendering/renderer_rd
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering/renderer_rd')
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp18
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp20
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp2
-rw-r--r--servers/rendering/renderer_rd/shaders/particles.glsl13
-rw-r--r--servers/rendering/renderer_rd/storage_rd/light_storage.cpp4
-rw-r--r--servers/rendering/renderer_rd/storage_rd/particles_storage.cpp9
-rw-r--r--servers/rendering/renderer_rd/storage_rd/particles_storage.h9
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.cpp40
8 files changed, 102 insertions, 13 deletions
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index c853ae6c69..608f7ff958 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -831,8 +831,18 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
for (int i = 0; i < (int)p_render_data->instances->size(); i++) {
GeometryInstanceForwardClustered *inst = static_cast<GeometryInstanceForwardClustered *>((*p_render_data->instances)[i]);
- Vector3 support_min = inst->transformed_aabb.get_support(-near_plane.normal);
- inst->depth = near_plane.distance_to(support_min);
+ Vector3 center = inst->transform.origin;
+ if (p_render_data->scene_data->cam_orthogonal) {
+ if (inst->use_aabb_center) {
+ center = inst->transformed_aabb.get_support(-near_plane.normal);
+ }
+ inst->depth = near_plane.distance_to(center) - inst->sorting_offset;
+ } else {
+ if (inst->use_aabb_center) {
+ center = inst->transformed_aabb.position + (inst->transformed_aabb.size * 0.5);
+ }
+ inst->depth = p_render_data->scene_data->cam_transform.origin.distance_to(center) - inst->sorting_offset;
+ }
uint32_t depth_layer = CLAMP(int(inst->depth * 16 / z_max), 0, 15);
uint32_t flags = inst->base_flags; //fill flags if appropriate
@@ -3598,6 +3608,10 @@ void RenderForwardClustered::_geometry_instance_update(RenderGeometryInstance *p
}
ginstance->transforms_uniform_set = particles_storage->particles_get_instance_buffer_uniform_set(ginstance->data->base, scene_shader.default_shader_rd, TRANSFORMS_UNIFORM_SET);
+ if (particles_storage->particles_get_frame_counter(ginstance->data->base) == 0) {
+ // Particles haven't been cleared or updated, update once now to ensure they are ready to render.
+ particles_storage->update_particles();
+ }
} else if (ginstance->data->base_type == RS::INSTANCE_MESH) {
if (mesh_storage->skeleton_is_valid(ginstance->data->skeleton)) {
ginstance->transforms_uniform_set = mesh_storage->skeleton_get_3d_uniform_set(ginstance->data->skeleton, scene_shader.default_shader_rd, TRANSFORMS_UNIFORM_SET);
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
index 350a5eb0e4..e47ca8dd73 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -154,8 +154,8 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RenderSceneBu
render_buffers->create_texture(RB_SCOPE_MOBILE, RB_TEX_COLOR_MSAA, format, usage_bits, texture_samples);
- format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT;
usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
+ format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, usage_bits) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT;
render_buffers->create_texture(RB_SCOPE_MOBILE, RB_TEX_DEPTH_MSAA, format, usage_bits, texture_samples);
}
@@ -1757,8 +1757,18 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
for (int i = 0; i < (int)p_render_data->instances->size(); i++) {
GeometryInstanceForwardMobile *inst = static_cast<GeometryInstanceForwardMobile *>((*p_render_data->instances)[i]);
- Vector3 support_min = inst->transformed_aabb.get_support(-near_plane.normal);
- inst->depth = near_plane.distance_to(support_min);
+ Vector3 center = inst->transform.origin;
+ if (p_render_data->scene_data->cam_orthogonal) {
+ if (inst->use_aabb_center) {
+ center = inst->transformed_aabb.get_support(-near_plane.normal);
+ }
+ inst->depth = near_plane.distance_to(center) - inst->sorting_offset;
+ } else {
+ if (inst->use_aabb_center) {
+ center = inst->transformed_aabb.position + (inst->transformed_aabb.size * 0.5);
+ }
+ inst->depth = p_render_data->scene_data->cam_transform.origin.distance_to(center) - inst->sorting_offset;
+ }
uint32_t depth_layer = CLAMP(int(inst->depth * 16 / z_max), 0, 15);
uint32_t flags = inst->base_flags; //fill flags if appropriate
@@ -2626,6 +2636,10 @@ void RenderForwardMobile::_geometry_instance_update(RenderGeometryInstance *p_ge
}
ginstance->transforms_uniform_set = particles_storage->particles_get_instance_buffer_uniform_set(ginstance->data->base, scene_shader.default_shader_rd, TRANSFORMS_UNIFORM_SET);
+ if (particles_storage->particles_get_frame_counter(ginstance->data->base) == 0) {
+ // Particles haven't been cleared or updated, update once now to ensure they are ready to render.
+ particles_storage->update_particles();
+ }
} else if (ginstance->data->base_type == RS::INSTANCE_MESH) {
if (mesh_storage->skeleton_is_valid(ginstance->data->skeleton)) {
ginstance->transforms_uniform_set = mesh_storage->skeleton_get_3d_uniform_set(ginstance->data->skeleton, scene_shader.default_shader_rd, TRANSFORMS_UNIFORM_SET);
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index f7302adbf6..96690ceac1 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -790,7 +790,7 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
ERR_BREAK(particles_storage->particles_get_mode(pt->particles) != RS::PARTICLES_MODE_2D);
particles_storage->particles_request_process(pt->particles);
- if (particles_storage->particles_is_inactive(pt->particles)) {
+ if (particles_storage->particles_is_inactive(pt->particles) || particles_storage->particles_get_frame_counter(pt->particles) == 0) {
break;
}
diff --git a/servers/rendering/renderer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl
index 9f6aa7adc0..a609076e2c 100644
--- a/servers/rendering/renderer_rd/shaders/particles.glsl
+++ b/servers/rendering/renderer_rd/shaders/particles.glsl
@@ -243,8 +243,14 @@ void main() {
if (params.trail_size > 1) {
if (params.trail_pass) {
+ if (particle >= params.total_particles * (params.trail_size - 1)) {
+ return;
+ }
particle += (particle / (params.trail_size - 1)) + 1;
} else {
+ if (particle >= params.total_particles) {
+ return;
+ }
particle *= params.trail_size;
}
}
@@ -298,12 +304,17 @@ void main() {
PARTICLE.flags = PARTICLE_FLAG_TRAILED | ((frame_history.data[0].frame & PARTICLE_FRAME_MASK) << PARTICLE_FRAME_SHIFT); //mark it as trailed, save in which frame it will start
PARTICLE.xform = particles.data[src_idx].xform;
}
-
+ if (!bool(particles.data[src_idx].flags & PARTICLE_FLAG_ACTIVE)) {
+ // Disable the entire trail if the parent is no longer active.
+ PARTICLE.flags = 0;
+ return;
+ }
if (bool(PARTICLE.flags & PARTICLE_FLAG_TRAILED) && ((PARTICLE.flags >> PARTICLE_FRAME_SHIFT) == (FRAME.frame & PARTICLE_FRAME_MASK))) { //check this is trailed and see if it should start now
// we just assume that this is the first frame of the particle, the rest is deterministic
PARTICLE.flags = PARTICLE_FLAG_ACTIVE | (particles.data[src_idx].flags & (PARTICLE_FRAME_MASK << PARTICLE_FRAME_SHIFT));
return; //- this appears like it should be correct, but it seems not to be.. wonder why.
}
+
} else {
PARTICLE.flags &= ~PARTICLE_FLAG_STARTED;
}
diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
index 1dd95969e6..ff882c1992 100644
--- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
@@ -1726,13 +1726,13 @@ void LightStorage::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_use
//erase lightmap users
if (lm->light_texture.is_valid()) {
- TextureStorage::Texture *t = texture_storage->get_singleton()->get_texture(lm->light_texture);
+ TextureStorage::Texture *t = texture_storage->get_texture(lm->light_texture);
if (t) {
t->lightmap_users.erase(p_lightmap);
}
}
- TextureStorage::Texture *t = texture_storage->get_singleton()->get_texture(p_light);
+ TextureStorage::Texture *t = texture_storage->get_texture(p_light);
lm->light_texture = p_light;
lm->uses_spherical_harmonics = p_uses_spherical_haromics;
diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
index 1e91982fe1..708455706b 100644
--- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
@@ -1415,6 +1415,7 @@ void ParticlesStorage::update_particles() {
}
bool zero_time_scale = Engine::get_singleton()->get_time_scale() <= 0.0;
+ bool updated = false;
if (particles->clear && particles->pre_process_time > 0.0) {
double frame_time;
@@ -1429,6 +1430,7 @@ void ParticlesStorage::update_particles() {
while (todo >= 0) {
_particles_process(particles, frame_time);
todo -= frame_time;
+ updated = true;
}
}
@@ -1450,9 +1452,10 @@ void ParticlesStorage::update_particles() {
}
double todo = particles->frame_remainder + delta;
- while (todo >= frame_time) {
+ while (todo >= frame_time || (particles->clear && !updated)) {
_particles_process(particles, frame_time);
todo -= decr;
+ updated = true;
}
particles->frame_remainder = todo;
@@ -1460,14 +1463,16 @@ void ParticlesStorage::update_particles() {
} else {
if (zero_time_scale) {
_particles_process(particles, 0.0);
+ updated = true;
} else {
_particles_process(particles, RendererCompositorRD::singleton->get_frame_delta_time());
+ updated = true;
}
}
//copy particles to instance buffer
- if (particles->draw_order != RS::PARTICLES_DRAW_ORDER_VIEW_DEPTH && particles->transform_align != RS::PARTICLES_TRANSFORM_ALIGN_Z_BILLBOARD && particles->transform_align != RS::PARTICLES_TRANSFORM_ALIGN_Z_BILLBOARD_Y_TO_VELOCITY) {
+ if (updated && particles->draw_order != RS::PARTICLES_DRAW_ORDER_VIEW_DEPTH && particles->transform_align != RS::PARTICLES_TRANSFORM_ALIGN_Z_BILLBOARD && particles->transform_align != RS::PARTICLES_TRANSFORM_ALIGN_Z_BILLBOARD_Y_TO_VELOCITY) {
//does not need view dependent operation, do copy here
ParticlesShader::CopyPushConstant copy_push_constant;
diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.h b/servers/rendering/renderer_rd/storage_rd/particles_storage.h
index ef3299ba1e..0701dc95dd 100644
--- a/servers/rendering/renderer_rd/storage_rd/particles_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.h
@@ -455,6 +455,12 @@ public:
return particles->mode;
}
+ _FORCE_INLINE_ uint32_t particles_get_frame_counter(RID p_particles) {
+ Particles *particles = particles_owner.get_or_null(p_particles);
+ ERR_FAIL_COND_V(!particles, false);
+ return particles->frame_counter;
+ }
+
_FORCE_INLINE_ uint32_t particles_get_amount(RID p_particles, uint32_t &r_trail_divisor) {
Particles *particles = particles_owner.get_or_null(p_particles);
ERR_FAIL_COND_V(!particles, 0);
@@ -485,9 +491,8 @@ public:
_FORCE_INLINE_ RID particles_get_instance_buffer_uniform_set(RID p_particles, RID p_shader, uint32_t p_set) {
Particles *particles = particles_owner.get_or_null(p_particles);
ERR_FAIL_COND_V(!particles, RID());
- if (particles->particles_transforms_buffer_uniform_set.is_null()) {
+ if (particles->particles_transforms_buffer_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(particles->particles_transforms_buffer_uniform_set)) {
_particles_update_buffers(particles);
-
Vector<RD::Uniform> uniforms;
{
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
index 67f013cfb0..6a4359faf3 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
@@ -1777,6 +1777,46 @@ Ref<Image> TextureStorage::_validate_texture_format(const Ref<Image> &p_image, T
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_ZERO;
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
} break;
+ case Image::FORMAT_ASTC_4x4:
+ case Image::FORMAT_ASTC_4x4_HDR: {
+ if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ASTC_4x4_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
+ r_format.format = RD::DATA_FORMAT_ASTC_4x4_UNORM_BLOCK;
+ if (p_image->get_format() == Image::FORMAT_ASTC_4x4) {
+ r_format.format_srgb = RD::DATA_FORMAT_ASTC_4x4_SRGB_BLOCK;
+ }
+ } else {
+ //not supported, reconvert
+ r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+ r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
+ image->decompress();
+ image->convert(Image::FORMAT_RGBA8);
+ }
+ r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
+ r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
+ r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
+ r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
+
+ } break; // astc 4x4
+ case Image::FORMAT_ASTC_8x8:
+ case Image::FORMAT_ASTC_8x8_HDR: {
+ if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ASTC_8x8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
+ r_format.format = RD::DATA_FORMAT_ASTC_8x8_UNORM_BLOCK;
+ if (p_image->get_format() == Image::FORMAT_ASTC_8x8) {
+ r_format.format_srgb = RD::DATA_FORMAT_ASTC_8x8_SRGB_BLOCK;
+ }
+ } else {
+ //not supported, reconvert
+ r_format.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+ r_format.format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
+ image->decompress();
+ image->convert(Image::FORMAT_RGBA8);
+ }
+ r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
+ r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
+ r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
+ r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
+
+ } break; // astc 8x8
default: {
}