diff options
Diffstat (limited to 'servers')
22 files changed, 159 insertions, 67 deletions
diff --git a/servers/rendering/dummy/storage/light_storage.h b/servers/rendering/dummy/storage/light_storage.h index 9a3918fd86..b9e8bcc6f1 100644 --- a/servers/rendering/dummy/storage/light_storage.h +++ b/servers/rendering/dummy/storage/light_storage.h @@ -80,6 +80,7 @@ public: virtual RS::LightBakeMode light_get_bake_mode(RID p_light) override { return RS::LIGHT_BAKE_DISABLED; } virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override { return 0; } virtual uint64_t light_get_version(RID p_light) const override { return 0; } + virtual uint32_t light_get_cull_mask(RID p_light) const override { return 0; } /* LIGHT INSTANCE API */ diff --git a/servers/rendering/dummy/storage/texture_storage.h b/servers/rendering/dummy/storage/texture_storage.h index 41251b348c..67661ce821 100644 --- a/servers/rendering/dummy/storage/texture_storage.h +++ b/servers/rendering/dummy/storage/texture_storage.h @@ -145,6 +145,7 @@ public: virtual void decal_set_normal_fade(RID p_decal, float p_fade) override {} virtual AABB decal_get_aabb(RID p_decal) const override { return AABB(); } + virtual uint32_t decal_get_cull_mask(RID p_decal) const override { return 0; } virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {} virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {} diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index bd8c11186e..f102bc0650 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -2634,6 +2634,7 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() { // Default CanvasGroup shader. shader_type canvas_item; +render_mode unshaded; uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_nearest; @@ -2661,6 +2662,7 @@ void fragment() { // Default clip children shader. shader_type canvas_item; +render_mode unshaded; uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_nearest; diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 885ea18151..5776414b14 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -280,7 +280,7 @@ void RendererSceneRenderRD::_render_buffers_copy_screen_texture(const RenderData for (int i = 1; i < mipmaps; i++) { RID source = dest; dest = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, v, i); - Size2i msize = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, v, i); + Size2i msize = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_0, i); if (can_use_storage) { copy_effects->make_mipmap(source, dest, msize); @@ -448,7 +448,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende float luminance_multiplier = _render_buffers_get_luminance_multiplier(); for (uint32_t l = 0; l < rb->get_view_count(); l++) { for (int i = 0; i < (max_glow_level + 1); i++) { - Size2i vp_size = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, l, i); + Size2i vp_size = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, i); if (i == 0) { RID luminance_texture; @@ -502,7 +502,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende tonemap.glow_levels[i] = environment_get_glow_levels(p_render_data->environment)[i]; } - Size2i msize = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, 0, 0); + Size2i msize = rb->get_texture_slice_size(RB_SCOPE_BUFFERS, RB_TEX_BLUR_1, 0); tonemap.glow_texture_size.x = msize.width; tonemap.glow_texture_size.y = msize.height; tonemap.glow_use_bicubic_upscale = glow_bicubic_upscale; diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp index 968f804593..e65d842a67 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp @@ -389,6 +389,13 @@ uint64_t LightStorage::light_get_version(RID p_light) const { return light->version; } +uint32_t LightStorage::light_get_cull_mask(RID p_light) const { + const Light *light = light_owner.get_or_null(p_light); + ERR_FAIL_COND_V(!light, 0); + + return light->cull_mask; +} + AABB LightStorage::light_get_aabb(RID p_light) const { const Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND_V(!light, AABB()); diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.h b/servers/rendering/renderer_rd/storage_rd/light_storage.h index 68f439ddef..c36d1ef503 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.h @@ -517,13 +517,6 @@ public: return light->color; } - _FORCE_INLINE_ uint32_t light_get_cull_mask(RID p_light) { - const Light *light = light_owner.get_or_null(p_light); - ERR_FAIL_COND_V(!light, 0); - - return light->cull_mask; - } - _FORCE_INLINE_ bool light_is_distance_fade_enabled(RID p_light) { const Light *light = light_owner.get_or_null(p_light); return light->distance_fade; @@ -575,6 +568,7 @@ public: virtual RS::LightBakeMode light_get_bake_mode(RID p_light) override; virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override; virtual uint64_t light_get_version(RID p_light) const override; + virtual uint32_t light_get_cull_mask(RID p_light) const override; Dependency *light_get_dependency(RID p_light) const; diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.h b/servers/rendering/renderer_rd/storage_rd/material_storage.h index 0ac5557659..ac217d9a49 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.h @@ -323,13 +323,13 @@ public: // http://andrewthall.org/papers/df64_qf128.pdf #ifdef REAL_T_IS_DOUBLE - static _FORCE_INLINE_ void split_double(double a, float *ahi, float *alo) { + static _FORCE_INLINE_ void split_double(double a, float *a_hi, float *a_lo) { const double SPLITTER = (1 << 29) + 1; double t = a * SPLITTER; - double thi = t - (t - a); - double tlo = a - thi; - *ahi = (float)thi; - *alo = (float)tlo; + double t_hi = t - (t - a); + double t_lo = a - t_hi; + *a_hi = (float)t_hi; + *a_lo = (float)t_lo; } #endif diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp index f65676185c..96618c3352 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp @@ -586,6 +586,8 @@ void MeshStorage::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) { Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_COND(!mesh); mesh->custom_aabb = p_aabb; + + mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); } AABB MeshStorage::mesh_get_custom_aabb(RID p_mesh) const { @@ -1803,8 +1805,12 @@ void MeshStorage::multimesh_set_visible_instances(RID p_multimesh, int p_visible } if (multimesh->data_cache.size()) { - //there is a data cache.. + // There is a data cache, but we may need to update some sections. _multimesh_mark_all_dirty(multimesh, false, true); + int start = multimesh->visible_instances >= 0 ? multimesh->visible_instances : multimesh->instances; + for (int i = start; i < p_visible; i++) { + _multimesh_mark_dirty(multimesh, i, true); + } } multimesh->visible_instances = p_visible; diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp index 255719183f..f5d6404f01 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp @@ -50,25 +50,19 @@ void RenderSceneBuffersRD::_bind_methods() { // ClassDB::bind_method(D_METHOD("create_texture_view", "context", "name", "view_name", "view"), &RenderSceneBuffersRD::has_texture); ClassDB::bind_method(D_METHOD("get_texture", "context", "name"), &RenderSceneBuffersRD::get_texture); // ClassDB::bind_method(D_METHOD("get_texture_format", "context", "name"), &RenderSceneBuffersRD::get_texture_format); - ClassDB::bind_method(D_METHOD("get_texture_slice", "context", "name", "layer", "mipmap"), &RenderSceneBuffersRD::get_texture_slice); - ClassDB::bind_method(D_METHOD("get_texture_slice_size", "context", "name", "layer", "mipmap"), &RenderSceneBuffersRD::get_texture_slice_size); + ClassDB::bind_method(D_METHOD("get_texture_slice", "context", "name", "layer", "mipmap", "layers", "mipmaps"), &RenderSceneBuffersRD::get_texture_slice); + ClassDB::bind_method(D_METHOD("get_texture_slice_size", "context", "name", "mipmap"), &RenderSceneBuffersRD::get_texture_slice_size); ClassDB::bind_method(D_METHOD("clear_context", "context"), &RenderSceneBuffersRD::clear_context); } void RenderSceneBuffersRD::update_sizes(NamedTexture &p_named_texture) { ERR_FAIL_COND(p_named_texture.texture.is_null()); - uint32_t size = p_named_texture.format.array_layers * p_named_texture.format.mipmaps; - p_named_texture.sizes.resize(size); + p_named_texture.sizes.resize(p_named_texture.format.mipmaps); Size2i mipmap_size = Size2i(p_named_texture.format.width, p_named_texture.format.height); - for (uint32_t mipmap = 0; mipmap < p_named_texture.format.mipmaps; mipmap++) { - for (uint32_t layer = 0; layer < p_named_texture.format.array_layers; layer++) { - uint32_t index = layer * p_named_texture.format.mipmaps + mipmap; - - p_named_texture.sizes.ptrw()[index] = mipmap_size; - } + p_named_texture.sizes.ptrw()[mipmap] = mipmap_size; mipmap_size.width = MAX(1, mipmap_size.width >> 1); mipmap_size.height = MAX(1, mipmap_size.height >> 1); @@ -324,7 +318,7 @@ const RD::TextureFormat RenderSceneBuffersRD::get_texture_format(const StringNam return named_textures[key].format; } -RID RenderSceneBuffersRD::get_texture_slice(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_layer, const uint32_t p_mipmap) { +RID RenderSceneBuffersRD::get_texture_slice(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_layer, const uint32_t p_mipmap, const uint32_t p_layers, const uint32_t p_mipmaps) { NTKey key(p_context, p_texture_name); // check if this is a known texture @@ -334,36 +328,41 @@ RID RenderSceneBuffersRD::get_texture_slice(const StringName &p_context, const S // check if we're in bounds ERR_FAIL_UNSIGNED_INDEX_V(p_layer, named_texture.format.array_layers, RID()); + ERR_FAIL_COND_V(p_layers == 0, RID()); + ERR_FAIL_COND_V(p_layer + p_layers > named_texture.format.array_layers, RID()); ERR_FAIL_UNSIGNED_INDEX_V(p_mipmap, named_texture.format.mipmaps, RID()); + ERR_FAIL_COND_V(p_mipmaps == 0, RID()); + ERR_FAIL_COND_V(p_mipmap + p_mipmaps > named_texture.format.mipmaps, RID()); - // if we don't have multiple layers or mipmaps, we can just return our texture as is - if (named_texture.format.array_layers == 1 && named_texture.format.mipmaps == 1) { + // asking the whole thing? just return the original + if (p_layer == 0 && p_mipmap == 0 && named_texture.format.array_layers == p_layers && named_texture.format.mipmaps == p_mipmaps) { return named_texture.texture; } - // get our index and make sure we have enough entries in our slices vector - uint32_t index = p_layer * named_texture.format.mipmaps + p_mipmap; - while (named_texture.slices.size() <= int(index)) { - named_texture.slices.push_back(RID()); + // see if we have this + NTSliceKey slice_key(p_layer, p_layers, p_mipmap, p_mipmaps); + if (named_texture.slices.has(slice_key)) { + return named_texture.slices[slice_key]; } - // create our slice if we don't have it already - if (named_texture.slices[index].is_null()) { - named_texture.slices.ptrw()[index] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), named_texture.texture, p_layer, p_mipmap); + // create our slice + RID &slice = named_texture.slices[slice_key]; + slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), named_texture.texture, p_layer, p_mipmap, p_mipmaps, p_layers > 1 ? RD::TEXTURE_SLICE_2D_ARRAY : RD::TEXTURE_SLICE_2D, p_layers); - Array arr; - arr.push_back(p_context); - arr.push_back(p_texture_name); - arr.push_back(itos(p_layer)); - arr.push_back(itos(p_mipmap)); - RD::get_singleton()->set_resource_name(named_texture.slices[index], String("RenderBuffer {0}/{1} slice {2}/{3}").format(arr)); - } + Array arr; + arr.push_back(p_context); + arr.push_back(p_texture_name); + arr.push_back(itos(p_layer)); + arr.push_back(itos(p_layers)); + arr.push_back(itos(p_mipmap)); + arr.push_back(itos(p_mipmaps)); + RD::get_singleton()->set_resource_name(slice, String("RenderBuffer {0}/{1}, layer {2}/{3}, mipmap {4}/{5}").format(arr)); // and return our slice - return named_texture.slices[index]; + return slice; } -Size2i RenderSceneBuffersRD::get_texture_slice_size(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_layer, const uint32_t p_mipmap) { +Size2i RenderSceneBuffersRD::get_texture_slice_size(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_mipmap) { NTKey key(p_context, p_texture_name); // check if this is a known texture @@ -372,14 +371,10 @@ Size2i RenderSceneBuffersRD::get_texture_slice_size(const StringName &p_context, ERR_FAIL_COND_V(named_texture.texture.is_null(), Size2i()); // check if we're in bounds - ERR_FAIL_UNSIGNED_INDEX_V(p_layer, named_texture.format.array_layers, Size2i()); ERR_FAIL_UNSIGNED_INDEX_V(p_mipmap, named_texture.format.mipmaps, Size2i()); - // get our index - uint32_t index = p_layer * named_texture.format.mipmaps + p_mipmap; - - // and return our size - return named_texture.sizes[index]; + // return our size + return named_texture.sizes[p_mipmap]; } void RenderSceneBuffersRD::clear_context(const StringName &p_context) { diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h index 50fb06c0d9..9a299a3415 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h @@ -93,7 +93,6 @@ private: } static uint32_t hash(const NTKey &p_val) { - // FIXME, properly hash two stringnames together uint32_t h = p_val.context.hash(); h = hash_murmur3_one_32(p_val.buffer_name.hash(), h); return hash_fmix32(h); @@ -106,6 +105,33 @@ private: } }; + struct NTSliceKey { + uint32_t layer; + uint32_t layers; + uint32_t mipmap; + uint32_t mipmaps; + + bool operator==(const NTSliceKey &p_val) const { + return (layer == p_val.layer) && (layers == p_val.layers) && (mipmap == p_val.mipmap) && (mipmaps == p_val.mipmaps); + } + + static uint32_t hash(const NTSliceKey &p_val) { + uint32_t h = hash_murmur3_one_32(p_val.layer); + h = hash_murmur3_one_32(p_val.layers, h); + h = hash_murmur3_one_32(p_val.mipmap, h); + h = hash_murmur3_one_32(p_val.mipmaps, h); + return hash_fmix32(h); + } + + NTSliceKey() {} + NTSliceKey(uint32_t p_layer, uint32_t p_layers, uint32_t p_mipmap, uint32_t p_mipmaps) { + layer = p_layer; + layers = p_layers; + mipmap = p_mipmap; + mipmaps = p_mipmaps; + } + }; + struct NamedTexture { // Cache the data used to create our texture RD::TextureFormat format; @@ -113,7 +139,7 @@ private: // Our texture objects, slices are lazy (i.e. only created when requested). RID texture; - Vector<RID> slices; + mutable HashMap<NTSliceKey, RID, NTSliceKey> slices; Vector<Size2i> sizes; }; @@ -154,8 +180,8 @@ public: RID create_texture_view(const StringName &p_context, const StringName &p_texture_name, const StringName p_view_name, RD::TextureView p_view = RD::TextureView()); RID get_texture(const StringName &p_context, const StringName &p_texture_name) const; const RD::TextureFormat get_texture_format(const StringName &p_context, const StringName &p_texture_name) const; - RID get_texture_slice(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_layer, const uint32_t p_mipmap); - Size2i get_texture_slice_size(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_layer, const uint32_t p_mipmap); + RID get_texture_slice(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_layer, const uint32_t p_mipmap, const uint32_t p_layers = 1, const uint32_t p_mipmaps = 1); + Size2i get_texture_slice_size(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_mipmap); void clear_context(const StringName &p_context); diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index 5d845ce510..0ee9b28826 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -1906,7 +1906,7 @@ void TextureStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) { Decal *decal = decal_owner.get_or_null(p_decal); ERR_FAIL_COND(!decal); decal->cull_mask = p_layers; - decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB); + decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_DECAL); } void TextureStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) { @@ -1952,6 +1952,13 @@ AABB TextureStorage::decal_get_aabb(RID p_decal) const { return AABB(-decal->size / 2, decal->size); } +uint32_t TextureStorage::decal_get_cull_mask(RID p_decal) const { + Decal *decal = decal_owner.get_or_null(p_decal); + ERR_FAIL_COND_V(!decal, 0); + + return decal->cull_mask; +} + Dependency *TextureStorage::decal_get_dependency(RID p_decal) { Decal *decal = decal_owner.get_or_null(p_decal); ERR_FAIL_COND_V(!decal, nullptr); diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h index aeab3bf3cb..c16f5274ad 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h @@ -638,6 +638,7 @@ public: } virtual AABB decal_get_aabb(RID p_decal) const override; + virtual uint32_t decal_get_cull_mask(RID p_decal) const override; Dependency *decal_get_dependency(RID p_decal); /* DECAL INSTANCE API */ diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index d696955800..7d2cd12959 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -1787,6 +1787,7 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { pair.pair_allocator = &pair_allocator; pair.pair_pass = pair_pass; pair.pair_mask = 0; + pair.cull_mask = 0xFFFFFFFF; if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) { pair.pair_mask |= 1 << RS::INSTANCE_LIGHT; @@ -1807,12 +1808,14 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { pair.pair_mask |= (1 << RS::INSTANCE_VOXEL_GI); pair.bvh2 = &p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES]; } + pair.cull_mask = RSG::light_storage->light_get_cull_mask(p_instance->base); } else if (geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE)) { pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK; pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY]; } else if (geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && (p_instance->base_type == RS::INSTANCE_DECAL)) { pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK; pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY]; + pair.cull_mask = RSG::texture_storage->decal_get_cull_mask(p_instance->base); } else if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) { pair.pair_mask = (1 << RS::INSTANCE_PARTICLES); pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY]; diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index 2ec75b03ef..b3874ee7ae 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -485,6 +485,7 @@ public: singleton->_instance_queue_update(instance, true, false); } break; + case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: case Dependency::DEPENDENCY_CHANGED_MATERIAL: { singleton->_instance_queue_update(instance, false, true); } break; @@ -496,9 +497,6 @@ public: case Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE: { singleton->_instance_queue_update(instance, true, true); } break; - case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: { - //ignored - } break; case Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR: { //requires repairing if (instance->indexer_id.is_valid()) { @@ -735,11 +733,12 @@ public: DynamicBVH *bvh2 = nullptr; //some may need to cull in two uint32_t pair_mask; uint64_t pair_pass; + uint32_t cull_mask = 0xFFFFFFFF; // Needed for decals and lights in the mobile and compatibility renderers. _FORCE_INLINE_ bool operator()(void *p_data) { Instance *p_instance = (Instance *)p_data; - if (instance != p_instance && instance->transformed_aabb.intersects(p_instance->transformed_aabb) && (pair_mask & (1 << p_instance->base_type))) { + if (instance != p_instance && instance->transformed_aabb.intersects(p_instance->transformed_aabb) && (pair_mask & (1 << p_instance->base_type)) && (cull_mask & p_instance->layer_mask)) { //test is more coarse in indexer p_instance->pair_check = pair_pass; InstancePair *pair = pair_allocator->alloc(); diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 08ca25b64b..9117669124 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -530,7 +530,7 @@ public: TEXTURE_SLICE_2D_ARRAY, }; - virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, uint32_t p_mipmaps = 1, TextureSliceType p_slice_type = TEXTURE_SLICE_2D) = 0; + virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, uint32_t p_mipmaps = 1, TextureSliceType p_slice_type = TEXTURE_SLICE_2D, uint32_t p_layers = 0) = 0; virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS) = 0; virtual Vector<uint8_t> texture_get_data(RID p_texture, uint32_t p_layer) = 0; // CPU textures will return immediately, while GPU textures will most likely force a flush diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 11a9303f11..2dc1c70064 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -1225,7 +1225,7 @@ void ShaderLanguage::clear() { char_idx = 0; error_set = false; error_str = ""; - last_const = false; + is_const_decl = false; while (nodes) { Node *n = nodes; nodes = nodes->next; @@ -3561,6 +3561,14 @@ bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Functio return false; } + if (is_const_decl && arg->type == Node::TYPE_VARIABLE) { + const VariableNode *var = static_cast<const VariableNode *>(arg); + if (!var->is_const) { + _set_error(RTR("Expected constant expression.")); + return false; + } + } + p_func->arguments.push_back(arg); tk = _get_token(); @@ -4530,14 +4538,14 @@ bool ShaderLanguage::_check_node_constness(const Node *p_node) const { case Node::TYPE_CONSTANT: break; case Node::TYPE_VARIABLE: { - const VariableNode *varn = static_cast<const VariableNode *>(p_node); - if (!varn->is_const) { + const VariableNode *var_node = static_cast<const VariableNode *>(p_node); + if (!var_node->is_const) { return false; } } break; case Node::TYPE_ARRAY: { - const ArrayNode *arrn = static_cast<const ArrayNode *>(p_node); - if (!arrn->is_const) { + const ArrayNode *arr_node = static_cast<const ArrayNode *>(p_node); + if (!arr_node->is_const) { return false; } } break; @@ -5184,6 +5192,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expr = func; } else { //a function call + if (p_block == nullptr) { // Non-constructor function call in global space is forbidden. + if (is_const_decl) { + _set_error(RTR("Expected constant expression.")); + } + return nullptr; + } const StringName &name = identifier; @@ -5460,6 +5474,10 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons _set_error(vformat(RTR("Unknown identifier in expression: '%s'."), String(identifier))); return nullptr; } + if (is_const_decl && !is_const) { + _set_error(RTR("Expected constant expression.")); + return nullptr; + } if (ident_type == IDENTIFIER_VARYING) { TkPos prev_pos = _get_tkpos(); Token next_token = _get_token(); @@ -6977,6 +6995,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun } } #endif // DEBUG_ENABLED + is_const_decl = is_const; BlockNode::Variable var; var.type = type; @@ -7233,6 +7252,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun vdnode->declarations.push_back(decl); p_block->variables[name] = var; + is_const_decl = false; if (!fixed_array_size) { array_size = 0; @@ -9101,6 +9121,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f constant.precision = precision; constant.initializer = nullptr; constant.array_size = array_size; + is_const_decl = true; if (tk.type == TK_BRACKET_OPEN) { Error error = _parse_array_size(nullptr, constants, false, nullptr, &constant.array_size, &unknown_size); @@ -9360,6 +9381,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f unknown_size = false; } else if (tk.type == TK_SEMICOLON) { + is_const_decl = false; break; } else { _set_expected_error(",", ";"); diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index 32e497aa46..aea61e42c3 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -953,7 +953,7 @@ private: StringName shader_type_identifier; StringName current_function; - bool last_const = false; + bool is_const_decl = false; StringName last_name; bool is_shader_inc = false; diff --git a/servers/rendering/storage/light_storage.h b/servers/rendering/storage/light_storage.h index 9f3f5dd8e4..5bd4297179 100644 --- a/servers/rendering/storage/light_storage.h +++ b/servers/rendering/storage/light_storage.h @@ -84,6 +84,7 @@ public: virtual RS::LightBakeMode light_get_bake_mode(RID p_light) = 0; virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) = 0; virtual uint64_t light_get_version(RID p_light) const = 0; + virtual uint32_t light_get_cull_mask(RID p_light) const = 0; /* LIGHT INSTANCE API */ diff --git a/servers/rendering/storage/texture_storage.h b/servers/rendering/storage/texture_storage.h index 3a9034ad0d..227d44aa27 100644 --- a/servers/rendering/storage/texture_storage.h +++ b/servers/rendering/storage/texture_storage.h @@ -118,6 +118,7 @@ public: virtual void decal_set_normal_fade(RID p_decal, float p_fade) = 0; virtual AABB decal_get_aabb(RID p_decal) const = 0; + virtual uint32_t decal_get_cull_mask(RID p_decal) const = 0; virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0; virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 1c19b9dcd0..848b6d01d4 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2675,6 +2675,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_filter", "light", "filter"), &RenderingServer::canvas_light_set_shadow_filter); ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_color", "light", "color"), &RenderingServer::canvas_light_set_shadow_color); ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_smooth", "light", "smooth"), &RenderingServer::canvas_light_set_shadow_smooth); + ClassDB::bind_method(D_METHOD("canvas_light_set_blend_mode", "light", "mode"), &RenderingServer::canvas_light_set_blend_mode); BIND_ENUM_CONSTANT(CANVAS_LIGHT_MODE_POINT); BIND_ENUM_CONSTANT(CANVAS_LIGHT_MODE_DIRECTIONAL); diff --git a/servers/xr/xr_interface.cpp b/servers/xr/xr_interface.cpp index 9968a47b0c..7f3d8668a4 100644 --- a/servers/xr/xr_interface.cpp +++ b/servers/xr/xr_interface.cpp @@ -75,6 +75,10 @@ void XRInterface::_bind_methods() { ClassDB::bind_method(D_METHOD("get_transform_for_view", "view", "cam_transform"), &XRInterface::get_transform_for_view); ClassDB::bind_method(D_METHOD("get_projection_for_view", "view", "aspect", "near", "far"), &XRInterface::get_projection_for_view); + /** environment blend mode. */ + ClassDB::bind_method(D_METHOD("get_supported_environment_blend_modes"), &XRInterface::get_supported_environment_blend_modes); + ClassDB::bind_method(D_METHOD("set_environment_blend_mode", "mode"), &XRInterface::set_environment_blend_mode); + ADD_GROUP("AR", "ar_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ar_is_anchor_detection_enabled"), "set_anchor_detection_is_enabled", "get_anchor_detection_is_enabled"); @@ -97,6 +101,10 @@ void XRInterface::_bind_methods() { BIND_ENUM_CONSTANT(XR_PLAY_AREA_SITTING); BIND_ENUM_CONSTANT(XR_PLAY_AREA_ROOMSCALE); BIND_ENUM_CONSTANT(XR_PLAY_AREA_STAGE); + + BIND_ENUM_CONSTANT(XR_ENV_BLEND_MODE_OPAQUE); + BIND_ENUM_CONSTANT(XR_ENV_BLEND_MODE_ADDITIVE); + BIND_ENUM_CONSTANT(XR_ENV_BLEND_MODE_ALPHA_BLEND); }; bool XRInterface::is_primary() { @@ -273,3 +281,9 @@ XRInterface::TrackingStatus XRInterface::get_tracking_status() const { void XRInterface::trigger_haptic_pulse(const String &p_action_name, const StringName &p_tracker_name, double p_frequency, double p_amplitude, double p_duration_sec, double p_delay_sec) { } + +Array XRInterface::get_supported_environment_blend_modes() { + Array default_blend_modes; + default_blend_modes.push_back(XR_ENV_BLEND_MODE_OPAQUE); + return default_blend_modes; +} diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h index 6f70f75772..c32455f466 100644 --- a/servers/xr/xr_interface.h +++ b/servers/xr/xr_interface.h @@ -78,6 +78,12 @@ public: XR_PLAY_AREA_STAGE, /* Same as roomscale but origin point is fixed to the center of the physical space, XRServer.center_on_hmd disabled */ }; + enum EnvironmentBlendMode { + XR_ENV_BLEND_MODE_OPAQUE, /* You cannot see the real world, VR like */ + XR_ENV_BLEND_MODE_ADDITIVE, /* You can see the real world, AR like */ + XR_ENV_BLEND_MODE_ALPHA_BLEND, /* Real world is passed through where alpha channel is 0.0 and gradually blends to opaque for value 1.0. */ + }; + protected: _THREAD_SAFE_CLASS_ @@ -138,6 +144,10 @@ public: virtual bool start_passthrough() { return false; } virtual void stop_passthrough() {} + /** environment blend mode. */ + virtual Array get_supported_environment_blend_modes(); + virtual bool set_environment_blend_mode(EnvironmentBlendMode mode) { return false; } + XRInterface(); ~XRInterface(); @@ -151,5 +161,6 @@ private: VARIANT_ENUM_CAST(XRInterface::Capabilities); VARIANT_ENUM_CAST(XRInterface::TrackingStatus); VARIANT_ENUM_CAST(XRInterface::PlayAreaMode); +VARIANT_ENUM_CAST(XRInterface::EnvironmentBlendMode); #endif // XR_INTERFACE_H |