Path: blob/master/drivers/gles3/storage/light_storage.cpp
21038 views
/**************************************************************************/1/* light_storage.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#ifdef GLES3_ENABLED3132#include "light_storage.h"33#include "../rasterizer_gles3.h"34#include "../rasterizer_scene_gles3.h"35#include "core/config/project_settings.h"36#include "core/math/geometry_3d.h"37#include "texture_storage.h"3839using namespace GLES3;4041LightStorage *LightStorage::singleton = nullptr;4243LightStorage *LightStorage::get_singleton() {44return singleton;45}4647LightStorage::LightStorage() {48singleton = this;4950directional_shadow.size = GLOBAL_GET("rendering/lights_and_shadows/directional_shadow/size");51directional_shadow.use_16_bits = GLOBAL_GET("rendering/lights_and_shadows/directional_shadow/16_bits");5253// lightmap_probe_capture_update_speed = GLOBAL_GET("rendering/lightmapping/probe_capture/update_speed");54}5556LightStorage::~LightStorage() {57singleton = nullptr;58}5960/* Light API */6162void LightStorage::_light_initialize(RID p_light, RS::LightType p_type) {63Light light;64light.type = p_type;6566light.param[RS::LIGHT_PARAM_ENERGY] = 1.0;67light.param[RS::LIGHT_PARAM_INDIRECT_ENERGY] = 1.0;68light.param[RS::LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY] = 1.0;69light.param[RS::LIGHT_PARAM_SPECULAR] = 0.5;70light.param[RS::LIGHT_PARAM_RANGE] = 1.0;71light.param[RS::LIGHT_PARAM_SIZE] = 0.0;72light.param[RS::LIGHT_PARAM_ATTENUATION] = 1.0;73light.param[RS::LIGHT_PARAM_SPOT_ANGLE] = 45;74light.param[RS::LIGHT_PARAM_SPOT_ATTENUATION] = 1.0;75light.param[RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE] = 0;76light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET] = 0.1;77light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET] = 0.3;78light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET] = 0.6;79light.param[RS::LIGHT_PARAM_SHADOW_FADE_START] = 0.8;80light.param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 1.0;81light.param[RS::LIGHT_PARAM_SHADOW_OPACITY] = 1.0;82light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02;83light.param[RS::LIGHT_PARAM_SHADOW_BLUR] = 0;84light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0;85light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05;86light.param[RS::LIGHT_PARAM_INTENSITY] = p_type == RS::LIGHT_DIRECTIONAL ? 100000.0 : 1000.0;8788light_owner.initialize_rid(p_light, light);89}9091RID LightStorage::directional_light_allocate() {92return light_owner.allocate_rid();93}9495void LightStorage::directional_light_initialize(RID p_rid) {96_light_initialize(p_rid, RS::LIGHT_DIRECTIONAL);97}9899RID LightStorage::omni_light_allocate() {100return light_owner.allocate_rid();101}102103void LightStorage::omni_light_initialize(RID p_rid) {104_light_initialize(p_rid, RS::LIGHT_OMNI);105}106107RID LightStorage::spot_light_allocate() {108return light_owner.allocate_rid();109}110111void LightStorage::spot_light_initialize(RID p_rid) {112_light_initialize(p_rid, RS::LIGHT_SPOT);113}114115void LightStorage::light_free(RID p_rid) {116light_set_projector(p_rid, RID()); //clear projector117118// delete the texture119Light *light = light_owner.get_or_null(p_rid);120light->dependency.deleted_notify(p_rid);121light_owner.free(p_rid);122}123124void LightStorage::light_set_color(RID p_light, const Color &p_color) {125Light *light = light_owner.get_or_null(p_light);126ERR_FAIL_NULL(light);127128light->color = p_color;129}130131void LightStorage::light_set_param(RID p_light, RS::LightParam p_param, float p_value) {132Light *light = light_owner.get_or_null(p_light);133ERR_FAIL_NULL(light);134ERR_FAIL_INDEX(p_param, RS::LIGHT_PARAM_MAX);135136if (light->param[p_param] == p_value) {137return;138}139140switch (p_param) {141case RS::LIGHT_PARAM_RANGE:142case RS::LIGHT_PARAM_SPOT_ANGLE:143case RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE:144case RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET:145case RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET:146case RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET:147case RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS:148case RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE:149case RS::LIGHT_PARAM_SHADOW_BIAS: {150light->version++;151light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);152} break;153case RS::LIGHT_PARAM_SIZE: {154if ((light->param[p_param] > CMP_EPSILON) != (p_value > CMP_EPSILON)) {155//changing from no size to size and the opposite156light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);157}158} break;159default: {160}161}162163light->param[p_param] = p_value;164}165166void LightStorage::light_set_shadow(RID p_light, bool p_enabled) {167Light *light = light_owner.get_or_null(p_light);168ERR_FAIL_NULL(light);169light->shadow = p_enabled;170171light->version++;172light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);173}174175void LightStorage::light_set_projector(RID p_light, RID p_texture) {176GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();177Light *light = light_owner.get_or_null(p_light);178ERR_FAIL_NULL(light);179180if (light->projector == p_texture) {181return;182}183184if (light->type != RS::LIGHT_DIRECTIONAL && light->projector.is_valid()) {185texture_storage->texture_remove_from_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);186}187188light->projector = p_texture;189190if (light->type != RS::LIGHT_DIRECTIONAL) {191if (light->projector.is_valid()) {192texture_storage->texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);193}194light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);195}196}197198void LightStorage::light_set_negative(RID p_light, bool p_enable) {199Light *light = light_owner.get_or_null(p_light);200ERR_FAIL_NULL(light);201202light->negative = p_enable;203}204205void LightStorage::light_set_cull_mask(RID p_light, uint32_t p_mask) {206Light *light = light_owner.get_or_null(p_light);207ERR_FAIL_NULL(light);208209light->cull_mask = p_mask;210211light->version++;212light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_CULL_MASK);213}214215void LightStorage::light_set_shadow_caster_mask(RID p_light, uint32_t p_caster_mask) {216Light *light = light_owner.get_or_null(p_light);217ERR_FAIL_NULL(light);218219light->shadow_caster_mask = p_caster_mask;220221light->version++;222light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);223}224225uint32_t LightStorage::light_get_shadow_caster_mask(RID p_light) const {226Light *light = light_owner.get_or_null(p_light);227ERR_FAIL_NULL_V(light, 0);228229return light->shadow_caster_mask;230}231232void LightStorage::light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) {233Light *light = light_owner.get_or_null(p_light);234ERR_FAIL_NULL(light);235236light->distance_fade = p_enabled;237light->distance_fade_begin = p_begin;238light->distance_fade_shadow = p_shadow;239light->distance_fade_length = p_length;240}241242void LightStorage::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) {243Light *light = light_owner.get_or_null(p_light);244ERR_FAIL_NULL(light);245246light->reverse_cull = p_enabled;247248light->version++;249light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);250}251252void LightStorage::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) {253Light *light = light_owner.get_or_null(p_light);254ERR_FAIL_NULL(light);255256light->bake_mode = p_bake_mode;257258light->version++;259light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);260}261262void LightStorage::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) {263Light *light = light_owner.get_or_null(p_light);264ERR_FAIL_NULL(light);265266light->omni_shadow_mode = p_mode;267268light->version++;269light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);270}271272RS::LightOmniShadowMode LightStorage::light_omni_get_shadow_mode(RID p_light) {273const Light *light = light_owner.get_or_null(p_light);274ERR_FAIL_NULL_V(light, RS::LIGHT_OMNI_SHADOW_CUBE);275276return light->omni_shadow_mode;277}278279void LightStorage::light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) {280Light *light = light_owner.get_or_null(p_light);281ERR_FAIL_NULL(light);282283light->directional_shadow_mode = p_mode;284light->version++;285light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);286}287288void LightStorage::light_directional_set_blend_splits(RID p_light, bool p_enable) {289Light *light = light_owner.get_or_null(p_light);290ERR_FAIL_NULL(light);291292light->directional_blend_splits = p_enable;293light->version++;294light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);295}296297bool LightStorage::light_directional_get_blend_splits(RID p_light) const {298const Light *light = light_owner.get_or_null(p_light);299ERR_FAIL_NULL_V(light, false);300301return light->directional_blend_splits;302}303304void LightStorage::light_directional_set_sky_mode(RID p_light, RS::LightDirectionalSkyMode p_mode) {305Light *light = light_owner.get_or_null(p_light);306ERR_FAIL_NULL(light);307308light->directional_sky_mode = p_mode;309}310311RS::LightDirectionalSkyMode LightStorage::light_directional_get_sky_mode(RID p_light) const {312const Light *light = light_owner.get_or_null(p_light);313ERR_FAIL_NULL_V(light, RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY);314315return light->directional_sky_mode;316}317318RS::LightDirectionalShadowMode LightStorage::light_directional_get_shadow_mode(RID p_light) {319const Light *light = light_owner.get_or_null(p_light);320ERR_FAIL_NULL_V(light, RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL);321322return light->directional_shadow_mode;323}324325RS::LightBakeMode LightStorage::light_get_bake_mode(RID p_light) {326const Light *light = light_owner.get_or_null(p_light);327ERR_FAIL_NULL_V(light, RS::LIGHT_BAKE_DISABLED);328329return light->bake_mode;330}331332uint64_t LightStorage::light_get_version(RID p_light) const {333const Light *light = light_owner.get_or_null(p_light);334ERR_FAIL_NULL_V(light, 0);335336return light->version;337}338339uint32_t LightStorage::light_get_cull_mask(RID p_light) const {340const Light *light = light_owner.get_or_null(p_light);341ERR_FAIL_NULL_V(light, 0);342343return light->cull_mask;344}345346AABB LightStorage::light_get_aabb(RID p_light) const {347const Light *light = light_owner.get_or_null(p_light);348ERR_FAIL_NULL_V(light, AABB());349350switch (light->type) {351case RS::LIGHT_SPOT: {352float len = light->param[RS::LIGHT_PARAM_RANGE];353float angle = Math::deg_to_rad(light->param[RS::LIGHT_PARAM_SPOT_ANGLE]);354355if (angle > Math::PI * 0.5) {356// Light casts backwards as well.357return AABB(Vector3(-1, -1, -1) * len, Vector3(2, 2, 2) * len);358}359360float size = Math::sin(angle) * len;361return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len));362};363case RS::LIGHT_OMNI: {364float r = light->param[RS::LIGHT_PARAM_RANGE];365return AABB(-Vector3(r, r, r), Vector3(r, r, r) * 2);366};367case RS::LIGHT_DIRECTIONAL: {368return AABB();369};370}371372ERR_FAIL_V(AABB());373}374375/* LIGHT INSTANCE API */376377RID LightStorage::light_instance_create(RID p_light) {378RID li = light_instance_owner.make_rid(LightInstance());379380LightInstance *light_instance = light_instance_owner.get_or_null(li);381382light_instance->self = li;383light_instance->light = p_light;384light_instance->light_type = light_get_type(p_light);385386return li;387}388389void LightStorage::light_instance_free(RID p_light_instance) {390LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance);391ERR_FAIL_NULL(light_instance);392393// Remove from shadow atlases.394for (const RID &E : light_instance->shadow_atlases) {395ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(E);396ERR_CONTINUE(!shadow_atlas->shadow_owners.has(p_light_instance));397uint32_t key = shadow_atlas->shadow_owners[p_light_instance];398uint32_t q = (key >> QUADRANT_SHIFT) & 0x3;399uint32_t s = key & SHADOW_INDEX_MASK;400401shadow_atlas->quadrants[q].shadows.write[s].owner = RID();402403shadow_atlas->shadow_owners.erase(p_light_instance);404}405406light_instance_owner.free(p_light_instance);407}408409void LightStorage::light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) {410LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance);411ERR_FAIL_NULL(light_instance);412413light_instance->transform = p_transform;414}415416void LightStorage::light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) {417LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance);418ERR_FAIL_NULL(light_instance);419420light_instance->aabb = p_aabb;421}422423void LightStorage::light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) {424LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance);425ERR_FAIL_NULL(light_instance);426427ERR_FAIL_INDEX(p_pass, 6);428429light_instance->shadow_transform[p_pass].camera = p_projection;430light_instance->shadow_transform[p_pass].transform = p_transform;431light_instance->shadow_transform[p_pass].farplane = p_far;432light_instance->shadow_transform[p_pass].split = p_split;433light_instance->shadow_transform[p_pass].bias_scale = p_bias_scale;434light_instance->shadow_transform[p_pass].range_begin = p_range_begin;435light_instance->shadow_transform[p_pass].shadow_texel_size = p_shadow_texel_size;436light_instance->shadow_transform[p_pass].uv_scale = p_uv_scale;437}438439void LightStorage::light_instance_mark_visible(RID p_light_instance) {440LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance);441ERR_FAIL_NULL(light_instance);442443light_instance->last_scene_pass = RasterizerSceneGLES3::get_singleton()->get_scene_pass();444}445446/* PROBE API */447448RID LightStorage::reflection_probe_allocate() {449return reflection_probe_owner.allocate_rid();450}451452void LightStorage::reflection_probe_initialize(RID p_rid) {453ReflectionProbe probe;454455reflection_probe_owner.initialize_rid(p_rid, probe);456}457458void LightStorage::reflection_probe_free(RID p_rid) {459ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_rid);460reflection_probe->dependency.deleted_notify(p_rid);461462reflection_probe_owner.free(p_rid);463}464465void LightStorage::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) {466ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);467ERR_FAIL_NULL(reflection_probe);468469reflection_probe->update_mode = p_mode;470reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);471}472473void LightStorage::reflection_probe_set_intensity(RID p_probe, float p_intensity) {474ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);475ERR_FAIL_NULL(reflection_probe);476477reflection_probe->intensity = p_intensity;478}479480void LightStorage::reflection_probe_set_blend_distance(RID p_probe, float p_blend_distance) {481ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);482ERR_FAIL_NULL(reflection_probe);483484reflection_probe->blend_distance = p_blend_distance;485}486487void LightStorage::reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) {488ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);489ERR_FAIL_NULL(reflection_probe);490491reflection_probe->ambient_mode = p_mode;492}493494void LightStorage::reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) {495ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);496ERR_FAIL_NULL(reflection_probe);497498reflection_probe->ambient_color = p_color;499}500501void LightStorage::reflection_probe_set_ambient_energy(RID p_probe, float p_energy) {502ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);503ERR_FAIL_NULL(reflection_probe);504505reflection_probe->ambient_color_energy = p_energy;506}507508void LightStorage::reflection_probe_set_max_distance(RID p_probe, float p_distance) {509ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);510ERR_FAIL_NULL(reflection_probe);511512reflection_probe->max_distance = p_distance;513reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);514}515516void LightStorage::reflection_probe_set_size(RID p_probe, const Vector3 &p_size) {517ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);518ERR_FAIL_NULL(reflection_probe);519520reflection_probe->size = p_size;521reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);522}523524void LightStorage::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {525ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);526ERR_FAIL_NULL(reflection_probe);527528reflection_probe->origin_offset = p_offset;529reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);530}531532void LightStorage::reflection_probe_set_as_interior(RID p_probe, bool p_enable) {533ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);534ERR_FAIL_NULL(reflection_probe);535536reflection_probe->interior = p_enable;537reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);538}539540void LightStorage::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {541ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);542ERR_FAIL_NULL(reflection_probe);543544reflection_probe->box_projection = p_enable;545}546547void LightStorage::reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) {548ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);549ERR_FAIL_NULL(reflection_probe);550551reflection_probe->enable_shadows = p_enable;552reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);553}554555void LightStorage::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {556ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);557ERR_FAIL_NULL(reflection_probe);558559reflection_probe->cull_mask = p_layers;560reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);561}562563void LightStorage::reflection_probe_set_reflection_mask(RID p_probe, uint32_t p_layers) {564ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);565ERR_FAIL_NULL(reflection_probe);566567reflection_probe->reflection_mask = p_layers;568reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);569}570571void LightStorage::reflection_probe_set_resolution(RID p_probe, int p_resolution) {572WARN_PRINT_ONCE("reflection_probe_set_resolution is not available in Godot 4. ReflectionProbe size is configured in the project settings with the rendering/reflections/reflection_atlas/reflection_size setting.");573}574575AABB LightStorage::reflection_probe_get_aabb(RID p_probe) const {576const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);577ERR_FAIL_NULL_V(reflection_probe, AABB());578579AABB aabb;580aabb.position = -reflection_probe->size / 2;581aabb.size = reflection_probe->size;582583return aabb;584}585586RS::ReflectionProbeUpdateMode LightStorage::reflection_probe_get_update_mode(RID p_probe) const {587const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);588ERR_FAIL_NULL_V(reflection_probe, RenderingServer::REFLECTION_PROBE_UPDATE_ONCE);589590return reflection_probe->update_mode;591}592593uint32_t LightStorage::reflection_probe_get_cull_mask(RID p_probe) const {594const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);595ERR_FAIL_NULL_V(reflection_probe, 0);596597return reflection_probe->cull_mask;598}599600uint32_t LightStorage::reflection_probe_get_reflection_mask(RID p_probe) const {601const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);602ERR_FAIL_NULL_V(reflection_probe, 0);603604return reflection_probe->reflection_mask;605}606607Vector3 LightStorage::reflection_probe_get_size(RID p_probe) const {608const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);609ERR_FAIL_NULL_V(reflection_probe, Vector3());610611return reflection_probe->size;612}613614Vector3 LightStorage::reflection_probe_get_origin_offset(RID p_probe) const {615const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);616ERR_FAIL_NULL_V(reflection_probe, Vector3());617618return reflection_probe->origin_offset;619}620621float LightStorage::reflection_probe_get_origin_max_distance(RID p_probe) const {622const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);623ERR_FAIL_NULL_V(reflection_probe, 0.0);624625return reflection_probe->max_distance;626}627628bool LightStorage::reflection_probe_renders_shadows(RID p_probe) const {629const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);630ERR_FAIL_NULL_V(reflection_probe, false);631632return reflection_probe->enable_shadows;633}634635void LightStorage::reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_ratio) {636ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);637ERR_FAIL_NULL(reflection_probe);638639reflection_probe->mesh_lod_threshold = p_ratio;640reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);641}642643float LightStorage::reflection_probe_get_mesh_lod_threshold(RID p_probe) const {644const ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);645ERR_FAIL_NULL_V(reflection_probe, 0.0);646647return reflection_probe->mesh_lod_threshold;648}649650Dependency *LightStorage::reflection_probe_get_dependency(RID p_probe) const {651ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_probe);652ERR_FAIL_NULL_V(reflection_probe, nullptr);653654return &reflection_probe->dependency;655}656657/* REFLECTION ATLAS */658659RID LightStorage::reflection_atlas_create() {660ReflectionAtlas ra;661ra.count = GLOBAL_GET("rendering/reflections/reflection_atlas/reflection_count");662ra.size = GLOBAL_GET("rendering/reflections/reflection_atlas/reflection_size");663664return reflection_atlas_owner.make_rid(ra);665}666667void LightStorage::reflection_atlas_free(RID p_ref_atlas) {668reflection_atlas_set_size(p_ref_atlas, 0, 0);669670reflection_atlas_owner.free(p_ref_atlas);671}672673int LightStorage::reflection_atlas_get_size(RID p_ref_atlas) const {674ReflectionAtlas *ra = reflection_atlas_owner.get_or_null(p_ref_atlas);675ERR_FAIL_NULL_V(ra, 0);676677return ra->size;678}679680void LightStorage::reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) {681ReflectionAtlas *ra = reflection_atlas_owner.get_or_null(p_ref_atlas);682ERR_FAIL_NULL(ra);683684if (ra->size == p_reflection_size && ra->count == p_reflection_count) {685return; //no changes686}687688ra->size = p_reflection_size;689ra->count = p_reflection_count;690691if (ra->depth != 0) {692//clear and invalidate everything693for (int i = 0; i < ra->reflections.size(); i++) {694for (int j = 0; j < 7; j++) {695if (ra->reflections[i].fbos[j] != 0) {696glDeleteFramebuffers(1, &ra->reflections[i].fbos[j]);697ra->reflections.write[i].fbos[j] = 0;698}699}700701GLES3::Utilities::get_singleton()->texture_free_data(ra->reflections[i].color);702ra->reflections.write[i].color = 0;703704GLES3::Utilities::get_singleton()->texture_free_data(ra->reflections[i].radiance);705ra->reflections.write[i].radiance = 0;706707if (ra->reflections[i].owner.is_null()) {708continue;709}710reflection_probe_release_atlas_index(ra->reflections[i].owner);711//rp->atlasindex clear712}713714ra->reflections.clear();715716GLES3::Utilities::get_singleton()->texture_free_data(ra->depth);717ra->depth = 0;718}719720if (ra->render_buffers.is_valid()) {721ra->render_buffers->free_render_buffer_data();722}723}724725/* REFLECTION PROBE INSTANCE */726727RID LightStorage::reflection_probe_instance_create(RID p_probe) {728ReflectionProbeInstance rpi;729rpi.probe = p_probe;730731return reflection_probe_instance_owner.make_rid(rpi);732}733734void LightStorage::reflection_probe_instance_free(RID p_instance) {735reflection_probe_release_atlas_index(p_instance);736reflection_probe_instance_owner.free(p_instance);737}738739void LightStorage::reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) {740ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);741ERR_FAIL_NULL(rpi);742743rpi->transform = p_transform;744rpi->dirty = true;745}746747bool LightStorage::reflection_probe_has_atlas_index(RID p_instance) {748ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);749ERR_FAIL_NULL_V(rpi, false);750751if (rpi->atlas.is_null()) {752return false;753}754755return rpi->atlas_index >= 0;756}757758void LightStorage::reflection_probe_release_atlas_index(RID p_instance) {759ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);760ERR_FAIL_NULL(rpi);761762if (rpi->atlas.is_null()) {763return; //nothing to release764}765ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(rpi->atlas);766ERR_FAIL_NULL(atlas);767768ERR_FAIL_INDEX(rpi->atlas_index, atlas->reflections.size());769atlas->reflections.write[rpi->atlas_index].owner = RID();770771if (rpi->rendering) {772// We were cancelled mid rendering, trigger refresh.773rpi->rendering = false;774rpi->dirty = true;775rpi->processing_layer = 0;776}777778rpi->atlas_index = -1;779rpi->atlas = RID();780}781782bool LightStorage::reflection_probe_instance_needs_redraw(RID p_instance) {783ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);784ERR_FAIL_NULL_V(rpi, false);785786if (rpi->rendering) {787return false;788}789790if (rpi->dirty) {791return true;792}793794if (reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS) {795return true;796}797798return rpi->atlas_index == -1;799}800801bool LightStorage::reflection_probe_instance_has_reflection(RID p_instance) {802ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);803ERR_FAIL_NULL_V(rpi, false);804805return rpi->atlas.is_valid();806}807808bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) {809TextureStorage *texture_storage = TextureStorage::get_singleton();810ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(p_reflection_atlas);811812ERR_FAIL_NULL_V(atlas, false);813814ERR_FAIL_COND_V_MSG(atlas->size < 4, false, "Attempted to render to a reflection atlas of invalid resolution.");815ERR_FAIL_COND_V_MSG(atlas->count < 1, false, "Attempted to render to a reflection atlas of size < 1.");816817ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);818ERR_FAIL_NULL_V(rpi, false);819820if (atlas->render_buffers.is_null()) {821atlas->render_buffers.instantiate();822atlas->render_buffers->configure_for_probe(Size2i(atlas->size, atlas->size));823}824825// First we check if our atlas is initialized.826827// Not making an exception for update_mode = REFLECTION_PROBE_UPDATE_ALWAYS, we are using828// the same render techniques regardless of realtime or update once (for now).829830if (atlas->depth == 0) {831// We need to create our textures832atlas->mipmap_count = Image::get_image_required_mipmaps(atlas->size, atlas->size, Image::FORMAT_RGBAH) - 1;833atlas->mipmap_count = MIN(atlas->mipmap_count, 8); // No more than 8 please..834835glActiveTexture(GL_TEXTURE0);836837{838// We create one set of 6 layers for depth, we can reuse this when rendering.839glGenTextures(1, &atlas->depth);840glBindTexture(GL_TEXTURE_2D_ARRAY, atlas->depth);841842glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT24, atlas->size, atlas->size, 6, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);843844GLES3::Utilities::get_singleton()->texture_allocated_data(atlas->depth, atlas->size * atlas->size * 6 * 3, "Reflection probe atlas (depth)");845}846847// Make room for our atlas entries848atlas->reflections.resize(atlas->count);849850for (int i = 0; i < atlas->count; i++) {851// Create a cube map for this atlas entry852GLuint color = 0;853glGenTextures(1, &color);854glBindTexture(GL_TEXTURE_CUBE_MAP, color);855atlas->reflections.write[i].color = color;856857#ifdef GL_API_ENABLED858if (RasterizerGLES3::is_gles_over_gl()) {859for (int s = 0; s < 6; s++) {860glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + s, 0, GL_RGB10_A2, atlas->size, atlas->size, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, nullptr);861}862glGenerateMipmap(GL_TEXTURE_CUBE_MAP);863}864#endif865#ifdef GLES_API_ENABLED866if (!RasterizerGLES3::is_gles_over_gl()) {867glTexStorage2D(GL_TEXTURE_CUBE_MAP, atlas->mipmap_count, GL_RGB10_A2, atlas->size, atlas->size);868}869#endif // GLES_API_ENABLED870871glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);872glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);873glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);874glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);875glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);876glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, atlas->mipmap_count - 1);877878// Setup sizes and calculate how much memory we're using.879int mipmap_size = atlas->size;880uint32_t data_size = 0;881for (int m = 0; m < atlas->mipmap_count; m++) {882atlas->mipmap_size[m] = mipmap_size;883data_size += mipmap_size * mipmap_size * 6 * 4;884mipmap_size = MAX(mipmap_size >> 1, 1);885}886887GLES3::Utilities::get_singleton()->texture_allocated_data(color, data_size, String("Reflection probe atlas (") + String::num_int64(i) + String(", color)"));888889// Create a radiance map for this atlas entry890GLuint radiance = 0;891glGenTextures(1, &radiance);892glBindTexture(GL_TEXTURE_CUBE_MAP, radiance);893atlas->reflections.write[i].radiance = radiance;894895#ifdef GL_API_ENABLED896if (RasterizerGLES3::is_gles_over_gl()) {897for (int s = 0; s < 6; s++) {898glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + s, 0, GL_RGB10_A2, atlas->size, atlas->size, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, nullptr);899}900glGenerateMipmap(GL_TEXTURE_CUBE_MAP);901}902#endif903#ifdef GLES_API_ENABLED904if (!RasterizerGLES3::is_gles_over_gl()) {905glTexStorage2D(GL_TEXTURE_CUBE_MAP, atlas->mipmap_count, GL_RGB10_A2, atlas->size, atlas->size);906}907#endif // GLES_API_ENABLED908909glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);910glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);911glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);912glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);913glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);914glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, atlas->mipmap_count - 1);915916// Same data size as our color buffer917GLES3::Utilities::get_singleton()->texture_allocated_data(radiance, data_size, String("Reflection probe atlas (") + String::num_int64(i) + String(", radiance)"));918919// Create our framebuffers so we can draw to all sides920for (int side = 0; side < 6; side++) {921GLuint fbo = 0;922glGenFramebuffers(1, &fbo);923glBindFramebuffer(GL_FRAMEBUFFER, fbo);924925// We use glFramebufferTexture2D for the color buffer as glFramebufferTextureLayer doesn't always work with cubemaps.926glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + side, color, 0);927glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, atlas->depth, 0, side);928929// Validate framebuffer930GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);931if (status != GL_FRAMEBUFFER_COMPLETE) {932WARN_PRINT("Could not create reflections framebuffer, status: " + texture_storage->get_framebuffer_error(status));933}934935atlas->reflections.write[i].fbos[side] = fbo;936}937938// Create an extra framebuffer for building our radiance939{940GLuint fbo = 0;941glGenFramebuffers(1, &fbo);942glBindFramebuffer(GL_FRAMEBUFFER, fbo);943944atlas->reflections.write[i].fbos[6] = fbo;945}946}947948glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);949glBindTexture(GL_TEXTURE_CUBE_MAP, 0);950glBindTexture(GL_TEXTURE_2D_ARRAY, 0);951}952953// Then we find a free slot for our reflection probe954955if (rpi->atlas_index == -1) {956for (int i = 0; i < atlas->reflections.size(); i++) {957if (atlas->reflections[i].owner.is_null()) {958rpi->atlas_index = i;959break;960}961}962//find the one used last963if (rpi->atlas_index == -1) {964//everything is in use, find the one least used via LRU965uint64_t pass_min = 0;966967for (int i = 0; i < atlas->reflections.size(); i++) {968ReflectionProbeInstance *rpi2 = reflection_probe_instance_owner.get_or_null(atlas->reflections[i].owner);969if (rpi2->last_pass < pass_min) {970pass_min = rpi2->last_pass;971rpi->atlas_index = i;972}973}974}975}976977if (rpi->atlas_index != -1) { // should we fail if this is still -1 ?978atlas->reflections.write[rpi->atlas_index].owner = p_instance;979}980981rpi->atlas = p_reflection_atlas;982rpi->rendering = true;983rpi->dirty = false;984rpi->processing_layer = 0;985986return true;987}988989bool LightStorage::reflection_probe_instance_end_render(RID p_instance, RID p_reflection_atlas) {990return true;991}992993Ref<RenderSceneBuffers> LightStorage::reflection_probe_atlas_get_render_buffers(RID p_reflection_atlas) {994ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(p_reflection_atlas);995ERR_FAIL_NULL_V(atlas, Ref<RenderSceneBuffersGLES3>());996997return atlas->render_buffers;998}9991000bool LightStorage::reflection_probe_instance_postprocess_step(RID p_instance) {1001GLES3::CubemapFilter *cubemap_filter = GLES3::CubemapFilter::get_singleton();1002ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);1003ERR_FAIL_NULL_V(rpi, false);1004ERR_FAIL_COND_V(!rpi->rendering, false);1005ERR_FAIL_COND_V(rpi->atlas.is_null(), false);10061007ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(rpi->atlas);1008if (!atlas || rpi->atlas_index == -1) {1009//does not belong to an atlas anymore, cancel (was removed from atlas or atlas changed while rendering)1010rpi->rendering = false;1011rpi->processing_layer = 0;1012return false;1013}10141015if (LightStorage::get_singleton()->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS) {1016// Using real time reflections, all roughness is done in one step1017for (int m = 0; m < atlas->mipmap_count; m++) {1018const GLES3::ReflectionAtlas::Reflection &reflection = atlas->reflections[rpi->atlas_index];1019cubemap_filter->filter_radiance(reflection.color, reflection.radiance, reflection.fbos[6], atlas->size, atlas->mipmap_count, m);1020}10211022rpi->rendering = false;1023rpi->processing_layer = 0;1024return true;1025} else {1026const GLES3::ReflectionAtlas::Reflection &reflection = atlas->reflections[rpi->atlas_index];1027cubemap_filter->filter_radiance(reflection.color, reflection.radiance, reflection.fbos[6], atlas->size, atlas->mipmap_count, rpi->processing_layer);10281029rpi->processing_layer++;1030if (rpi->processing_layer == atlas->mipmap_count) {1031rpi->rendering = false;1032rpi->processing_layer = 0;1033return true;1034}1035}10361037return false;1038}10391040GLuint LightStorage::reflection_probe_instance_get_texture(RID p_instance) {1041ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);1042ERR_FAIL_NULL_V(rpi, 0);10431044ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(rpi->atlas);1045ERR_FAIL_NULL_V(atlas, 0);1046ERR_FAIL_COND_V(rpi->atlas_index < 0, 0);10471048return atlas->reflections[rpi->atlas_index].radiance;1049}10501051GLuint LightStorage::reflection_probe_instance_get_framebuffer(RID p_instance, int p_index) {1052ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);1053ERR_FAIL_NULL_V(rpi, 0);1054ERR_FAIL_INDEX_V(p_index, 6, 0);10551056ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(rpi->atlas);1057ERR_FAIL_NULL_V(atlas, 0);1058ERR_FAIL_COND_V(rpi->atlas_index < 0, 0);10591060return atlas->reflections[rpi->atlas_index].fbos[p_index];1061}10621063/* LIGHTMAP CAPTURE */10641065RID LightStorage::lightmap_allocate() {1066return lightmap_owner.allocate_rid();1067}10681069void LightStorage::lightmap_initialize(RID p_rid) {1070lightmap_owner.initialize_rid(p_rid, Lightmap());1071}10721073void LightStorage::lightmap_free(RID p_rid) {1074Lightmap *lightmap = lightmap_owner.get_or_null(p_rid);1075ERR_FAIL_NULL(lightmap);1076lightmap->dependency.deleted_notify(p_rid);1077lightmap_owner.free(p_rid);1078}10791080void LightStorage::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) {1081Lightmap *lightmap = lightmap_owner.get_or_null(p_lightmap);1082ERR_FAIL_NULL(lightmap);1083lightmap->light_texture = p_light;1084lightmap->uses_spherical_harmonics = p_uses_spherical_haromics;10851086Vector3i light_texture_size = GLES3::TextureStorage::get_singleton()->texture_get_size(lightmap->light_texture);1087lightmap->light_texture_size = Vector2i(light_texture_size.x, light_texture_size.y);10881089GLuint tex = GLES3::TextureStorage::get_singleton()->texture_get_texid(lightmap->light_texture);1090glBindTexture(GL_TEXTURE_2D_ARRAY, tex);1091glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);1092glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);1093glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);1094glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);1095glBindTexture(GL_TEXTURE_2D_ARRAY, 0);1096}10971098void LightStorage::lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) {1099Lightmap *lightmap = lightmap_owner.get_or_null(p_lightmap);1100ERR_FAIL_NULL(lightmap);1101lightmap->bounds = p_bounds;1102}11031104void LightStorage::lightmap_set_probe_interior(RID p_lightmap, bool p_interior) {1105Lightmap *lightmap = lightmap_owner.get_or_null(p_lightmap);1106ERR_FAIL_NULL(lightmap);1107lightmap->interior = p_interior;1108}11091110void LightStorage::lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) {1111Lightmap *lightmap = lightmap_owner.get_or_null(p_lightmap);1112ERR_FAIL_NULL(lightmap);11131114if (p_points.size()) {1115ERR_FAIL_COND(p_points.size() * 9 != p_point_sh.size());1116ERR_FAIL_COND((p_tetrahedra.size() % 4) != 0);1117ERR_FAIL_COND((p_bsp_tree.size() % 6) != 0);1118}11191120lightmap->points = p_points;1121lightmap->point_sh = p_point_sh;1122lightmap->tetrahedra = p_tetrahedra;1123lightmap->bsp_tree = p_bsp_tree;1124}11251126void LightStorage::lightmap_set_baked_exposure_normalization(RID p_lightmap, float p_exposure) {1127Lightmap *lightmap = lightmap_owner.get_or_null(p_lightmap);1128ERR_FAIL_NULL(lightmap);11291130lightmap->baked_exposure = p_exposure;1131}11321133PackedVector3Array LightStorage::lightmap_get_probe_capture_points(RID p_lightmap) const {1134Lightmap *lightmap = lightmap_owner.get_or_null(p_lightmap);1135ERR_FAIL_NULL_V(lightmap, PackedVector3Array());1136return lightmap->points;1137}11381139PackedColorArray LightStorage::lightmap_get_probe_capture_sh(RID p_lightmap) const {1140Lightmap *lightmap = lightmap_owner.get_or_null(p_lightmap);1141ERR_FAIL_NULL_V(lightmap, PackedColorArray());1142return lightmap->point_sh;1143}11441145PackedInt32Array LightStorage::lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const {1146Lightmap *lightmap = lightmap_owner.get_or_null(p_lightmap);1147ERR_FAIL_NULL_V(lightmap, PackedInt32Array());1148return lightmap->tetrahedra;1149}11501151PackedInt32Array LightStorage::lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const {1152Lightmap *lightmap = lightmap_owner.get_or_null(p_lightmap);1153ERR_FAIL_NULL_V(lightmap, PackedInt32Array());1154return lightmap->bsp_tree;1155}11561157AABB LightStorage::lightmap_get_aabb(RID p_lightmap) const {1158Lightmap *lightmap = lightmap_owner.get_or_null(p_lightmap);1159ERR_FAIL_NULL_V(lightmap, AABB());1160return lightmap->bounds;1161}11621163void LightStorage::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) {1164Lightmap *lm = lightmap_owner.get_or_null(p_lightmap);1165ERR_FAIL_NULL(lm);11661167for (int i = 0; i < 9; i++) {1168r_sh[i] = Color(0, 0, 0, 0);1169}11701171if (!lm->points.size() || !lm->bsp_tree.size() || !lm->tetrahedra.size()) {1172return;1173}11741175static_assert(sizeof(Lightmap::BSP) == 24);11761177const Lightmap::BSP *bsp = (const Lightmap::BSP *)lm->bsp_tree.ptr();1178int32_t node = 0;1179while (node >= 0) {1180if (Plane(bsp[node].plane[0], bsp[node].plane[1], bsp[node].plane[2], bsp[node].plane[3]).is_point_over(p_point)) {1181#ifdef DEBUG_ENABLED1182ERR_FAIL_COND(bsp[node].over >= 0 && bsp[node].over < node);1183#endif11841185node = bsp[node].over;1186} else {1187#ifdef DEBUG_ENABLED1188ERR_FAIL_COND(bsp[node].under >= 0 && bsp[node].under < node);1189#endif1190node = bsp[node].under;1191}1192}11931194if (node == Lightmap::BSP::EMPTY_LEAF) {1195return; // Nothing could be done.1196}11971198node = Math::abs(node) - 1;11991200uint32_t *tetrahedron = (uint32_t *)&lm->tetrahedra[node * 4];1201Vector3 points[4] = { lm->points[tetrahedron[0]], lm->points[tetrahedron[1]], lm->points[tetrahedron[2]], lm->points[tetrahedron[3]] };1202const Color *sh_colors[4]{ &lm->point_sh[tetrahedron[0] * 9], &lm->point_sh[tetrahedron[1] * 9], &lm->point_sh[tetrahedron[2] * 9], &lm->point_sh[tetrahedron[3] * 9] };1203Color barycentric = Geometry3D::tetrahedron_get_barycentric_coords(points[0], points[1], points[2], points[3], p_point);12041205for (int i = 0; i < 4; i++) {1206float c = CLAMP(barycentric[i], 0.0, 1.0);1207for (int j = 0; j < 9; j++) {1208r_sh[j] += sh_colors[i][j] * c;1209}1210}1211}12121213bool LightStorage::lightmap_is_interior(RID p_lightmap) const {1214Lightmap *lightmap = lightmap_owner.get_or_null(p_lightmap);1215ERR_FAIL_NULL_V(lightmap, false);1216return lightmap->interior;1217}12181219void LightStorage::lightmap_set_probe_capture_update_speed(float p_speed) {1220lightmap_probe_capture_update_speed = p_speed;1221}12221223float LightStorage::lightmap_get_probe_capture_update_speed() const {1224return lightmap_probe_capture_update_speed;1225}12261227void LightStorage::lightmap_set_shadowmask_textures(RID p_lightmap, RID p_shadow) {1228Lightmap *lightmap = lightmap_owner.get_or_null(p_lightmap);1229ERR_FAIL_NULL(lightmap);1230lightmap->shadow_texture = p_shadow;12311232GLuint tex = GLES3::TextureStorage::get_singleton()->texture_get_texid(lightmap->shadow_texture);1233glBindTexture(GL_TEXTURE_2D_ARRAY, tex);1234glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);1235glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);1236glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);1237glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);1238glBindTexture(GL_TEXTURE_2D_ARRAY, 0);1239}12401241RS::ShadowmaskMode LightStorage::lightmap_get_shadowmask_mode(RID p_lightmap) {1242Lightmap *lightmap = lightmap_owner.get_or_null(p_lightmap);1243ERR_FAIL_NULL_V(lightmap, RS::SHADOWMASK_MODE_NONE);12441245return lightmap->shadowmask_mode;1246}12471248void LightStorage::lightmap_set_shadowmask_mode(RID p_lightmap, RS::ShadowmaskMode p_mode) {1249Lightmap *lightmap = lightmap_owner.get_or_null(p_lightmap);1250ERR_FAIL_NULL(lightmap);1251lightmap->shadowmask_mode = p_mode;1252}12531254/* LIGHTMAP INSTANCE */12551256RID LightStorage::lightmap_instance_create(RID p_lightmap) {1257LightmapInstance li;1258li.lightmap = p_lightmap;1259return lightmap_instance_owner.make_rid(li);1260}12611262void LightStorage::lightmap_instance_free(RID p_lightmap) {1263lightmap_instance_owner.free(p_lightmap);1264}12651266void LightStorage::lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) {1267LightmapInstance *li = lightmap_instance_owner.get_or_null(p_lightmap);1268ERR_FAIL_NULL(li);1269li->transform = p_transform;1270}12711272/* SHADOW ATLAS API */12731274RID LightStorage::shadow_atlas_create() {1275return shadow_atlas_owner.make_rid(ShadowAtlas());1276}12771278void LightStorage::shadow_atlas_free(RID p_atlas) {1279shadow_atlas_set_size(p_atlas, 0);1280shadow_atlas_owner.free(p_atlas);1281}12821283void LightStorage::shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits) {1284ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_atlas);1285ERR_FAIL_NULL(shadow_atlas);1286ERR_FAIL_COND(p_size < 0);1287p_size = next_power_of_2((uint32_t)p_size);12881289if (p_size == shadow_atlas->size && p_16_bits == shadow_atlas->use_16_bits) {1290return;1291}12921293for (uint32_t i = 0; i < 4; i++) {1294// Clear all subdivisions and free shadows.1295for (uint32_t j = 0; j < shadow_atlas->quadrants[i].textures.size(); j++) {1296glDeleteTextures(1, &shadow_atlas->quadrants[i].textures[j]);1297glDeleteFramebuffers(1, &shadow_atlas->quadrants[i].fbos[j]);1298}1299shadow_atlas->quadrants[i].textures.clear();1300shadow_atlas->quadrants[i].fbos.clear();13011302shadow_atlas->quadrants[i].shadows.clear();1303shadow_atlas->quadrants[i].shadows.resize(shadow_atlas->quadrants[i].subdivision * shadow_atlas->quadrants[i].subdivision);1304}13051306// Erase shadow atlas reference from lights.1307for (const KeyValue<RID, uint32_t> &E : shadow_atlas->shadow_owners) {1308LightInstance *li = light_instance_owner.get_or_null(E.key);1309ERR_CONTINUE(!li);1310li->shadow_atlases.erase(p_atlas);1311}13121313if (shadow_atlas->debug_texture != 0) {1314glDeleteTextures(1, &shadow_atlas->debug_texture);1315}13161317if (shadow_atlas->debug_fbo != 0) {1318glDeleteFramebuffers(1, &shadow_atlas->debug_fbo);1319}13201321// Clear owners.1322shadow_atlas->shadow_owners.clear();13231324shadow_atlas->size = p_size;1325shadow_atlas->use_16_bits = p_16_bits;1326}13271328void LightStorage::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) {1329ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_atlas);1330ERR_FAIL_NULL(shadow_atlas);1331ERR_FAIL_INDEX(p_quadrant, 4);1332ERR_FAIL_INDEX(p_subdivision, 16384);13331334uint32_t subdiv = next_power_of_2((uint32_t)p_subdivision);1335if (subdiv & 0xaaaaaaaa) { // sqrt(subdiv) must be integer.1336subdiv <<= 1;1337}13381339subdiv = int(Math::sqrt((float)subdiv));13401341if (shadow_atlas->quadrants[p_quadrant].subdivision == subdiv) {1342return;1343}13441345// Erase all data from quadrant.1346for (int i = 0; i < shadow_atlas->quadrants[p_quadrant].shadows.size(); i++) {1347if (shadow_atlas->quadrants[p_quadrant].shadows[i].owner.is_valid()) {1348shadow_atlas->shadow_owners.erase(shadow_atlas->quadrants[p_quadrant].shadows[i].owner);1349LightInstance *li = light_instance_owner.get_or_null(shadow_atlas->quadrants[p_quadrant].shadows[i].owner);1350ERR_CONTINUE(!li);1351li->shadow_atlases.erase(p_atlas);1352}1353}13541355for (uint32_t j = 0; j < shadow_atlas->quadrants[p_quadrant].textures.size(); j++) {1356glDeleteTextures(1, &shadow_atlas->quadrants[p_quadrant].textures[j]);1357glDeleteFramebuffers(1, &shadow_atlas->quadrants[p_quadrant].fbos[j]);1358}13591360shadow_atlas->quadrants[p_quadrant].textures.clear();1361shadow_atlas->quadrants[p_quadrant].fbos.clear();13621363shadow_atlas->quadrants[p_quadrant].shadows.clear();1364shadow_atlas->quadrants[p_quadrant].shadows.resize(subdiv * subdiv);1365shadow_atlas->quadrants[p_quadrant].subdivision = subdiv;13661367// Cache the smallest subdiv (for faster allocation in light update).13681369shadow_atlas->smallest_subdiv = 1 << 30;13701371for (int i = 0; i < 4; i++) {1372if (shadow_atlas->quadrants[i].subdivision) {1373shadow_atlas->smallest_subdiv = MIN(shadow_atlas->smallest_subdiv, shadow_atlas->quadrants[i].subdivision);1374}1375}13761377if (shadow_atlas->smallest_subdiv == 1 << 30) {1378shadow_atlas->smallest_subdiv = 0;1379}13801381// Re-sort the size orders, simple bubblesort for 4 elements.13821383int swaps = 0;1384do {1385swaps = 0;13861387for (int i = 0; i < 3; i++) {1388if (shadow_atlas->quadrants[shadow_atlas->size_order[i]].subdivision < shadow_atlas->quadrants[shadow_atlas->size_order[i + 1]].subdivision) {1389SWAP(shadow_atlas->size_order[i], shadow_atlas->size_order[i + 1]);1390swaps++;1391}1392}1393} while (swaps > 0);1394}13951396bool LightStorage::shadow_atlas_update_light(RID p_atlas, RID p_light_instance, float p_coverage, uint64_t p_light_version) {1397ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_atlas);1398ERR_FAIL_NULL_V(shadow_atlas, false);13991400LightInstance *li = light_instance_owner.get_or_null(p_light_instance);1401ERR_FAIL_NULL_V(li, false);14021403if (shadow_atlas->size == 0 || shadow_atlas->smallest_subdiv == 0) {1404return false;1405}14061407uint32_t quad_size = shadow_atlas->size >> 1;1408int desired_fit = MIN(quad_size / shadow_atlas->smallest_subdiv, next_power_of_2(uint32_t(quad_size * p_coverage)));14091410int valid_quadrants[4];1411int valid_quadrant_count = 0;1412int best_size = -1; // Best size found.1413int best_subdiv = -1; // Subdiv for the best size.14141415// Find the quadrants this fits into, and the best possible size it can fit into.1416for (int i = 0; i < 4; i++) {1417int q = shadow_atlas->size_order[i];1418int sd = shadow_atlas->quadrants[q].subdivision;1419if (sd == 0) {1420continue; // Unused.1421}14221423int max_fit = quad_size / sd;14241425if (best_size != -1 && max_fit > best_size) {1426break; // Too large.1427}14281429valid_quadrants[valid_quadrant_count++] = q;1430best_subdiv = sd;14311432if (max_fit >= desired_fit) {1433best_size = max_fit;1434}1435}14361437ERR_FAIL_COND_V(valid_quadrant_count == 0, false);14381439uint64_t tick = OS::get_singleton()->get_ticks_msec();14401441uint32_t old_key = SHADOW_INVALID;1442uint32_t old_quadrant = SHADOW_INVALID;1443uint32_t old_shadow = SHADOW_INVALID;1444int old_subdivision = -1;14451446bool should_realloc = false;1447bool should_redraw = false;14481449if (shadow_atlas->shadow_owners.has(p_light_instance)) {1450old_key = shadow_atlas->shadow_owners[p_light_instance];1451old_quadrant = (old_key >> QUADRANT_SHIFT) & 0x3;1452old_shadow = old_key & SHADOW_INDEX_MASK;14531454// Only re-allocate if a better option is available, and enough time has passed.1455should_realloc = shadow_atlas->quadrants[old_quadrant].subdivision != (uint32_t)best_subdiv && (tick - shadow_atlas->quadrants[old_quadrant].shadows[old_shadow].alloc_tick > shadow_atlas_realloc_tolerance_msec);1456should_redraw = shadow_atlas->quadrants[old_quadrant].shadows[old_shadow].version != p_light_version;14571458if (!should_realloc) {1459shadow_atlas->quadrants[old_quadrant].shadows.write[old_shadow].version = p_light_version;1460// Already existing, see if it should redraw or it's just OK.1461return should_redraw;1462}14631464old_subdivision = shadow_atlas->quadrants[old_quadrant].subdivision;1465}14661467bool is_omni = li->light_type == RS::LIGHT_OMNI;1468bool found_shadow = false;1469int new_quadrant = -1;1470int new_shadow = -1;14711472found_shadow = _shadow_atlas_find_shadow(shadow_atlas, valid_quadrants, valid_quadrant_count, old_subdivision, tick, is_omni, new_quadrant, new_shadow);14731474// For new shadows if we found an atlas.1475// Or for existing shadows that found a better atlas.1476if (found_shadow) {1477if (old_quadrant != SHADOW_INVALID) {1478shadow_atlas->quadrants[old_quadrant].shadows.write[old_shadow].version = 0;1479shadow_atlas->quadrants[old_quadrant].shadows.write[old_shadow].owner = RID();1480}14811482uint32_t new_key = new_quadrant << QUADRANT_SHIFT;1483new_key |= new_shadow;14841485ShadowAtlas::Quadrant::Shadow *sh = &shadow_atlas->quadrants[new_quadrant].shadows.write[new_shadow];1486_shadow_atlas_invalidate_shadow(sh, p_atlas, shadow_atlas, new_quadrant, new_shadow);14871488sh->owner = p_light_instance;1489sh->owner_is_omni = is_omni;1490sh->alloc_tick = tick;1491sh->version = p_light_version;14921493li->shadow_atlases.insert(p_atlas);14941495// Update it in map.1496shadow_atlas->shadow_owners[p_light_instance] = new_key;1497// Make it dirty, as it should redraw anyway.1498return true;1499}15001501return should_redraw;1502}15031504bool LightStorage::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, bool is_omni, int &r_quadrant, int &r_shadow) {1505for (int i = p_quadrant_count - 1; i >= 0; i--) {1506int qidx = p_in_quadrants[i];15071508if (shadow_atlas->quadrants[qidx].subdivision == (uint32_t)p_current_subdiv) {1509return false;1510}15111512// Look for an empty space.1513int sc = shadow_atlas->quadrants[qidx].shadows.size();1514const ShadowAtlas::Quadrant::Shadow *sarr = shadow_atlas->quadrants[qidx].shadows.ptr();15151516// We have a free space in this quadrant, allocate a texture and use it.1517if (sc > (int)shadow_atlas->quadrants[qidx].textures.size()) {1518GLuint fbo_id = 0;1519glGenFramebuffers(1, &fbo_id);1520glBindFramebuffer(GL_FRAMEBUFFER, fbo_id);15211522GLuint texture_id = 0;1523glGenTextures(1, &texture_id);1524glActiveTexture(GL_TEXTURE0);15251526int size = (shadow_atlas->size >> 1) / shadow_atlas->quadrants[qidx].subdivision;15271528GLenum format = shadow_atlas->use_16_bits ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT24;1529GLenum type = shadow_atlas->use_16_bits ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;15301531if (is_omni) {1532glBindTexture(GL_TEXTURE_CUBE_MAP, texture_id);1533for (int id = 0; id < 6; id++) {1534glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + id, 0, format, size / 2, size / 2, 0, GL_DEPTH_COMPONENT, type, nullptr);1535}15361537glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);1538glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);15391540glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);1541glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);1542glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);15431544glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);1545glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);15461547glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X, texture_id, 0);15481549#ifdef DEBUG_ENABLED1550GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);1551if (status != GL_FRAMEBUFFER_COMPLETE) {1552ERR_PRINT("Could not create omni light shadow framebuffer, status: " + GLES3::TextureStorage::get_singleton()->get_framebuffer_error(status));1553}1554#endif1555glBindTexture(GL_TEXTURE_CUBE_MAP, 0);1556} else {1557glBindTexture(GL_TEXTURE_2D, texture_id);15581559glTexImage2D(GL_TEXTURE_2D, 0, format, size, size, 0, GL_DEPTH_COMPONENT, type, nullptr);15601561glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);1562glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);1563glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);1564glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);15651566glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);1567glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);15681569glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture_id, 0);15701571glBindTexture(GL_TEXTURE_2D, 0);1572}1573glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);15741575r_quadrant = qidx;1576r_shadow = shadow_atlas->quadrants[qidx].textures.size();15771578shadow_atlas->quadrants[qidx].textures.push_back(texture_id);1579shadow_atlas->quadrants[qidx].fbos.push_back(fbo_id);15801581return true;1582}15831584int found_used_idx = -1; // Found existing one, must steal it.1585uint64_t min_pass = 0; // Pass of the existing one, try to use the least recently used one (LRU fashion).15861587for (int j = 0; j < sc; j++) {1588if (sarr[j].owner_is_omni != is_omni) {1589// Existing light instance type doesn't match new light instance type skip.1590continue;1591}15921593LightInstance *sli = light_instance_owner.get_or_null(sarr[j].owner);1594if (!sli) {1595// Found a released light instance.1596found_used_idx = j;1597break;1598}15991600if (sli->last_scene_pass != RasterizerSceneGLES3::get_singleton()->get_scene_pass()) {1601// Was just allocated, don't kill it so soon, wait a bit.1602if (p_tick - sarr[j].alloc_tick < shadow_atlas_realloc_tolerance_msec) {1603continue;1604}16051606if (found_used_idx == -1 || sli->last_scene_pass < min_pass) {1607found_used_idx = j;1608min_pass = sli->last_scene_pass;1609}1610}1611}16121613if (found_used_idx != -1) {1614r_quadrant = qidx;1615r_shadow = found_used_idx;16161617return true;1618}1619}16201621return false;1622}16231624void LightStorage::_shadow_atlas_invalidate_shadow(ShadowAtlas::Quadrant::Shadow *p_shadow, RID p_atlas, ShadowAtlas *p_shadow_atlas, uint32_t p_quadrant, uint32_t p_shadow_idx) {1625if (p_shadow->owner.is_valid()) {1626LightInstance *sli = light_instance_owner.get_or_null(p_shadow->owner);16271628p_shadow_atlas->shadow_owners.erase(p_shadow->owner);1629p_shadow->version = 0;1630p_shadow->owner = RID();1631sli->shadow_atlases.erase(p_atlas);1632}1633}16341635void LightStorage::shadow_atlas_update(RID p_atlas) {1636// Do nothing as there is no shadow atlas texture.1637}16381639/* DIRECTIONAL SHADOW */16401641// Create if necessary and clear.1642void LightStorage::update_directional_shadow_atlas() {1643if (directional_shadow.depth == 0 && directional_shadow.size > 0) {1644glGenFramebuffers(1, &directional_shadow.fbo);1645glBindFramebuffer(GL_FRAMEBUFFER, directional_shadow.fbo);16461647glGenTextures(1, &directional_shadow.depth);1648glActiveTexture(GL_TEXTURE0);1649glBindTexture(GL_TEXTURE_2D, directional_shadow.depth);16501651GLenum format = directional_shadow.use_16_bits ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT24;1652GLenum type = directional_shadow.use_16_bits ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;16531654glTexImage2D(GL_TEXTURE_2D, 0, format, directional_shadow.size, directional_shadow.size, 0, GL_DEPTH_COMPONENT, type, nullptr);16551656glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);1657glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);1658glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);1659glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);16601661glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);1662glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);16631664glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, directional_shadow.depth, 0);1665}1666glUseProgram(0);1667glDepthMask(GL_TRUE);1668glBindFramebuffer(GL_FRAMEBUFFER, directional_shadow.fbo);1669RasterizerGLES3::clear_depth(0.0);1670glClear(GL_DEPTH_BUFFER_BIT);16711672glBindTexture(GL_TEXTURE_2D, 0);1673glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);1674}16751676void LightStorage::directional_shadow_atlas_set_size(int p_size, bool p_16_bits) {1677p_size = nearest_power_of_2_templated(p_size);16781679if (directional_shadow.size == p_size && directional_shadow.use_16_bits == p_16_bits) {1680return;1681}16821683directional_shadow.size = p_size;1684directional_shadow.use_16_bits = p_16_bits;16851686if (directional_shadow.depth != 0) {1687glDeleteTextures(1, &directional_shadow.depth);1688directional_shadow.depth = 0;1689glDeleteFramebuffers(1, &directional_shadow.fbo);1690directional_shadow.fbo = 0;1691}1692}16931694void LightStorage::set_directional_shadow_count(int p_count) {1695directional_shadow.light_count = p_count;1696directional_shadow.current_light = 0;1697}16981699static Rect2i _get_directional_shadow_rect(int p_size, int p_shadow_count, int p_shadow_index) {1700int split_h = 1;1701int split_v = 1;17021703while (split_h * split_v < p_shadow_count) {1704if (split_h == split_v) {1705split_h <<= 1;1706} else {1707split_v <<= 1;1708}1709}17101711Rect2i rect(0, 0, p_size, p_size);1712rect.size.width /= split_h;1713rect.size.height /= split_v;17141715rect.position.x = rect.size.width * (p_shadow_index % split_h);1716rect.position.y = rect.size.height * (p_shadow_index / split_h);17171718return rect;1719}17201721Rect2i LightStorage::get_directional_shadow_rect() {1722return _get_directional_shadow_rect(directional_shadow.size, directional_shadow.light_count, directional_shadow.current_light);1723}17241725int LightStorage::get_directional_light_shadow_size(RID p_light_instance) {1726ERR_FAIL_COND_V(directional_shadow.light_count == 0, 0);17271728Rect2i r = _get_directional_shadow_rect(directional_shadow.size, directional_shadow.light_count, 0);17291730LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance);1731ERR_FAIL_NULL_V(light_instance, 0);17321733switch (light_directional_get_shadow_mode(light_instance->light)) {1734case RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL:1735break; //none1736case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS:1737r.size.height /= 2;1738break;1739case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS:1740r.size /= 2;1741break;1742}17431744return MAX(r.size.width, r.size.height);1745}17461747#endif // !GLES3_ENABLED174817491750