Extract Decal and Decal atlas from Storage class

This commit is contained in:
Bastiaan Olij 2022-03-20 22:28:24 +11:00
parent aa8ff21b2a
commit 0fe06e9467
27 changed files with 1001 additions and 686 deletions

View file

@ -39,6 +39,7 @@
#include "servers/rendering/renderer_compositor.h"
#include "storage/canvas_texture_storage.h"
#include "storage/config.h"
#include "storage/decal_atlas_storage.h"
#include "storage/render_target_storage.h"
#include "storage/texture_storage.h"
@ -53,6 +54,7 @@ protected:
GLES3::Config config;
GLES3::CanvasTextureStorage canvas_texture_storage;
GLES3::TextureStorage texture_storage;
GLES3::DecalAtlasStorage decal_atlas_storage;
RasterizerStorageGLES3 storage;
RasterizerCanvasGLES3 canvas;
RasterizerSceneGLES3 scene;
@ -62,6 +64,7 @@ protected:
public:
RendererCanvasTextureStorage *get_canvas_texture_storage() { return &canvas_texture_storage; }
RendererTextureStorage *get_texture_storage() { return &texture_storage; }
RendererDecalAtlasStorage *get_decal_atlas_storage() { return &decal_atlas_storage; }
RendererStorage *get_storage() { return &storage; }
RendererCanvasRender *get_canvas() { return &canvas; }
RendererSceneRender *get_scene() { return &scene; }

View file

@ -1202,46 +1202,6 @@ void RasterizerStorageGLES3::base_update_dependency(RID p_base, DependencyTracke
void RasterizerStorageGLES3::skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) {
}
/* DECAL API */
RID RasterizerStorageGLES3::decal_allocate() {
return RID();
}
void RasterizerStorageGLES3::decal_initialize(RID p_rid) {
}
void RasterizerStorageGLES3::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
}
void RasterizerStorageGLES3::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
}
void RasterizerStorageGLES3::decal_set_emission_energy(RID p_decal, float p_energy) {
}
void RasterizerStorageGLES3::decal_set_albedo_mix(RID p_decal, float p_mix) {
}
void RasterizerStorageGLES3::decal_set_modulate(RID p_decal, const Color &p_modulate) {
}
void RasterizerStorageGLES3::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
}
void RasterizerStorageGLES3::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
}
void RasterizerStorageGLES3::decal_set_fade(RID p_decal, float p_above, float p_below) {
}
void RasterizerStorageGLES3::decal_set_normal_fade(RID p_decal, float p_fade) {
}
AABB RasterizerStorageGLES3::decal_get_aabb(RID p_decal) const {
return AABB();
}
/* VOXEL GI API */
RID RasterizerStorageGLES3::voxel_gi_allocate() {

View file

@ -579,25 +579,6 @@ public:
void base_update_dependency(RID p_base, DependencyTracker *p_instance) override;
void skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) override;
/* DECAL API */
RID decal_allocate() override;
void decal_initialize(RID p_rid) override;
void decal_set_extents(RID p_decal, const Vector3 &p_extents) override;
void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override;
void decal_set_emission_energy(RID p_decal, float p_energy) override;
void decal_set_albedo_mix(RID p_decal, float p_mix) override;
void decal_set_modulate(RID p_decal, const Color &p_modulate) override;
void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override;
void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override;
void decal_set_fade(RID p_decal, float p_above, float p_below) override;
void decal_set_normal_fade(RID p_decal, float p_fade) override;
AABB decal_get_aabb(RID p_decal) const override;
void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
/* VOXEL GI API */
RID voxel_gi_allocate() override;

View file

@ -0,0 +1,75 @@
/*************************************************************************/
/* decal_atlas_storage.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 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. */
/*************************************************************************/
#ifdef GLES3_ENABLED
#include "decal_atlas_storage.h"
using namespace GLES3;
RID DecalAtlasStorage::decal_allocate() {
return RID();
}
void DecalAtlasStorage::decal_initialize(RID p_rid) {
}
void DecalAtlasStorage::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
}
void DecalAtlasStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
}
void DecalAtlasStorage::decal_set_emission_energy(RID p_decal, float p_energy) {
}
void DecalAtlasStorage::decal_set_albedo_mix(RID p_decal, float p_mix) {
}
void DecalAtlasStorage::decal_set_modulate(RID p_decal, const Color &p_modulate) {
}
void DecalAtlasStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
}
void DecalAtlasStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
}
void DecalAtlasStorage::decal_set_fade(RID p_decal, float p_above, float p_below) {
}
void DecalAtlasStorage::decal_set_normal_fade(RID p_decal, float p_fade) {
}
AABB DecalAtlasStorage::decal_get_aabb(RID p_decal) const {
return AABB();
}
#endif // !GLES3_ENABLED

View file

@ -0,0 +1,67 @@
/*************************************************************************/
/* decal_atlas_storage.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 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 DECAL_ATLAS_STORAGE_GLES3_H
#define DECAL_ATLAS_STORAGE_GLES3_H
#ifdef GLES3_ENABLED
#include "core/templates/rid_owner.h"
#include "servers/rendering/storage/decal_atlas_storage.h"
namespace GLES3 {
class DecalAtlasStorage : public RendererDecalAtlasStorage {
public:
virtual RID decal_allocate() override;
virtual void decal_initialize(RID p_rid) override;
virtual void decal_free(RID p_rid) override{};
virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override;
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override;
virtual void decal_set_emission_energy(RID p_decal, float p_energy) override;
virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override;
virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) override;
virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override;
virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override;
virtual void decal_set_fade(RID p_decal, float p_above, float p_below) override;
virtual void decal_set_normal_fade(RID p_decal, float p_fade) override;
virtual AABB decal_get_aabb(RID p_decal) const override;
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 {}
};
} // namespace GLES3
#endif // !GLES3_ENABLED
#endif // !DECAL_ATLAS_STORAGE_GLES3_H

View file

@ -38,6 +38,7 @@
#include "servers/rendering/dummy/rasterizer_scene_dummy.h"
#include "servers/rendering/dummy/rasterizer_storage_dummy.h"
#include "servers/rendering/dummy/storage/canvas_texture_storage.h"
#include "servers/rendering/dummy/storage/decal_atlas_storage.h"
#include "servers/rendering/dummy/storage/texture_storage.h"
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering_server.h"
@ -51,12 +52,14 @@ protected:
RasterizerCanvasDummy canvas;
RendererDummy::CanvasTextureStorage canvas_texture_storage;
RendererDummy::TextureStorage texture_storage;
RendererDummy::DecalAtlasStorage decal_atlas_storage;
RasterizerStorageDummy storage;
RasterizerSceneDummy scene;
public:
RendererCanvasTextureStorage *get_canvas_texture_storage() override { return &canvas_texture_storage; };
RendererTextureStorage *get_texture_storage() override { return &texture_storage; };
RendererDecalAtlasStorage *get_decal_atlas_storage() override { return &decal_atlas_storage; };
RendererStorage *get_storage() override { return &storage; }
RendererCanvasRender *get_canvas() override { return &canvas; }
RendererSceneRender *get_scene() override { return &scene; }

View file

@ -214,25 +214,6 @@ public:
void base_update_dependency(RID p_base, DependencyTracker *p_instance) override {}
void skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) override {}
/* DECAL API */
RID decal_allocate() override { return RID(); }
void decal_initialize(RID p_rid) override {}
void decal_set_extents(RID p_decal, const Vector3 &p_extents) override {}
void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override {}
void decal_set_emission_energy(RID p_decal, float p_energy) override {}
void decal_set_albedo_mix(RID p_decal, float p_mix) override {}
void decal_set_modulate(RID p_decal, const Color &p_modulate) override {}
void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override {}
void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override {}
void decal_set_fade(RID p_decal, float p_above, float p_below) override {}
void decal_set_normal_fade(RID p_decal, float p_fade) override {}
AABB decal_get_aabb(RID p_decal) const override { return AABB(); }
void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
/* VOXEL GI API */
RID voxel_gi_allocate() override { return RID(); }

View file

@ -0,0 +1,62 @@
/*************************************************************************/
/* decal_atlas_storage.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 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 DECAL_ATLAS_STORAGE_DUMMY_H
#define DECAL_ATLAS_STORAGE_DUMMY_H
#include "servers/rendering/storage/decal_atlas_storage.h"
namespace RendererDummy {
class DecalAtlasStorage : public RendererDecalAtlasStorage {
public:
virtual RID decal_allocate() override { return RID(); }
virtual void decal_initialize(RID p_rid) override {}
virtual void decal_free(RID p_rid) override{};
virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override {}
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override {}
virtual void decal_set_emission_energy(RID p_decal, float p_energy) override {}
virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override {}
virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) override {}
virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override {}
virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override {}
virtual void decal_set_fade(RID p_decal, float p_above, float p_below) override {}
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 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 {}
};
} // namespace RendererDummy
#endif // !DECAL_ATLAS_STORAGE_DUMMY_H

View file

@ -35,6 +35,7 @@
#include "servers/rendering/renderer_scene.h"
#include "servers/rendering/renderer_storage.h"
#include "servers/rendering/storage/canvas_texture_storage.h"
#include "servers/rendering/storage/decal_atlas_storage.h"
#include "servers/rendering/storage/texture_storage.h"
#include "servers/rendering_server.h"
@ -74,6 +75,7 @@ public:
virtual RendererCanvasTextureStorage *get_canvas_texture_storage() = 0;
virtual RendererTextureStorage *get_texture_storage() = 0;
virtual RendererDecalAtlasStorage *get_decal_atlas_storage() = 0;
virtual RendererStorage *get_storage() = 0;
virtual RendererCanvasRender *get_canvas() = 0;
virtual RendererSceneRender *get_scene() = 0;

View file

@ -30,6 +30,7 @@
#include "render_forward_clustered.h"
#include "core/config/project_settings.h"
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h"
#include "servers/rendering/rendering_device.h"
#include "servers/rendering/rendering_server_default.h"
@ -2140,7 +2141,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() {
RD::Uniform u;
u.binding = 11;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID decal_atlas = storage->decal_atlas_get_texture();
RID decal_atlas = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture();
u.append_id(decal_atlas);
uniforms.push_back(u);
}
@ -2148,7 +2149,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() {
RD::Uniform u;
u.binding = 12;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID decal_atlas = storage->decal_atlas_get_texture_srgb();
RID decal_atlas = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture_srgb();
u.append_id(decal_atlas);
uniforms.push_back(u);
}

View file

@ -30,6 +30,7 @@
#include "render_forward_mobile.h"
#include "core/config/project_settings.h"
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
#include "servers/rendering/rendering_device.h"
#include "servers/rendering/rendering_server_default.h"
@ -1275,7 +1276,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() {
RD::Uniform u;
u.binding = 11;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID decal_atlas = storage->decal_atlas_get_texture();
RID decal_atlas = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture();
u.append_id(decal_atlas);
uniforms.push_back(u);
}
@ -1283,7 +1284,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() {
RD::Uniform u;
u.binding = 12;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID decal_atlas = storage->decal_atlas_get_texture_srgb();
RID decal_atlas = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture_srgb();
u.append_id(decal_atlas);
uniforms.push_back(u);
}

View file

@ -35,6 +35,7 @@
#include "core/math/math_defs.h"
#include "core/math/math_funcs.h"
#include "renderer_compositor_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
#include "servers/rendering/rendering_server_default.h"
void RendererCanvasRenderRD::_update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4) {
@ -947,7 +948,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 3;
u.append_id(storage->decal_atlas_get_texture());
u.append_id(RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture());
uniforms.push_back(u);
}
@ -1253,7 +1254,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
}
if (clight->texture.is_valid()) {
Rect2 atlas_rect = storage->decal_atlas_get_texture_rect(clight->texture);
Rect2 atlas_rect = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture_rect(clight->texture);
state.light_uniforms[index].atlas_rect[0] = atlas_rect.position.x;
state.light_uniforms[index].atlas_rect[1] = atlas_rect.position.y;
state.light_uniforms[index].atlas_rect[2] = atlas_rect.size.width;
@ -1479,18 +1480,20 @@ RID RendererCanvasRenderRD::light_create() {
}
void RendererCanvasRenderRD::light_set_texture(RID p_rid, RID p_texture) {
RendererRD::DecalAtlasStorage *decal_atlas_storage = RendererRD::DecalAtlasStorage::get_singleton();
CanvasLight *cl = canvas_light_owner.get_or_null(p_rid);
ERR_FAIL_COND(!cl);
if (cl->texture == p_texture) {
return;
}
if (cl->texture.is_valid()) {
storage->texture_remove_from_decal_atlas(cl->texture);
decal_atlas_storage->texture_remove_from_decal_atlas(cl->texture);
}
cl->texture = p_texture;
if (cl->texture.is_valid()) {
storage->texture_add_to_decal_atlas(cl->texture);
decal_atlas_storage->texture_add_to_decal_atlas(cl->texture);
}
}

View file

@ -155,6 +155,7 @@ void RendererCompositorRD::finalize() {
memdelete(scene);
memdelete(canvas);
memdelete(storage);
memdelete(decal_atlas_storage);
memdelete(texture_storage);
memdelete(canvas_texture_storage);
@ -287,6 +288,7 @@ RendererCompositorRD::RendererCompositorRD() {
canvas_texture_storage = memnew(RendererRD::CanvasTextureStorage);
texture_storage = memnew(RendererRD::TextureStorage);
decal_atlas_storage = memnew(RendererRD::DecalAtlasStorage);
storage = memnew(RendererStorageRD);
canvas = memnew(RendererCanvasRenderRD(storage));

View file

@ -40,6 +40,7 @@
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/blit.glsl.gen.h"
#include "servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h"
@ -49,6 +50,7 @@ protected:
RendererCanvasRenderRD *canvas;
RendererRD::CanvasTextureStorage *canvas_texture_storage;
RendererRD::TextureStorage *texture_storage;
RendererRD::DecalAtlasStorage *decal_atlas_storage;
RendererStorageRD *storage;
RendererSceneRenderRD *scene;
@ -92,8 +94,9 @@ protected:
static uint64_t frame;
public:
RendererCanvasTextureStorage *get_canvas_texture_storage() { return canvas_texture_storage; };
RendererTextureStorage *get_texture_storage() { return texture_storage; };
RendererCanvasTextureStorage *get_canvas_texture_storage() { return canvas_texture_storage; }
RendererTextureStorage *get_texture_storage() { return texture_storage; }
RendererDecalAtlasStorage *get_decal_atlas_storage() { return decal_atlas_storage; }
RendererStorage *get_storage() { return storage; }
RendererCanvasRender *get_canvas() { return canvas; }
RendererSceneRender *get_scene() { return scene; }

View file

@ -33,6 +33,7 @@
#include "core/config/project_settings.h"
#include "core/os/os.h"
#include "renderer_compositor_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
#include "servers/rendering/rendering_server_default.h"
void get_vogel_disk(float *r_kernel, int p_sample_count) {
@ -2674,7 +2675,7 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID
}
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_DECAL_ATLAS) {
RID decal_atlas = storage->decal_atlas_get_texture();
RID decal_atlas = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture();
if (decal_atlas.is_valid()) {
Size2 rtsize = storage->render_target_get_size(rb->render_target);
@ -3262,6 +3263,8 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti
}
void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const Transform3D &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count, bool &r_directional_light_soft_shadows) {
RendererRD::DecalAtlasStorage *decal_atlas_storage = RendererRD::DecalAtlasStorage::get_singleton();
Transform3D inverse_transform = p_camera_transform.affine_inverse();
r_directional_light_count = 0;
@ -3545,7 +3548,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
RID projector = storage->light_get_projector(base);
if (projector.is_valid()) {
Rect2 rect = storage->decal_atlas_get_texture_rect(projector);
Rect2 rect = decal_atlas_storage->decal_atlas_get_texture_rect(projector);
if (type == RS::LIGHT_SPOT) {
light_data.projector_rect[0] = rect.position.x;
@ -3661,6 +3664,8 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
}
void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const Transform3D &p_camera_inverse_xform) {
RendererRD::DecalAtlasStorage *decal_atlas_storage = RendererRD::DecalAtlasStorage::get_singleton();
Transform3D uv_xform;
uv_xform.basis.scale(Vector3(2.0, 1.0, 2.0));
uv_xform.origin = Vector3(-1.0, 0.0, -1.0);
@ -3684,9 +3689,9 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
real_t distance = -p_camera_inverse_xform.xform(xform.origin).z;
if (storage->decal_is_distance_fade_enabled(decal)) {
float fade_begin = storage->decal_get_distance_fade_begin(decal);
float fade_length = storage->decal_get_distance_fade_length(decal);
if (decal_atlas_storage->decal_is_distance_fade_enabled(decal)) {
float fade_begin = decal_atlas_storage->decal_get_distance_fade_begin(decal);
float fade_length = decal_atlas_storage->decal_get_distance_fade_length(decal);
if (distance > fade_begin) {
if (distance > fade_begin + fade_length) {
@ -3714,15 +3719,15 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
_map_forward_id(FORWARD_ID_TYPE_DECAL, di->forward_id, i);
}
di->cull_mask = storage->decal_get_cull_mask(decal);
di->cull_mask = decal_atlas_storage->decal_get_cull_mask(decal);
Transform3D xform = di->transform;
float fade = 1.0;
if (storage->decal_is_distance_fade_enabled(decal)) {
if (decal_atlas_storage->decal_is_distance_fade_enabled(decal)) {
real_t distance = -p_camera_inverse_xform.xform(xform.origin).z;
float fade_begin = storage->decal_get_distance_fade_begin(decal);
float fade_length = storage->decal_get_distance_fade_length(decal);
float fade_begin = decal_atlas_storage->decal_get_distance_fade_begin(decal);
float fade_length = decal_atlas_storage->decal_get_distance_fade_length(decal);
if (distance > fade_begin) {
fade = 1.0 - (distance - fade_begin) / fade_length;
@ -3731,7 +3736,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
Cluster::DecalData &dd = cluster.decals[i];
Vector3 decal_extents = storage->decal_get_extents(decal);
Vector3 decal_extents = decal_atlas_storage->decal_get_extents(decal);
Transform3D scale_xform;
scale_xform.basis.scale(decal_extents);
@ -3744,12 +3749,12 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
dd.normal[0] = normal.x;
dd.normal[1] = normal.y;
dd.normal[2] = normal.z;
dd.normal_fade = storage->decal_get_normal_fade(decal);
dd.normal_fade = decal_atlas_storage->decal_get_normal_fade(decal);
RID albedo_tex = storage->decal_get_texture(decal, RS::DECAL_TEXTURE_ALBEDO);
RID emission_tex = storage->decal_get_texture(decal, RS::DECAL_TEXTURE_EMISSION);
RID albedo_tex = decal_atlas_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_ALBEDO);
RID emission_tex = decal_atlas_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_EMISSION);
if (albedo_tex.is_valid()) {
Rect2 rect = storage->decal_atlas_get_texture_rect(albedo_tex);
Rect2 rect = decal_atlas_storage->decal_atlas_get_texture_rect(albedo_tex);
dd.albedo_rect[0] = rect.position.x;
dd.albedo_rect[1] = rect.position.y;
dd.albedo_rect[2] = rect.size.x;
@ -3764,10 +3769,10 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
dd.albedo_rect[3] = 0;
}
RID normal_tex = storage->decal_get_texture(decal, RS::DECAL_TEXTURE_NORMAL);
RID normal_tex = decal_atlas_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_NORMAL);
if (normal_tex.is_valid()) {
Rect2 rect = storage->decal_atlas_get_texture_rect(normal_tex);
Rect2 rect = decal_atlas_storage->decal_atlas_get_texture_rect(normal_tex);
dd.normal_rect[0] = rect.position.x;
dd.normal_rect[1] = rect.position.y;
dd.normal_rect[2] = rect.size.x;
@ -3782,9 +3787,9 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
dd.normal_rect[3] = 0;
}
RID orm_tex = storage->decal_get_texture(decal, RS::DECAL_TEXTURE_ORM);
RID orm_tex = decal_atlas_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_ORM);
if (orm_tex.is_valid()) {
Rect2 rect = storage->decal_atlas_get_texture_rect(orm_tex);
Rect2 rect = decal_atlas_storage->decal_atlas_get_texture_rect(orm_tex);
dd.orm_rect[0] = rect.position.x;
dd.orm_rect[1] = rect.position.y;
dd.orm_rect[2] = rect.size.x;
@ -3797,7 +3802,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
}
if (emission_tex.is_valid()) {
Rect2 rect = storage->decal_atlas_get_texture_rect(emission_tex);
Rect2 rect = decal_atlas_storage->decal_atlas_get_texture_rect(emission_tex);
dd.emission_rect[0] = rect.position.x;
dd.emission_rect[1] = rect.position.y;
dd.emission_rect[2] = rect.size.x;
@ -3809,16 +3814,16 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
dd.emission_rect[3] = 0;
}
Color modulate = storage->decal_get_modulate(decal);
Color modulate = decal_atlas_storage->decal_get_modulate(decal);
dd.modulate[0] = modulate.r;
dd.modulate[1] = modulate.g;
dd.modulate[2] = modulate.b;
dd.modulate[3] = modulate.a * fade;
dd.emission_energy = storage->decal_get_emission_energy(decal) * fade;
dd.albedo_mix = storage->decal_get_albedo_mix(decal);
dd.mask = storage->decal_get_cull_mask(decal);
dd.upper_fade = storage->decal_get_upper_fade(decal);
dd.lower_fade = storage->decal_get_lower_fade(decal);
dd.emission_energy = decal_atlas_storage->decal_get_emission_energy(decal) * fade;
dd.albedo_mix = decal_atlas_storage->decal_get_albedo_mix(decal);
dd.mask = decal_atlas_storage->decal_get_cull_mask(decal);
dd.upper_fade = decal_atlas_storage->decal_get_upper_fade(decal);
dd.lower_fade = decal_atlas_storage->decal_get_lower_fade(decal);
if (current_cluster_builder != nullptr) {
current_cluster_builder->add_box(ClusterBuilderRD::BOX_TYPE_DECAL, xform, decal_extents);

View file

@ -36,6 +36,7 @@
#include "core/math/math_defs.h"
#include "renderer_compositor_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/rendering_server_globals.h"
#include "servers/rendering/shader_language.h"
@ -5315,6 +5316,7 @@ void RendererStorageRD::light_set_shadow(RID p_light, bool p_enabled) {
}
void RendererStorageRD::light_set_projector(RID p_light, RID p_texture) {
RendererRD::DecalAtlasStorage *decal_atlas_storage = RendererRD::DecalAtlasStorage::get_singleton();
Light *light = light_owner.get_or_null(p_light);
ERR_FAIL_COND(!light);
@ -5323,14 +5325,14 @@ void RendererStorageRD::light_set_projector(RID p_light, RID p_texture) {
}
if (light->type != RS::LIGHT_DIRECTIONAL && light->projector.is_valid()) {
texture_remove_from_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
decal_atlas_storage->texture_remove_from_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
}
light->projector = p_texture;
if (light->type != RS::LIGHT_DIRECTIONAL) {
if (light->projector.is_valid()) {
texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
decal_atlas_storage->texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
}
light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
}
@ -5727,97 +5729,6 @@ float RendererStorageRD::reflection_probe_get_ambient_color_energy(RID p_probe)
return reflection_probe->ambient_color_energy;
}
RID RendererStorageRD::decal_allocate() {
return decal_owner.allocate_rid();
}
void RendererStorageRD::decal_initialize(RID p_decal) {
decal_owner.initialize_rid(p_decal, Decal());
}
void RendererStorageRD::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
decal->extents = p_extents;
decal->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
void RendererStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
ERR_FAIL_INDEX(p_type, RS::DECAL_TEXTURE_MAX);
if (decal->textures[p_type] == p_texture) {
return;
}
ERR_FAIL_COND(p_texture.is_valid() && !RendererRD::TextureStorage::get_singleton()->owns_texture(p_texture));
if (decal->textures[p_type].is_valid() && RendererRD::TextureStorage::get_singleton()->owns_texture(decal->textures[p_type])) {
texture_remove_from_decal_atlas(decal->textures[p_type]);
}
decal->textures[p_type] = p_texture;
if (decal->textures[p_type].is_valid()) {
texture_add_to_decal_atlas(decal->textures[p_type]);
}
decal->dependency.changed_notify(DEPENDENCY_CHANGED_DECAL);
}
void RendererStorageRD::decal_set_emission_energy(RID p_decal, float p_energy) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
decal->emission_energy = p_energy;
}
void RendererStorageRD::decal_set_albedo_mix(RID p_decal, float p_mix) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
decal->albedo_mix = p_mix;
}
void RendererStorageRD::decal_set_modulate(RID p_decal, const Color &p_modulate) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
decal->modulate = p_modulate;
}
void RendererStorageRD::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_CHANGED_AABB);
}
void RendererStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
decal->distance_fade = p_enabled;
decal->distance_fade_begin = p_begin;
decal->distance_fade_length = p_length;
}
void RendererStorageRD::decal_set_fade(RID p_decal, float p_above, float p_below) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
decal->upper_fade = p_above;
decal->lower_fade = p_below;
}
void RendererStorageRD::decal_set_normal_fade(RID p_decal, float p_fade) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
decal->normal_fade = p_fade;
}
AABB RendererStorageRD::decal_get_aabb(RID p_decal) const {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND_V(!decal, AABB());
return AABB(-decal->extents, decal->extents * 2.0);
}
RID RendererStorageRD::voxel_gi_allocate() {
return voxel_gi_owner.allocate_rid();
}
@ -7030,8 +6941,8 @@ void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_
} else if (reflection_probe_owner.owns(p_base)) {
ReflectionProbe *rp = reflection_probe_owner.get_or_null(p_base);
p_instance->update_dependency(&rp->dependency);
} else if (decal_owner.owns(p_base)) {
Decal *decal = decal_owner.get_or_null(p_base);
} else if (RendererRD::DecalAtlasStorage::get_singleton()->owns_decal(p_base)) {
RendererRD::Decal *decal = RendererRD::DecalAtlasStorage::get_singleton()->get_decal(p_base);
p_instance->update_dependency(&decal->dependency);
} else if (voxel_gi_owner.owns(p_base)) {
VoxelGI *gip = voxel_gi_owner.get_or_null(p_base);
@ -7074,7 +6985,7 @@ RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const {
if (reflection_probe_owner.owns(p_rid)) {
return RS::INSTANCE_REFLECTION_PROBE;
}
if (decal_owner.owns(p_rid)) {
if (RendererRD::DecalAtlasStorage::get_singleton()->owns_decal(p_rid)) {
return RS::INSTANCE_DECAL;
}
if (voxel_gi_owner.owns(p_rid)) {
@ -7102,252 +7013,6 @@ RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const {
return RS::INSTANCE_NONE;
}
void RendererStorageRD::decal_atlas_remove_texture(RID p_texture) {
if (decal_atlas.textures.has(p_texture)) {
decal_atlas.textures.erase(p_texture);
//there is not much a point of making it dirty, just let it be.
}
}
void RendererStorageRD::decal_atlas_mark_dirty_on_texture(RID p_texture) {
if (decal_atlas.textures.has(p_texture)) {
//belongs to decal atlas..
decal_atlas.dirty = true; //mark it dirty since it was most likely modified
}
}
void RendererStorageRD::texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp) {
if (!decal_atlas.textures.has(p_texture)) {
DecalAtlas::Texture t;
t.users = 1;
t.panorama_to_dp_users = p_panorama_to_dp ? 1 : 0;
decal_atlas.textures[p_texture] = t;
decal_atlas.dirty = true;
} else {
DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
t->users++;
if (p_panorama_to_dp) {
t->panorama_to_dp_users++;
}
}
}
void RendererStorageRD::texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp) {
DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
ERR_FAIL_COND(!t);
t->users--;
if (p_panorama_to_dp) {
ERR_FAIL_COND(t->panorama_to_dp_users == 0);
t->panorama_to_dp_users--;
}
if (t->users == 0) {
decal_atlas.textures.erase(p_texture);
//do not mark it dirty, there is no need to since it remains working
}
}
RID RendererStorageRD::decal_atlas_get_texture() const {
return decal_atlas.texture;
}
RID RendererStorageRD::decal_atlas_get_texture_srgb() const {
return decal_atlas.texture_srgb;
}
void RendererStorageRD::_update_decal_atlas() {
if (!decal_atlas.dirty) {
return; //nothing to do
}
decal_atlas.dirty = false;
if (decal_atlas.texture.is_valid()) {
RD::get_singleton()->free(decal_atlas.texture);
decal_atlas.texture = RID();
decal_atlas.texture_srgb = RID();
decal_atlas.texture_mipmaps.clear();
}
int border = 1 << decal_atlas.mipmaps;
if (decal_atlas.textures.size()) {
//generate atlas
Vector<DecalAtlas::SortItem> itemsv;
itemsv.resize(decal_atlas.textures.size());
int base_size = 8;
const RID *K = nullptr;
int idx = 0;
while ((K = decal_atlas.textures.next(K))) {
DecalAtlas::SortItem &si = itemsv.write[idx];
RendererRD::Texture *src_tex = RendererRD::TextureStorage::get_singleton()->get_texture(*K);
si.size.width = (src_tex->width / border) + 1;
si.size.height = (src_tex->height / border) + 1;
si.pixel_size = Size2i(src_tex->width, src_tex->height);
if (base_size < si.size.width) {
base_size = nearest_power_of_2_templated(si.size.width);
}
si.texture = *K;
idx++;
}
//sort items by size
itemsv.sort();
//attempt to create atlas
int item_count = itemsv.size();
DecalAtlas::SortItem *items = itemsv.ptrw();
int atlas_height = 0;
while (true) {
Vector<int> v_offsetsv;
v_offsetsv.resize(base_size);
int *v_offsets = v_offsetsv.ptrw();
memset(v_offsets, 0, sizeof(int) * base_size);
int max_height = 0;
for (int i = 0; i < item_count; i++) {
//best fit
DecalAtlas::SortItem &si = items[i];
int best_idx = -1;
int best_height = 0x7FFFFFFF;
for (int j = 0; j <= base_size - si.size.width; j++) {
int height = 0;
for (int k = 0; k < si.size.width; k++) {
int h = v_offsets[k + j];
if (h > height) {
height = h;
if (height > best_height) {
break; //already bad
}
}
}
if (height < best_height) {
best_height = height;
best_idx = j;
}
}
//update
for (int k = 0; k < si.size.width; k++) {
v_offsets[k + best_idx] = best_height + si.size.height;
}
si.pos.x = best_idx;
si.pos.y = best_height;
if (si.pos.y + si.size.height > max_height) {
max_height = si.pos.y + si.size.height;
}
}
if (max_height <= base_size * 2) {
atlas_height = max_height;
break; //good ratio, break;
}
base_size *= 2;
}
decal_atlas.size.width = base_size * border;
decal_atlas.size.height = nearest_power_of_2_templated(atlas_height * border);
for (int i = 0; i < item_count; i++) {
DecalAtlas::Texture *t = decal_atlas.textures.getptr(items[i].texture);
t->uv_rect.position = items[i].pos * border + Vector2i(border / 2, border / 2);
t->uv_rect.size = items[i].pixel_size;
t->uv_rect.position /= Size2(decal_atlas.size);
t->uv_rect.size /= Size2(decal_atlas.size);
}
} else {
//use border as size, so it at least has enough mipmaps
decal_atlas.size.width = border;
decal_atlas.size.height = border;
}
//blit textures
RD::TextureFormat tformat;
tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
tformat.width = decal_atlas.size.width;
tformat.height = decal_atlas.size.height;
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
tformat.texture_type = RD::TEXTURE_TYPE_2D;
tformat.mipmaps = decal_atlas.mipmaps;
tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_UNORM);
tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_SRGB);
decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView());
RD::get_singleton()->texture_clear(decal_atlas.texture, Color(0, 0, 0, 0), 0, decal_atlas.mipmaps, 0, 1);
{
//create the framebuffer
Size2i s = decal_atlas.size;
for (int i = 0; i < decal_atlas.mipmaps; i++) {
DecalAtlas::MipMap mm;
mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), decal_atlas.texture, 0, i);
Vector<RID> fb;
fb.push_back(mm.texture);
mm.fb = RD::get_singleton()->framebuffer_create(fb);
mm.size = s;
decal_atlas.texture_mipmaps.push_back(mm);
s.width = MAX(1, s.width >> 1);
s.height = MAX(1, s.height >> 1);
}
{
//create the SRGB variant
RD::TextureView rd_view;
rd_view.format_override = RD::DATA_FORMAT_R8G8B8A8_SRGB;
decal_atlas.texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, decal_atlas.texture);
}
}
RID prev_texture;
for (int i = 0; i < decal_atlas.texture_mipmaps.size(); i++) {
const DecalAtlas::MipMap &mm = decal_atlas.texture_mipmaps[i];
Color clear_color(0, 0, 0, 0);
if (decal_atlas.textures.size()) {
if (i == 0) {
Vector<Color> cc;
cc.push_back(clear_color);
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(mm.fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, cc);
const RID *K = nullptr;
while ((K = decal_atlas.textures.next(K))) {
DecalAtlas::Texture *t = decal_atlas.textures.getptr(*K);
RendererRD::Texture *src_tex = RendererRD::TextureStorage::get_singleton()->get_texture(*K);
effects->copy_to_atlas_fb(src_tex->rd_texture, mm.fb, t->uv_rect, draw_list, false, t->panorama_to_dp_users > 0);
}
RD::get_singleton()->draw_list_end();
prev_texture = mm.texture;
} else {
effects->copy_to_fb_rect(prev_texture, mm.fb, Rect2i(Point2i(), mm.size));
prev_texture = mm.texture;
}
} else {
RD::get_singleton()->texture_clear(mm.texture, clear_color, 0, 1, 0, 1);
}
}
}
int32_t RendererStorageRD::_global_variable_allocate(uint32_t p_elements) {
int32_t idx = 0;
while (idx + p_elements <= global_variables.buffer_size) {
@ -8017,7 +7682,7 @@ void RendererStorageRD::update_dirty_resources() {
_update_queued_materials();
_update_dirty_multimeshes();
_update_dirty_skeletons();
_update_decal_atlas();
RendererRD::DecalAtlasStorage::get_singleton()->update_decal_atlas();
}
bool RendererStorageRD::has_os_feature(const String &p_feature) const {
@ -8103,15 +7768,8 @@ bool RendererStorageRD::free(RID p_rid) {
ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(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.get_or_null(p_rid);
for (int i = 0; i < RS::DECAL_TEXTURE_MAX; i++) {
if (decal->textures[i].is_valid() && RendererRD::TextureStorage::get_singleton()->owns_texture(decal->textures[i])) {
texture_remove_from_decal_atlas(decal->textures[i]);
}
}
decal->dependency.deleted_notify(p_rid);
decal_owner.free(p_rid);
} else if (RendererRD::DecalAtlasStorage::get_singleton()->owns_decal(p_rid)) {
RendererRD::DecalAtlasStorage::get_singleton()->decal_free(p_rid);
} else if (voxel_gi_owner.owns(p_rid)) {
voxel_gi_allocate_data(p_rid, Transform3D(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate
VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_rid);
@ -8259,33 +7917,6 @@ RendererStorageRD::RendererStorageRD() {
memset(global_variables.buffer_dirty_regions, 0, sizeof(bool) * global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE);
global_variables.buffer = RD::get_singleton()->storage_buffer_create(sizeof(GlobalVariables::Value) * global_variables.buffer_size);
{ // default atlas texture
RD::TextureFormat tformat;
tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
tformat.width = 4;
tformat.height = 4;
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
tformat.texture_type = RD::TEXTURE_TYPE_2D;
Vector<uint8_t> pv;
pv.resize(16 * 4);
for (int i = 0; i < 16; i++) {
pv.set(i * 4 + 0, 0);
pv.set(i * 4 + 1, 0);
pv.set(i * 4 + 2, 0);
pv.set(i * 4 + 3, 255);
}
{
//take the chance and initialize decal atlas to something
Vector<Vector<uint8_t>> vpv;
vpv.push_back(pv);
decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
decal_atlas.texture_srgb = decal_atlas.texture;
}
}
//default samplers
for (int i = 1; i < RS::CANVAS_ITEM_TEXTURE_FILTER_MAX; i++) {
for (int j = 1; j < RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX; j++) {
@ -8737,14 +8368,6 @@ RendererStorageRD::~RendererStorageRD() {
RD::get_singleton()->free(default_rd_storage_buffer);
if (decal_atlas.textures.size()) {
ERR_PRINT("Decal Atlas: " + itos(decal_atlas.textures.size()) + " textures were not removed from the atlas.");
}
if (decal_atlas.texture.is_valid()) {
RD::get_singleton()->free(decal_atlas.texture);
}
if (effects) {
memdelete(effects);
effects = nullptr;

View file

@ -205,50 +205,6 @@ private:
RID custom_rd_samplers[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX];
RID default_rd_storage_buffer;
/* DECAL ATLAS */
struct DecalAtlas {
struct Texture {
int panorama_to_dp_users;
int users;
Rect2 uv_rect;
};
struct SortItem {
RID texture;
Size2i pixel_size;
Size2i size;
Point2i pos;
bool operator<(const SortItem &p_item) const {
//sort larger to smaller
if (size.height == p_item.size.height) {
return size.width > p_item.size.width;
} else {
return size.height > p_item.size.height;
}
}
};
HashMap<RID, Texture> textures;
bool dirty = true;
int mipmaps = 5;
RID texture;
RID texture_srgb;
struct MipMap {
RID fb;
RID texture;
Size2i size;
};
Vector<MipMap> texture_mipmaps;
Size2i size;
} decal_atlas;
void _update_decal_atlas();
/* SHADER */
struct Material;
@ -952,27 +908,6 @@ private:
mutable RID_Owner<ReflectionProbe, true> reflection_probe_owner;
/* DECAL */
struct Decal {
Vector3 extents = Vector3(1, 1, 1);
RID textures[RS::DECAL_TEXTURE_MAX];
float emission_energy = 1.0;
float albedo_mix = 1.0;
Color modulate = Color(1, 1, 1, 1);
uint32_t cull_mask = (1 << 20) - 1;
float upper_fade = 0.3;
float lower_fade = 0.3;
bool distance_fade = false;
float distance_fade_begin = 10;
float distance_fade_length = 1;
float normal_fade = 0.0;
Dependency dependency;
};
mutable RID_Owner<Decal, true> decal_owner;
/* VOXEL GI */
struct VoxelGI {
@ -1190,17 +1125,6 @@ private:
EffectsRD *effects = nullptr;
public:
RID decal_atlas_get_texture() const;
RID decal_atlas_get_texture_srgb() const;
_FORCE_INLINE_ Rect2 decal_atlas_get_texture_rect(RID p_texture) {
DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
if (!t) {
return Rect2();
}
return t->uv_rect;
}
//internal usage
_FORCE_INLINE_ RID sampler_rd_get_default(RS::CanvasItemTextureFilter p_filter, RS::CanvasItemTextureRepeat p_repeat) {
@ -1791,89 +1715,6 @@ public:
void base_update_dependency(RID p_base, DependencyTracker *p_instance);
void skeleton_update_dependency(RID p_skeleton, DependencyTracker *p_instance);
/* DECAL API */
RID decal_allocate();
void decal_initialize(RID p_decal);
virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents);
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture);
virtual void decal_set_emission_energy(RID p_decal, float p_energy);
virtual void decal_set_albedo_mix(RID p_decal, float p_mix);
virtual void decal_set_modulate(RID p_decal, const Color &p_modulate);
virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers);
virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length);
virtual void decal_set_fade(RID p_decal, float p_above, float p_below);
virtual void decal_set_normal_fade(RID p_decal, float p_fade);
void decal_atlas_mark_dirty_on_texture(RID p_texture);
void decal_atlas_remove_texture(RID p_texture);
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false);
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false);
_FORCE_INLINE_ Vector3 decal_get_extents(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->extents;
}
_FORCE_INLINE_ RID decal_get_texture(RID p_decal, RS::DecalTexture p_texture) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->textures[p_texture];
}
_FORCE_INLINE_ Color decal_get_modulate(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->modulate;
}
_FORCE_INLINE_ float decal_get_emission_energy(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->emission_energy;
}
_FORCE_INLINE_ float decal_get_albedo_mix(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->albedo_mix;
}
_FORCE_INLINE_ uint32_t decal_get_cull_mask(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->cull_mask;
}
_FORCE_INLINE_ float decal_get_upper_fade(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->upper_fade;
}
_FORCE_INLINE_ float decal_get_lower_fade(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->lower_fade;
}
_FORCE_INLINE_ float decal_get_normal_fade(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->normal_fade;
}
_FORCE_INLINE_ bool decal_is_distance_fade_enabled(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->distance_fade;
}
_FORCE_INLINE_ float decal_get_distance_fade_begin(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->distance_fade_begin;
}
_FORCE_INLINE_ float decal_get_distance_fade_length(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->distance_fade_length;
}
virtual AABB decal_get_aabb(RID p_decal) const;
/* VOXEL GI API */
RID voxel_gi_allocate();

View file

@ -0,0 +1,437 @@
/*************************************************************************/
/* decal_atlas_storage.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 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 "decal_atlas_storage.h"
#include "texture_storage.h"
// Should be able to remove this once we move effects into their own file and include the correct effects
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
using namespace RendererRD;
DecalAtlasStorage *DecalAtlasStorage::singleton = nullptr;
DecalAtlasStorage *DecalAtlasStorage::get_singleton() {
return singleton;
}
DecalAtlasStorage::DecalAtlasStorage() {
singleton = this;
{ // default atlas texture
RD::TextureFormat tformat;
tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
tformat.width = 4;
tformat.height = 4;
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
tformat.texture_type = RD::TEXTURE_TYPE_2D;
Vector<uint8_t> pv;
pv.resize(16 * 4);
for (int i = 0; i < 16; i++) {
pv.set(i * 4 + 0, 0);
pv.set(i * 4 + 1, 0);
pv.set(i * 4 + 2, 0);
pv.set(i * 4 + 3, 255);
}
{
//take the chance and initialize decal atlas to something
Vector<Vector<uint8_t>> vpv;
vpv.push_back(pv);
decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
decal_atlas.texture_srgb = decal_atlas.texture;
}
}
}
DecalAtlasStorage::~DecalAtlasStorage() {
if (decal_atlas.textures.size()) {
ERR_PRINT("Decal Atlas: " + itos(decal_atlas.textures.size()) + " textures were not removed from the atlas.");
}
if (decal_atlas.texture.is_valid()) {
RD::get_singleton()->free(decal_atlas.texture);
}
singleton = nullptr;
}
RID DecalAtlasStorage::decal_atlas_get_texture() const {
return decal_atlas.texture;
}
RID DecalAtlasStorage::decal_atlas_get_texture_srgb() const {
return decal_atlas.texture_srgb;
}
RID DecalAtlasStorage::decal_allocate() {
return decal_owner.allocate_rid();
}
void DecalAtlasStorage::decal_initialize(RID p_decal) {
decal_owner.initialize_rid(p_decal, Decal());
}
void DecalAtlasStorage::decal_free(RID p_rid) {
Decal *decal = decal_owner.get_or_null(p_rid);
for (int i = 0; i < RS::DECAL_TEXTURE_MAX; i++) {
if (decal->textures[i].is_valid() && TextureStorage::get_singleton()->owns_texture(decal->textures[i])) {
texture_remove_from_decal_atlas(decal->textures[i]);
}
}
decal->dependency.deleted_notify(p_rid);
decal_owner.free(p_rid);
}
void DecalAtlasStorage::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
decal->extents = p_extents;
decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
}
void DecalAtlasStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
ERR_FAIL_INDEX(p_type, RS::DECAL_TEXTURE_MAX);
if (decal->textures[p_type] == p_texture) {
return;
}
ERR_FAIL_COND(p_texture.is_valid() && !TextureStorage::get_singleton()->owns_texture(p_texture));
if (decal->textures[p_type].is_valid() && TextureStorage::get_singleton()->owns_texture(decal->textures[p_type])) {
texture_remove_from_decal_atlas(decal->textures[p_type]);
}
decal->textures[p_type] = p_texture;
if (decal->textures[p_type].is_valid()) {
texture_add_to_decal_atlas(decal->textures[p_type]);
}
decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_DECAL);
}
void DecalAtlasStorage::decal_set_emission_energy(RID p_decal, float p_energy) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
decal->emission_energy = p_energy;
}
void DecalAtlasStorage::decal_set_albedo_mix(RID p_decal, float p_mix) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
decal->albedo_mix = p_mix;
}
void DecalAtlasStorage::decal_set_modulate(RID p_decal, const Color &p_modulate) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
decal->modulate = p_modulate;
}
void DecalAtlasStorage::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(RendererStorage::DEPENDENCY_CHANGED_AABB);
}
void DecalAtlasStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
decal->distance_fade = p_enabled;
decal->distance_fade_begin = p_begin;
decal->distance_fade_length = p_length;
}
void DecalAtlasStorage::decal_set_fade(RID p_decal, float p_above, float p_below) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
decal->upper_fade = p_above;
decal->lower_fade = p_below;
}
void DecalAtlasStorage::decal_set_normal_fade(RID p_decal, float p_fade) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
decal->normal_fade = p_fade;
}
void DecalAtlasStorage::decal_atlas_mark_dirty_on_texture(RID p_texture) {
if (decal_atlas.textures.has(p_texture)) {
//belongs to decal atlas..
decal_atlas.dirty = true; //mark it dirty since it was most likely modified
}
}
void DecalAtlasStorage::decal_atlas_remove_texture(RID p_texture) {
if (decal_atlas.textures.has(p_texture)) {
decal_atlas.textures.erase(p_texture);
//there is not much a point of making it dirty, just let it be.
}
}
AABB DecalAtlasStorage::decal_get_aabb(RID p_decal) const {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND_V(!decal, AABB());
return AABB(-decal->extents, decal->extents * 2.0);
}
void DecalAtlasStorage::update_decal_atlas() {
EffectsRD *effects = RendererStorageRD::base_singleton->get_effects();
if (!decal_atlas.dirty) {
return; //nothing to do
}
decal_atlas.dirty = false;
if (decal_atlas.texture.is_valid()) {
RD::get_singleton()->free(decal_atlas.texture);
decal_atlas.texture = RID();
decal_atlas.texture_srgb = RID();
decal_atlas.texture_mipmaps.clear();
}
int border = 1 << decal_atlas.mipmaps;
if (decal_atlas.textures.size()) {
//generate atlas
Vector<DecalAtlas::SortItem> itemsv;
itemsv.resize(decal_atlas.textures.size());
int base_size = 8;
const RID *K = nullptr;
int idx = 0;
while ((K = decal_atlas.textures.next(K))) {
DecalAtlas::SortItem &si = itemsv.write[idx];
Texture *src_tex = TextureStorage::get_singleton()->get_texture(*K);
si.size.width = (src_tex->width / border) + 1;
si.size.height = (src_tex->height / border) + 1;
si.pixel_size = Size2i(src_tex->width, src_tex->height);
if (base_size < si.size.width) {
base_size = nearest_power_of_2_templated(si.size.width);
}
si.texture = *K;
idx++;
}
//sort items by size
itemsv.sort();
//attempt to create atlas
int item_count = itemsv.size();
DecalAtlas::SortItem *items = itemsv.ptrw();
int atlas_height = 0;
while (true) {
Vector<int> v_offsetsv;
v_offsetsv.resize(base_size);
int *v_offsets = v_offsetsv.ptrw();
memset(v_offsets, 0, sizeof(int) * base_size);
int max_height = 0;
for (int i = 0; i < item_count; i++) {
//best fit
DecalAtlas::SortItem &si = items[i];
int best_idx = -1;
int best_height = 0x7FFFFFFF;
for (int j = 0; j <= base_size - si.size.width; j++) {
int height = 0;
for (int k = 0; k < si.size.width; k++) {
int h = v_offsets[k + j];
if (h > height) {
height = h;
if (height > best_height) {
break; //already bad
}
}
}
if (height < best_height) {
best_height = height;
best_idx = j;
}
}
//update
for (int k = 0; k < si.size.width; k++) {
v_offsets[k + best_idx] = best_height + si.size.height;
}
si.pos.x = best_idx;
si.pos.y = best_height;
if (si.pos.y + si.size.height > max_height) {
max_height = si.pos.y + si.size.height;
}
}
if (max_height <= base_size * 2) {
atlas_height = max_height;
break; //good ratio, break;
}
base_size *= 2;
}
decal_atlas.size.width = base_size * border;
decal_atlas.size.height = nearest_power_of_2_templated(atlas_height * border);
for (int i = 0; i < item_count; i++) {
DecalAtlas::Texture *t = decal_atlas.textures.getptr(items[i].texture);
t->uv_rect.position = items[i].pos * border + Vector2i(border / 2, border / 2);
t->uv_rect.size = items[i].pixel_size;
t->uv_rect.position /= Size2(decal_atlas.size);
t->uv_rect.size /= Size2(decal_atlas.size);
}
} else {
//use border as size, so it at least has enough mipmaps
decal_atlas.size.width = border;
decal_atlas.size.height = border;
}
//blit textures
RD::TextureFormat tformat;
tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
tformat.width = decal_atlas.size.width;
tformat.height = decal_atlas.size.height;
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
tformat.texture_type = RD::TEXTURE_TYPE_2D;
tformat.mipmaps = decal_atlas.mipmaps;
tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_UNORM);
tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_SRGB);
decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView());
RD::get_singleton()->texture_clear(decal_atlas.texture, Color(0, 0, 0, 0), 0, decal_atlas.mipmaps, 0, 1);
{
//create the framebuffer
Size2i s = decal_atlas.size;
for (int i = 0; i < decal_atlas.mipmaps; i++) {
DecalAtlas::MipMap mm;
mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), decal_atlas.texture, 0, i);
Vector<RID> fb;
fb.push_back(mm.texture);
mm.fb = RD::get_singleton()->framebuffer_create(fb);
mm.size = s;
decal_atlas.texture_mipmaps.push_back(mm);
s.width = MAX(1, s.width >> 1);
s.height = MAX(1, s.height >> 1);
}
{
//create the SRGB variant
RD::TextureView rd_view;
rd_view.format_override = RD::DATA_FORMAT_R8G8B8A8_SRGB;
decal_atlas.texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, decal_atlas.texture);
}
}
RID prev_texture;
for (int i = 0; i < decal_atlas.texture_mipmaps.size(); i++) {
const DecalAtlas::MipMap &mm = decal_atlas.texture_mipmaps[i];
Color clear_color(0, 0, 0, 0);
if (decal_atlas.textures.size()) {
if (i == 0) {
Vector<Color> cc;
cc.push_back(clear_color);
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(mm.fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, cc);
const RID *K = nullptr;
while ((K = decal_atlas.textures.next(K))) {
DecalAtlas::Texture *t = decal_atlas.textures.getptr(*K);
Texture *src_tex = TextureStorage::get_singleton()->get_texture(*K);
effects->copy_to_atlas_fb(src_tex->rd_texture, mm.fb, t->uv_rect, draw_list, false, t->panorama_to_dp_users > 0);
}
RD::get_singleton()->draw_list_end();
prev_texture = mm.texture;
} else {
effects->copy_to_fb_rect(prev_texture, mm.fb, Rect2i(Point2i(), mm.size));
prev_texture = mm.texture;
}
} else {
RD::get_singleton()->texture_clear(mm.texture, clear_color, 0, 1, 0, 1);
}
}
}
void DecalAtlasStorage::texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp) {
if (!decal_atlas.textures.has(p_texture)) {
DecalAtlas::Texture t;
t.users = 1;
t.panorama_to_dp_users = p_panorama_to_dp ? 1 : 0;
decal_atlas.textures[p_texture] = t;
decal_atlas.dirty = true;
} else {
DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
t->users++;
if (p_panorama_to_dp) {
t->panorama_to_dp_users++;
}
}
}
void DecalAtlasStorage::texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp) {
DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
ERR_FAIL_COND(!t);
t->users--;
if (p_panorama_to_dp) {
ERR_FAIL_COND(t->panorama_to_dp_users == 0);
t->panorama_to_dp_users--;
}
if (t->users == 0) {
decal_atlas.textures.erase(p_texture);
//do not mark it dirty, there is no need to since it remains working
}
}

View file

@ -0,0 +1,211 @@
/*************************************************************************/
/* decal_atlas_storage.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 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 DECAL_ATLAS_STORAGE_RD_H
#define DECAL_ATLAS_STORAGE_RD_H
#include "core/templates/rid_owner.h"
#include "servers/rendering/renderer_storage.h"
#include "servers/rendering/storage/decal_atlas_storage.h"
namespace RendererRD {
struct DecalAtlas {
struct Texture {
int panorama_to_dp_users;
int users;
Rect2 uv_rect;
};
struct SortItem {
RID texture;
Size2i pixel_size;
Size2i size;
Point2i pos;
bool operator<(const SortItem &p_item) const {
//sort larger to smaller
if (size.height == p_item.size.height) {
return size.width > p_item.size.width;
} else {
return size.height > p_item.size.height;
}
}
};
HashMap<RID, Texture> textures;
bool dirty = true;
int mipmaps = 5;
RID texture;
RID texture_srgb;
struct MipMap {
RID fb;
RID texture;
Size2i size;
};
Vector<MipMap> texture_mipmaps;
Size2i size;
};
struct Decal {
Vector3 extents = Vector3(1, 1, 1);
RID textures[RS::DECAL_TEXTURE_MAX];
float emission_energy = 1.0;
float albedo_mix = 1.0;
Color modulate = Color(1, 1, 1, 1);
uint32_t cull_mask = (1 << 20) - 1;
float upper_fade = 0.3;
float lower_fade = 0.3;
bool distance_fade = false;
float distance_fade_begin = 10;
float distance_fade_length = 1;
float normal_fade = 0.0;
RendererStorage::Dependency dependency;
};
class DecalAtlasStorage : public RendererDecalAtlasStorage {
private:
static DecalAtlasStorage *singleton;
DecalAtlas decal_atlas;
mutable RID_Owner<Decal, true> decal_owner;
public:
static DecalAtlasStorage *get_singleton();
void update_decal_atlas();
DecalAtlasStorage();
virtual ~DecalAtlasStorage();
Decal *get_decal(RID p_rid) { return decal_owner.get_or_null(p_rid); };
bool owns_decal(RID p_rid) { return decal_owner.owns(p_rid); };
RID decal_atlas_get_texture() const;
RID decal_atlas_get_texture_srgb() const;
_FORCE_INLINE_ Rect2 decal_atlas_get_texture_rect(RID p_texture) {
DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
if (!t) {
return Rect2();
}
return t->uv_rect;
}
virtual RID decal_allocate() override;
virtual void decal_initialize(RID p_decal) override;
virtual void decal_free(RID p_rid) override;
virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override;
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override;
virtual void decal_set_emission_energy(RID p_decal, float p_energy) override;
virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override;
virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) override;
virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override;
virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override;
virtual void decal_set_fade(RID p_decal, float p_above, float p_below) override;
virtual void decal_set_normal_fade(RID p_decal, float p_fade) override;
void decal_atlas_mark_dirty_on_texture(RID p_texture);
void decal_atlas_remove_texture(RID p_texture);
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;
_FORCE_INLINE_ Vector3 decal_get_extents(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->extents;
}
_FORCE_INLINE_ RID decal_get_texture(RID p_decal, RS::DecalTexture p_texture) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->textures[p_texture];
}
_FORCE_INLINE_ Color decal_get_modulate(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->modulate;
}
_FORCE_INLINE_ float decal_get_emission_energy(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->emission_energy;
}
_FORCE_INLINE_ float decal_get_albedo_mix(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->albedo_mix;
}
_FORCE_INLINE_ uint32_t decal_get_cull_mask(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->cull_mask;
}
_FORCE_INLINE_ float decal_get_upper_fade(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->upper_fade;
}
_FORCE_INLINE_ float decal_get_lower_fade(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->lower_fade;
}
_FORCE_INLINE_ float decal_get_normal_fade(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->normal_fade;
}
_FORCE_INLINE_ bool decal_is_distance_fade_enabled(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->distance_fade;
}
_FORCE_INLINE_ float decal_get_distance_fade_begin(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->distance_fade_begin;
}
_FORCE_INLINE_ float decal_get_distance_fade_length(RID p_decal) {
const Decal *decal = decal_owner.get_or_null(p_decal);
return decal->distance_fade_length;
}
virtual AABB decal_get_aabb(RID p_decal) const override;
};
} // namespace RendererRD
#endif // !DECAL_ATLAS_STORAGE_RD_H

View file

@ -29,9 +29,7 @@
/*************************************************************************/
#include "texture_storage.h"
// only include until we have DecalStorage sorted
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "decal_atlas_storage.h"
using namespace RendererRD;
@ -332,7 +330,7 @@ void TextureStorage::texture_free(RID p_texture) {
}
}
RendererStorageRD::base_singleton->decal_atlas_remove_texture(p_texture);
DecalAtlasStorage::get_singleton()->decal_atlas_remove_texture(p_texture);
for (int i = 0; i < t->proxies.size(); i++) {
Texture *p = texture_owner.get_or_null(t->proxies[i]);
@ -931,7 +929,7 @@ void TextureStorage::texture_replace(RID p_texture, RID p_by_texture) {
//delete last, so proxies can be updated
texture_owner.free(p_by_texture);
RendererStorageRD::base_singleton->decal_atlas_mark_dirty_on_texture(p_texture);
DecalAtlasStorage::get_singleton()->decal_atlas_mark_dirty_on_texture(p_texture);
}
void TextureStorage::texture_set_size_override(RID p_texture, int p_width, int p_height) {

View file

@ -1887,7 +1887,7 @@ void RendererSceneCull::_update_instance_aabb(Instance *p_instance) {
} break;
case RenderingServer::INSTANCE_DECAL: {
new_aabb = RSG::storage->decal_get_aabb(p_instance->base);
new_aabb = RSG::decal_atlas_storage->decal_get_aabb(p_instance->base);
} break;
case RenderingServer::INSTANCE_VOXEL_GI: {

View file

@ -54,7 +54,6 @@ public:
struct DependencyTracker;
protected:
struct Dependency {
void changed_notify(DependencyChangedNotification p_notification);
void deleted_notify(const RID &p_rid);
@ -327,26 +326,6 @@ public:
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 */
virtual RID decal_allocate() = 0;
virtual void decal_initialize(RID p_rid) = 0;
virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) = 0;
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) = 0;
virtual void decal_set_emission_energy(RID p_decal, float p_energy) = 0;
virtual void decal_set_albedo_mix(RID p_decal, float p_mix) = 0;
virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) = 0;
virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) = 0;
virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) = 0;
virtual void decal_set_fade(RID p_decal, float p_above, float p_below) = 0;
virtual void decal_set_normal_fade(RID p_decal, float p_fade) = 0;
virtual AABB decal_get_aabb(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;
/* VOXEL GI API */
virtual RID voxel_gi_allocate() = 0;

View file

@ -399,6 +399,7 @@ RenderingServerDefault::RenderingServerDefault(bool p_create_thread) :
RSG::scene = sr;
RSG::rasterizer = RendererCompositor::create();
RSG::canvas_texture_storage = RSG::rasterizer->get_canvas_texture_storage();
RSG::decal_atlas_storage = RSG::rasterizer->get_decal_atlas_storage();
RSG::texture_storage = RSG::rasterizer->get_texture_storage();
RSG::storage = RSG::rasterizer->get_storage();
RSG::canvas_render = RSG::rasterizer->get_canvas();

View file

@ -385,6 +385,12 @@ public:
/* DECAL API */
#undef ServerName
#undef server_name
#define ServerName RendererDecalAtlasStorage
#define server_name RSG::decal_atlas_storage
FUNCRIDSPLIT(decal)
FUNC2(decal_set_extents, RID, const Vector3 &)
@ -399,6 +405,13 @@ public:
/* BAKED LIGHT API */
//from now on, calls forwarded to this singleton
#undef ServerName
#undef server_name
#define ServerName RendererStorage
#define server_name RSG::storage
FUNCRIDSPLIT(voxel_gi)
FUNC8(voxel_gi_allocate_data, RID, const Transform3D &, const AABB &, const Vector3i &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<int> &)

View file

@ -33,6 +33,7 @@
bool RenderingServerGlobals::threaded = false;
RendererCanvasTextureStorage *RenderingServerGlobals::canvas_texture_storage = nullptr;
RendererDecalAtlasStorage *RenderingServerGlobals::decal_atlas_storage = nullptr;
RendererTextureStorage *RenderingServerGlobals::texture_storage = nullptr;
RendererStorage *RenderingServerGlobals::storage = nullptr;
RendererCanvasRender *RenderingServerGlobals::canvas_render = nullptr;

View file

@ -35,6 +35,7 @@
#include "servers/rendering/renderer_canvas_render.h"
#include "servers/rendering/renderer_scene.h"
#include "servers/rendering/storage/canvas_texture_storage.h"
#include "servers/rendering/storage/decal_atlas_storage.h"
#include "servers/rendering/storage/texture_storage.h"
class RendererCanvasCull;
@ -47,6 +48,7 @@ public:
static RendererCanvasTextureStorage *canvas_texture_storage;
static RendererTextureStorage *texture_storage;
static RendererDecalAtlasStorage *decal_atlas_storage;
static RendererStorage *storage;
static RendererCanvasRender *canvas_render;
static RendererCompositor *rasterizer;

View file

@ -0,0 +1,60 @@
/*************************************************************************/
/* decal_atlas_storage.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 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 DECAL_ATLAS_STORAGE_H
#define DECAL_ATLAS_STORAGE_H
#include "servers/rendering_server.h"
class RendererDecalAtlasStorage {
public:
virtual ~RendererDecalAtlasStorage(){};
virtual RID decal_allocate() = 0;
virtual void decal_initialize(RID p_rid) = 0;
virtual void decal_free(RID p_rid) = 0;
virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) = 0;
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) = 0;
virtual void decal_set_emission_energy(RID p_decal, float p_energy) = 0;
virtual void decal_set_albedo_mix(RID p_decal, float p_mix) = 0;
virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) = 0;
virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) = 0;
virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) = 0;
virtual void decal_set_fade(RID p_decal, float p_above, float p_below) = 0;
virtual void decal_set_normal_fade(RID p_decal, float p_fade) = 0;
virtual AABB decal_get_aabb(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;
};
#endif // !DECAL_ATLAS_STORAGE_H