Path: blob/master/drivers/gles3/rasterizer_scene_gles3.cpp
9973 views
/**************************************************************************/1/* rasterizer_scene_gles3.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#include "rasterizer_scene_gles3.h"3132#include "drivers/gles3/effects/copy_effects.h"33#include "drivers/gles3/effects/feed_effects.h"34#include "drivers/gles3/storage/material_storage.h"35#include "rasterizer_gles3.h"36#include "storage/config.h"37#include "storage/mesh_storage.h"38#include "storage/particles_storage.h"39#include "storage/texture_storage.h"4041#include "core/config/project_settings.h"42#include "core/templates/sort_array.h"43#include "servers/camera/camera_feed.h"44#include "servers/camera_server.h"45#include "servers/rendering/rendering_server_default.h"46#include "servers/rendering/rendering_server_globals.h"4748#ifdef GLES3_ENABLED4950RasterizerSceneGLES3 *RasterizerSceneGLES3::singleton = nullptr;5152RenderGeometryInstance *RasterizerSceneGLES3::geometry_instance_create(RID p_base) {53RS::InstanceType type = RSG::utilities->get_base_type(p_base);54ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr);5556GeometryInstanceGLES3 *ginstance = geometry_instance_alloc.alloc();57ginstance->data = memnew(GeometryInstanceGLES3::Data);5859ginstance->data->base = p_base;60ginstance->data->base_type = type;61ginstance->data->dependency_tracker.userdata = ginstance;62ginstance->data->dependency_tracker.changed_callback = _geometry_instance_dependency_changed;63ginstance->data->dependency_tracker.deleted_callback = _geometry_instance_dependency_deleted;6465ginstance->_mark_dirty();6667return ginstance;68}6970uint32_t RasterizerSceneGLES3::geometry_instance_get_pair_mask() {71return ((1 << RS::INSTANCE_LIGHT) | (1 << RS::INSTANCE_REFLECTION_PROBE));72}7374void RasterizerSceneGLES3::GeometryInstanceGLES3::pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) {75GLES3::Config *config = GLES3::Config::get_singleton();7677paired_omni_light_count = 0;78paired_spot_light_count = 0;79paired_omni_lights.clear();80paired_spot_lights.clear();8182for (uint32_t i = 0; i < p_light_instance_count; i++) {83RS::LightType type = GLES3::LightStorage::get_singleton()->light_instance_get_type(p_light_instances[i]);84switch (type) {85case RS::LIGHT_OMNI: {86if (paired_omni_light_count < (uint32_t)config->max_lights_per_object) {87paired_omni_lights.push_back(p_light_instances[i]);88paired_omni_light_count++;89}90} break;91case RS::LIGHT_SPOT: {92if (paired_spot_light_count < (uint32_t)config->max_lights_per_object) {93paired_spot_lights.push_back(p_light_instances[i]);94paired_spot_light_count++;95}96} break;97default:98break;99}100}101}102103void RasterizerSceneGLES3::GeometryInstanceGLES3::pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) {104paired_reflection_probes.clear();105106for (uint32_t i = 0; i < p_reflection_probe_instance_count; i++) {107paired_reflection_probes.push_back(p_reflection_probe_instances[i]);108}109}110111void RasterizerSceneGLES3::geometry_instance_free(RenderGeometryInstance *p_geometry_instance) {112GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);113ERR_FAIL_NULL(ginstance);114GeometryInstanceSurface *surf = ginstance->surface_caches;115while (surf) {116GeometryInstanceSurface *next = surf->next;117geometry_instance_surface_alloc.free(surf);118surf = next;119}120memdelete(ginstance->data);121geometry_instance_alloc.free(ginstance);122}123124void RasterizerSceneGLES3::GeometryInstanceGLES3::_mark_dirty() {125if (dirty_list_element.in_list()) {126return;127}128129//clear surface caches130GeometryInstanceSurface *surf = surface_caches;131132while (surf) {133GeometryInstanceSurface *next = surf->next;134RasterizerSceneGLES3::get_singleton()->geometry_instance_surface_alloc.free(surf);135surf = next;136}137138surface_caches = nullptr;139140RasterizerSceneGLES3::get_singleton()->geometry_instance_dirty_list.add(&dirty_list_element);141}142143void RasterizerSceneGLES3::GeometryInstanceGLES3::set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) {144lightmap_instance = p_lightmap_instance;145lightmap_uv_scale = p_lightmap_uv_scale;146lightmap_slice_index = p_lightmap_slice_index;147148_mark_dirty();149}150151void RasterizerSceneGLES3::GeometryInstanceGLES3::set_lightmap_capture(const Color *p_sh9) {152if (p_sh9) {153if (lightmap_sh == nullptr) {154lightmap_sh = memnew(GeometryInstanceLightmapSH);155}156157memcpy(lightmap_sh->sh, p_sh9, sizeof(Color) * 9);158} else {159if (lightmap_sh != nullptr) {160memdelete(lightmap_sh);161lightmap_sh = nullptr;162}163}164_mark_dirty();165}166167void RasterizerSceneGLES3::_update_dirty_geometry_instances() {168while (geometry_instance_dirty_list.first()) {169_geometry_instance_update(geometry_instance_dirty_list.first()->self());170}171}172173void RasterizerSceneGLES3::_geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker) {174switch (p_notification) {175case Dependency::DEPENDENCY_CHANGED_MATERIAL:176case Dependency::DEPENDENCY_CHANGED_MESH:177case Dependency::DEPENDENCY_CHANGED_PARTICLES:178case Dependency::DEPENDENCY_CHANGED_MULTIMESH:179case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: {180static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty();181static_cast<GeometryInstanceGLES3 *>(p_tracker->userdata)->data->dirty_dependencies = true;182} break;183case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: {184GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_tracker->userdata);185if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) {186ginstance->instance_count = GLES3::MeshStorage::get_singleton()->multimesh_get_instances_to_draw(ginstance->data->base);187}188} break;189default: {190//rest of notifications of no interest191} break;192}193}194195void RasterizerSceneGLES3::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) {196static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty();197static_cast<GeometryInstanceGLES3 *>(p_tracker->userdata)->data->dirty_dependencies = true;198}199200void RasterizerSceneGLES3::_geometry_instance_add_surface_with_material(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, GLES3::SceneMaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh) {201GLES3::MeshStorage *mesh_storage = GLES3::MeshStorage::get_singleton();202203bool has_read_screen_alpha = p_material->shader_data->uses_screen_texture || p_material->shader_data->uses_depth_texture || p_material->shader_data->uses_normal_texture;204bool has_base_alpha = ((p_material->shader_data->uses_alpha && !p_material->shader_data->uses_alpha_clip) || has_read_screen_alpha);205bool has_blend_alpha = p_material->shader_data->uses_blend_alpha;206bool has_alpha = has_base_alpha || has_blend_alpha;207208uint32_t flags = 0;209210if (p_material->shader_data->uses_screen_texture) {211flags |= GeometryInstanceSurface::FLAG_USES_SCREEN_TEXTURE;212}213214if (p_material->shader_data->uses_depth_texture) {215flags |= GeometryInstanceSurface::FLAG_USES_DEPTH_TEXTURE;216}217218if (p_material->shader_data->uses_normal_texture) {219flags |= GeometryInstanceSurface::FLAG_USES_NORMAL_TEXTURE;220}221222if (ginstance->data->cast_double_sided_shadows) {223flags |= GeometryInstanceSurface::FLAG_USES_DOUBLE_SIDED_SHADOWS;224}225226if (p_material->shader_data->stencil_enabled) {227flags |= GeometryInstanceSurface::FLAG_USES_STENCIL;228}229230if (has_alpha || has_read_screen_alpha || p_material->shader_data->depth_draw == GLES3::SceneShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test != GLES3::SceneShaderData::DEPTH_TEST_ENABLED) {231//material is only meant for alpha pass232flags |= GeometryInstanceSurface::FLAG_PASS_ALPHA;233if (p_material->shader_data->uses_depth_prepass_alpha && !(p_material->shader_data->depth_draw == GLES3::SceneShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test != GLES3::SceneShaderData::DEPTH_TEST_ENABLED)) {234flags |= GeometryInstanceSurface::FLAG_PASS_DEPTH;235flags |= GeometryInstanceSurface::FLAG_PASS_SHADOW;236}237} else {238flags |= GeometryInstanceSurface::FLAG_PASS_OPAQUE;239flags |= GeometryInstanceSurface::FLAG_PASS_DEPTH;240flags |= GeometryInstanceSurface::FLAG_PASS_SHADOW;241}242243if (p_material->shader_data->stencil_enabled) {244if (p_material->shader_data->stencil_flags & GLES3::SceneShaderData::STENCIL_FLAG_READ) {245// Stencil materials which read from the stencil buffer must be in the alpha pass.246// This is critical to preserve compatibility once we'll have the compositor.247if (!(flags & GeometryInstanceSurface::FLAG_PASS_ALPHA)) {248String shader_path = p_material->shader_data->path.is_empty() ? "" : "(" + p_material->shader_data->path + ")";249ERR_PRINT_ED(vformat("Attempting to use a shader %s that reads stencil but is not in the alpha queue. Ensure the material uses alpha blending or has depth_draw disabled or depth_test disabled.", shader_path));250}251}252}253254GLES3::SceneMaterialData *material_shadow = nullptr;255void *surface_shadow = nullptr;256if (!p_material->shader_data->uses_particle_trails && !p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_prepass_alpha && !p_material->shader_data->uses_alpha_clip && !p_material->shader_data->uses_world_coordinates && !p_material->shader_data->wireframe) {257flags |= GeometryInstanceSurface::FLAG_USES_SHARED_SHADOW_MATERIAL;258material_shadow = static_cast<GLES3::SceneMaterialData *>(GLES3::MaterialStorage::get_singleton()->material_get_data(scene_globals.default_material, RS::SHADER_SPATIAL));259260RID shadow_mesh = mesh_storage->mesh_get_shadow_mesh(p_mesh);261262if (shadow_mesh.is_valid()) {263surface_shadow = mesh_storage->mesh_get_surface(shadow_mesh, p_surface);264}265266} else {267material_shadow = p_material;268}269270GeometryInstanceSurface *sdcache = geometry_instance_surface_alloc.alloc();271272sdcache->flags = flags;273274sdcache->shader = p_material->shader_data;275sdcache->material = p_material;276sdcache->surface = mesh_storage->mesh_get_surface(p_mesh, p_surface);277sdcache->primitive = mesh_storage->mesh_surface_get_primitive(sdcache->surface);278sdcache->surface_index = p_surface;279280if (ginstance->data->dirty_dependencies) {281RSG::utilities->base_update_dependency(p_mesh, &ginstance->data->dependency_tracker);282}283284//shadow285sdcache->shader_shadow = material_shadow->shader_data;286sdcache->material_shadow = material_shadow;287288sdcache->surface_shadow = surface_shadow ? surface_shadow : sdcache->surface;289290sdcache->owner = ginstance;291292sdcache->next = ginstance->surface_caches;293ginstance->surface_caches = sdcache;294295//sortkey296297sdcache->sort.sort_key1 = 0;298sdcache->sort.sort_key2 = 0;299300sdcache->sort.surface_index = p_surface;301sdcache->sort.material_id_low = p_material_id & 0x0000FFFF;302sdcache->sort.material_id_hi = p_material_id >> 16;303sdcache->sort.shader_id = p_shader_id;304sdcache->sort.geometry_id = p_mesh.get_local_index();305sdcache->sort.priority = p_material->priority;306307GLES3::Mesh::Surface *s = reinterpret_cast<GLES3::Mesh::Surface *>(sdcache->surface);308if (p_material->shader_data->uses_tangent && !(s->format & RS::ARRAY_FORMAT_TANGENT)) {309String shader_path = p_material->shader_data->path.is_empty() ? "" : "(" + p_material->shader_data->path + ")";310String mesh_path = mesh_storage->mesh_get_path(p_mesh).is_empty() ? "" : "(" + mesh_storage->mesh_get_path(p_mesh) + ")";311WARN_PRINT_ED(vformat("Attempting to use a shader %s that requires tangents with a mesh %s that doesn't contain tangents. Ensure that meshes are imported with the 'ensure_tangents' option. If creating your own meshes, add an `ARRAY_TANGENT` array (when using ArrayMesh) or call `generate_tangents()` (when using SurfaceTool).", shader_path, mesh_path));312}313}314315void RasterizerSceneGLES3::_geometry_instance_add_surface_with_material_chain(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, GLES3::SceneMaterialData *p_material_data, RID p_mat_src, RID p_mesh) {316GLES3::SceneMaterialData *material_data = p_material_data;317GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();318319_geometry_instance_add_surface_with_material(ginstance, p_surface, material_data, p_mat_src.get_local_index(), material_storage->material_get_shader_id(p_mat_src), p_mesh);320321while (material_data->next_pass.is_valid()) {322RID next_pass = material_data->next_pass;323material_data = static_cast<GLES3::SceneMaterialData *>(material_storage->material_get_data(next_pass, RS::SHADER_SPATIAL));324if (!material_data || !material_data->shader_data->valid) {325break;326}327if (ginstance->data->dirty_dependencies) {328material_storage->material_update_dependency(next_pass, &ginstance->data->dependency_tracker);329}330_geometry_instance_add_surface_with_material(ginstance, p_surface, material_data, next_pass.get_local_index(), material_storage->material_get_shader_id(next_pass), p_mesh);331}332}333334void RasterizerSceneGLES3::_geometry_instance_add_surface(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, RID p_material, RID p_mesh) {335GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();336RID m_src;337338m_src = ginstance->data->material_override.is_valid() ? ginstance->data->material_override : p_material;339340GLES3::SceneMaterialData *material_data = nullptr;341342if (m_src.is_valid()) {343material_data = static_cast<GLES3::SceneMaterialData *>(material_storage->material_get_data(m_src, RS::SHADER_SPATIAL));344if (!material_data || !material_data->shader_data->valid) {345material_data = nullptr;346}347}348349if (material_data) {350if (ginstance->data->dirty_dependencies) {351material_storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker);352}353} else {354material_data = static_cast<GLES3::SceneMaterialData *>(material_storage->material_get_data(scene_globals.default_material, RS::SHADER_SPATIAL));355m_src = scene_globals.default_material;356}357358ERR_FAIL_NULL(material_data);359360_geometry_instance_add_surface_with_material_chain(ginstance, p_surface, material_data, m_src, p_mesh);361362if (ginstance->data->material_overlay.is_valid()) {363m_src = ginstance->data->material_overlay;364365material_data = static_cast<GLES3::SceneMaterialData *>(material_storage->material_get_data(m_src, RS::SHADER_SPATIAL));366if (material_data && material_data->shader_data->valid) {367if (ginstance->data->dirty_dependencies) {368material_storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker);369}370371_geometry_instance_add_surface_with_material_chain(ginstance, p_surface, material_data, m_src, p_mesh);372}373}374}375376void RasterizerSceneGLES3::_geometry_instance_update(RenderGeometryInstance *p_geometry_instance) {377GLES3::MeshStorage *mesh_storage = GLES3::MeshStorage::get_singleton();378GLES3::ParticlesStorage *particles_storage = GLES3::ParticlesStorage::get_singleton();379380GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);381382if (ginstance->data->dirty_dependencies) {383ginstance->data->dependency_tracker.update_begin();384}385386//add geometry for drawing387switch (ginstance->data->base_type) {388case RS::INSTANCE_MESH: {389const RID *materials = nullptr;390uint32_t surface_count;391RID mesh = ginstance->data->base;392393materials = mesh_storage->mesh_get_surface_count_and_materials(mesh, surface_count);394if (materials) {395//if no materials, no surfaces.396const RID *inst_materials = ginstance->data->surface_materials.ptr();397uint32_t surf_mat_count = ginstance->data->surface_materials.size();398399for (uint32_t j = 0; j < surface_count; j++) {400RID material = (j < surf_mat_count && inst_materials[j].is_valid()) ? inst_materials[j] : materials[j];401_geometry_instance_add_surface(ginstance, j, material, mesh);402}403}404405ginstance->instance_count = -1;406407} break;408409case RS::INSTANCE_MULTIMESH: {410RID mesh = mesh_storage->multimesh_get_mesh(ginstance->data->base);411if (mesh.is_valid()) {412const RID *materials = nullptr;413uint32_t surface_count;414415materials = mesh_storage->mesh_get_surface_count_and_materials(mesh, surface_count);416if (materials) {417for (uint32_t j = 0; j < surface_count; j++) {418_geometry_instance_add_surface(ginstance, j, materials[j], mesh);419}420}421422ginstance->instance_count = mesh_storage->multimesh_get_instances_to_draw(ginstance->data->base);423}424425} break;426case RS::INSTANCE_PARTICLES: {427int draw_passes = particles_storage->particles_get_draw_passes(ginstance->data->base);428429for (int j = 0; j < draw_passes; j++) {430RID mesh = particles_storage->particles_get_draw_pass_mesh(ginstance->data->base, j);431if (!mesh.is_valid()) {432continue;433}434435const RID *materials = nullptr;436uint32_t surface_count;437438materials = mesh_storage->mesh_get_surface_count_and_materials(mesh, surface_count);439if (materials) {440for (uint32_t k = 0; k < surface_count; k++) {441_geometry_instance_add_surface(ginstance, k, materials[k], mesh);442}443}444}445446ginstance->instance_count = particles_storage->particles_get_amount(ginstance->data->base);447} break;448449default: {450}451}452453bool store_transform = true;454ginstance->base_flags = 0;455456if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) {457ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH;458if (mesh_storage->multimesh_get_transform_format(ginstance->data->base) == RS::MULTIMESH_TRANSFORM_2D) {459ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D;460}461if (mesh_storage->multimesh_uses_colors(ginstance->data->base)) {462ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR;463}464if (mesh_storage->multimesh_uses_custom_data(ginstance->data->base)) {465ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA;466}467468} else if (ginstance->data->base_type == RS::INSTANCE_PARTICLES) {469ginstance->base_flags |= INSTANCE_DATA_FLAG_PARTICLES;470ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH;471472ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR;473ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA;474475if (!particles_storage->particles_is_using_local_coords(ginstance->data->base)) {476store_transform = false;477}478479} else if (ginstance->data->base_type == RS::INSTANCE_MESH) {480if (mesh_storage->skeleton_is_valid(ginstance->data->skeleton)) {481if (ginstance->data->dirty_dependencies) {482mesh_storage->skeleton_update_dependency(ginstance->data->skeleton, &ginstance->data->dependency_tracker);483}484}485}486487ginstance->store_transform_cache = store_transform;488489if (ginstance->data->dirty_dependencies) {490ginstance->data->dependency_tracker.update_end();491ginstance->data->dirty_dependencies = false;492}493494ginstance->dirty_list_element.remove_from_list();495}496497/* SKY API */498499void RasterizerSceneGLES3::_free_sky_data(Sky *p_sky) {500if (p_sky->radiance != 0) {501GLES3::Utilities::get_singleton()->texture_free_data(p_sky->radiance);502p_sky->radiance = 0;503GLES3::Utilities::get_singleton()->texture_free_data(p_sky->raw_radiance);504p_sky->raw_radiance = 0;505glDeleteFramebuffers(1, &p_sky->radiance_framebuffer);506p_sky->radiance_framebuffer = 0;507}508}509510RID RasterizerSceneGLES3::sky_allocate() {511return sky_owner.allocate_rid();512}513514void RasterizerSceneGLES3::sky_initialize(RID p_rid) {515sky_owner.initialize_rid(p_rid);516}517518void RasterizerSceneGLES3::sky_set_radiance_size(RID p_sky, int p_radiance_size) {519Sky *sky = sky_owner.get_or_null(p_sky);520ERR_FAIL_NULL(sky);521ERR_FAIL_COND_MSG(p_radiance_size < 32 || p_radiance_size > 2048, "Sky radiance size must be between 32 and 2048");522523if (sky->radiance_size == p_radiance_size) {524return; // No need to update525}526527sky->radiance_size = p_radiance_size;528529_free_sky_data(sky);530_invalidate_sky(sky);531}532533void RasterizerSceneGLES3::sky_set_mode(RID p_sky, RS::SkyMode p_mode) {534Sky *sky = sky_owner.get_or_null(p_sky);535ERR_FAIL_NULL(sky);536537if (sky->mode == p_mode) {538return;539}540541sky->mode = p_mode;542_invalidate_sky(sky);543}544545void RasterizerSceneGLES3::sky_set_material(RID p_sky, RID p_material) {546Sky *sky = sky_owner.get_or_null(p_sky);547ERR_FAIL_NULL(sky);548549if (sky->material == p_material) {550return;551}552553sky->material = p_material;554_invalidate_sky(sky);555}556557float RasterizerSceneGLES3::sky_get_baked_exposure(RID p_sky) const {558Sky *sky = sky_owner.get_or_null(p_sky);559ERR_FAIL_NULL_V(sky, 1.0);560561return sky->baked_exposure;562}563564void RasterizerSceneGLES3::_invalidate_sky(Sky *p_sky) {565if (!p_sky->dirty) {566p_sky->dirty = true;567p_sky->dirty_list = dirty_sky_list;568dirty_sky_list = p_sky;569}570}571572GLuint _init_radiance_texture(int p_size, int p_mipmaps, String p_name) {573GLuint radiance_id = 0;574575glGenTextures(1, &radiance_id);576glBindTexture(GL_TEXTURE_CUBE_MAP, radiance_id);577#ifdef GL_API_ENABLED578if (RasterizerGLES3::is_gles_over_gl()) {579//TODO, on low-end compare this to allocating each face of each mip individually580// see: https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glTexStorage2D.xhtml581for (int i = 0; i < 6; i++) {582glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB10_A2, p_size, p_size, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, nullptr);583}584585glGenerateMipmap(GL_TEXTURE_CUBE_MAP);586}587#endif // GL_API_ENABLED588#ifdef GLES_API_ENABLED589if (!RasterizerGLES3::is_gles_over_gl()) {590glTexStorage2D(GL_TEXTURE_CUBE_MAP, p_mipmaps, GL_RGB10_A2, p_size, p_size);591}592#endif // GLES_API_ENABLED593glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);594glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);595glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);596glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);597glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);598glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, p_mipmaps - 1);599600GLES3::Utilities::get_singleton()->texture_allocated_data(radiance_id, Image::get_image_data_size(p_size, p_size, Image::FORMAT_RGBA8, true), p_name);601return radiance_id;602}603604void RasterizerSceneGLES3::_update_dirty_skys() {605Sky *sky = dirty_sky_list;606607while (sky) {608if (sky->radiance == 0) {609sky->mipmap_count = Image::get_image_required_mipmaps(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBA8) - 1;610// Left uninitialized, will attach a texture at render time611glGenFramebuffers(1, &sky->radiance_framebuffer);612sky->radiance = _init_radiance_texture(sky->radiance_size, sky->mipmap_count, "Sky radiance texture");613sky->raw_radiance = _init_radiance_texture(sky->radiance_size, sky->mipmap_count, "Sky raw radiance texture");614}615616sky->reflection_dirty = true;617sky->processing_layer = 0;618619Sky *next = sky->dirty_list;620sky->dirty_list = nullptr;621sky->dirty = false;622sky = next;623}624625dirty_sky_list = nullptr;626}627628void RasterizerSceneGLES3::_setup_sky(const RenderDataGLES3 *p_render_data, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size) {629GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton();630GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();631ERR_FAIL_COND(p_render_data->environment.is_null());632633GLES3::SkyMaterialData *material = nullptr;634Sky *sky = sky_owner.get_or_null(environment_get_sky(p_render_data->environment));635636RID sky_material;637638GLES3::SkyShaderData *shader_data = nullptr;639640if (sky) {641sky_material = sky->material;642643if (sky_material.is_valid()) {644material = static_cast<GLES3::SkyMaterialData *>(material_storage->material_get_data(sky_material, RS::SHADER_SKY));645if (!material || !material->shader_data->valid) {646material = nullptr;647}648}649}650651if (!material) {652sky_material = sky_globals.default_material;653material = static_cast<GLES3::SkyMaterialData *>(material_storage->material_get_data(sky_material, RS::SHADER_SKY));654}655656ERR_FAIL_NULL(material);657658shader_data = material->shader_data;659660ERR_FAIL_NULL(shader_data);661662if (sky) {663if (shader_data->uses_time && time - sky->prev_time > 0.00001) {664sky->prev_time = time;665sky->reflection_dirty = true;666RenderingServerDefault::redraw_request();667}668669if (material != sky->prev_material) {670sky->prev_material = material;671sky->reflection_dirty = true;672}673674if (material->uniform_set_updated) {675material->uniform_set_updated = false;676sky->reflection_dirty = true;677}678679if (!p_transform.origin.is_equal_approx(sky->prev_position) && shader_data->uses_position) {680sky->prev_position = p_transform.origin;681sky->reflection_dirty = true;682}683}684685glBindBufferBase(GL_UNIFORM_BUFFER, SKY_DIRECTIONAL_LIGHT_UNIFORM_LOCATION, sky_globals.directional_light_buffer);686if (shader_data->uses_light || (environment_get_fog_enabled(p_render_data->environment) && environment_get_fog_sun_scatter(p_render_data->environment) > 0.001)) {687sky_globals.directional_light_count = 0;688for (int i = 0; i < (int)p_lights.size(); i++) {689GLES3::LightInstance *li = GLES3::LightStorage::get_singleton()->get_light_instance(p_lights[i]);690if (!li) {691continue;692}693RID base = li->light;694695ERR_CONTINUE(base.is_null());696697RS::LightType type = light_storage->light_get_type(base);698if (type == RS::LIGHT_DIRECTIONAL && light_storage->light_directional_get_sky_mode(base) != RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_ONLY) {699DirectionalLightData &sky_light_data = sky_globals.directional_lights[sky_globals.directional_light_count];700Transform3D light_transform = li->transform;701Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized();702703sky_light_data.direction[0] = world_direction.x;704sky_light_data.direction[1] = world_direction.y;705sky_light_data.direction[2] = world_direction.z;706707float sign = light_storage->light_is_negative(base) ? -1 : 1;708sky_light_data.energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY);709710if (is_using_physical_light_units()) {711sky_light_data.energy *= light_storage->light_get_param(base, RS::LIGHT_PARAM_INTENSITY);712}713714if (p_render_data->camera_attributes.is_valid()) {715sky_light_data.energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);716}717718Color srgb_col = light_storage->light_get_color(base);719sky_light_data.color[0] = srgb_col.r;720sky_light_data.color[1] = srgb_col.g;721sky_light_data.color[2] = srgb_col.b;722723sky_light_data.enabled = true;724725float angular_diameter = light_storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);726sky_light_data.size = Math::deg_to_rad(angular_diameter);727sky_globals.directional_light_count++;728if (sky_globals.directional_light_count >= sky_globals.max_directional_lights) {729break;730}731}732}733// Check whether the directional_light_buffer changes734bool light_data_dirty = false;735736// Light buffer is dirty if we have fewer or more lights737// If we have fewer lights, make sure that old lights are disabled738if (sky_globals.directional_light_count != sky_globals.last_frame_directional_light_count) {739light_data_dirty = true;740for (uint32_t i = sky_globals.directional_light_count; i < sky_globals.max_directional_lights; i++) {741sky_globals.directional_lights[i].enabled = false;742sky_globals.last_frame_directional_lights[i].enabled = false;743}744}745746if (!light_data_dirty) {747for (uint32_t i = 0; i < sky_globals.directional_light_count; i++) {748if (sky_globals.directional_lights[i].direction[0] != sky_globals.last_frame_directional_lights[i].direction[0] ||749sky_globals.directional_lights[i].direction[1] != sky_globals.last_frame_directional_lights[i].direction[1] ||750sky_globals.directional_lights[i].direction[2] != sky_globals.last_frame_directional_lights[i].direction[2] ||751sky_globals.directional_lights[i].energy != sky_globals.last_frame_directional_lights[i].energy ||752sky_globals.directional_lights[i].color[0] != sky_globals.last_frame_directional_lights[i].color[0] ||753sky_globals.directional_lights[i].color[1] != sky_globals.last_frame_directional_lights[i].color[1] ||754sky_globals.directional_lights[i].color[2] != sky_globals.last_frame_directional_lights[i].color[2] ||755sky_globals.directional_lights[i].enabled != sky_globals.last_frame_directional_lights[i].enabled ||756sky_globals.directional_lights[i].size != sky_globals.last_frame_directional_lights[i].size) {757light_data_dirty = true;758break;759}760}761}762763if (light_data_dirty) {764glBufferData(GL_UNIFORM_BUFFER, sizeof(DirectionalLightData) * sky_globals.max_directional_lights, sky_globals.directional_lights, GL_STREAM_DRAW);765glBindBuffer(GL_UNIFORM_BUFFER, 0);766767DirectionalLightData *temp = sky_globals.last_frame_directional_lights;768sky_globals.last_frame_directional_lights = sky_globals.directional_lights;769sky_globals.directional_lights = temp;770sky_globals.last_frame_directional_light_count = sky_globals.directional_light_count;771if (sky) {772sky->reflection_dirty = true;773}774}775}776777if (p_render_data->view_count > 1) {778glBindBufferBase(GL_UNIFORM_BUFFER, SKY_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);779glBindBuffer(GL_UNIFORM_BUFFER, 0);780}781782if (sky && !sky->radiance) {783_invalidate_sky(sky);784_update_dirty_skys();785}786}787788void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_sky_energy_multiplier, float p_luminance_multiplier, bool p_use_multiview, bool p_flip_y, bool p_apply_color_adjustments_in_post) {789GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();790ERR_FAIL_COND(p_env.is_null());791792Sky *sky = sky_owner.get_or_null(environment_get_sky(p_env));793794GLES3::SkyMaterialData *material_data = nullptr;795RID sky_material;796797uint64_t spec_constants = p_use_multiview ? SkyShaderGLES3::USE_MULTIVIEW : 0;798if (p_flip_y) {799spec_constants |= SkyShaderGLES3::USE_INVERTED_Y;800}801if (!p_apply_color_adjustments_in_post) {802spec_constants |= SkyShaderGLES3::APPLY_TONEMAPPING;803}804805RS::EnvironmentBG background = environment_get_background(p_env);806807if (sky) {808sky_material = sky->material;809810if (sky_material.is_valid()) {811material_data = static_cast<GLES3::SkyMaterialData *>(material_storage->material_get_data(sky_material, RS::SHADER_SKY));812if (!material_data || !material_data->shader_data->valid) {813material_data = nullptr;814}815}816817if (!material_data) {818sky_material = sky_globals.default_material;819material_data = static_cast<GLES3::SkyMaterialData *>(material_storage->material_get_data(sky_material, RS::SHADER_SKY));820}821} else if (background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) {822sky_material = sky_globals.fog_material;823material_data = static_cast<GLES3::SkyMaterialData *>(material_storage->material_get_data(sky_material, RS::SHADER_SKY));824}825826ERR_FAIL_NULL(material_data);827material_data->bind_uniforms();828829GLES3::SkyShaderData *shader_data = material_data->shader_data;830831ERR_FAIL_NULL(shader_data);832833// Camera834Projection camera;835836if (environment_get_sky_custom_fov(p_env)) {837float near_plane = p_projection.get_z_near();838float far_plane = p_projection.get_z_far();839float aspect = p_projection.get_aspect();840841camera.set_perspective(environment_get_sky_custom_fov(p_env), aspect, near_plane, far_plane);842} else {843camera = p_projection;844}845846Projection correction;847correction.set_depth_correction(false, true, false);848camera = correction * camera;849850Basis sky_transform = environment_get_sky_orientation(p_env);851sky_transform.invert();852sky_transform = sky_transform * p_transform.basis;853854bool success = material_storage->shaders.sky_shader.version_bind_shader(shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);855if (!success) {856return;857}858859material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::ORIENTATION, sky_transform, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);860material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::PROJECTION, camera.columns[2][0], camera.columns[0][0], camera.columns[2][1], camera.columns[1][1], shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);861material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::POSITION, p_transform.origin, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);862material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::TIME, time, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);863material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::SKY_ENERGY_MULTIPLIER, p_sky_energy_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);864material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, p_luminance_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);865866Color fog_color = environment_get_fog_light_color(p_env).srgb_to_linear() * environment_get_fog_light_energy(p_env);867material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_ENABLED, environment_get_fog_enabled(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);868material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_AERIAL_PERSPECTIVE, environment_get_fog_aerial_perspective(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);869material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_LIGHT_COLOR, fog_color, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);870material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_SUN_SCATTER, environment_get_fog_sun_scatter(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);871material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_DENSITY, environment_get_fog_density(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);872material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_SKY_AFFECT, environment_get_fog_sky_affect(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);873material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::DIRECTIONAL_LIGHT_COUNT, sky_globals.directional_light_count, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);874875if (p_use_multiview) {876glBindBufferBase(GL_UNIFORM_BUFFER, SKY_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);877glBindBuffer(GL_UNIFORM_BUFFER, 0);878}879880glBindVertexArray(sky_globals.screen_triangle_array);881glDrawArrays(GL_TRIANGLES, 0, 3);882}883884void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_sky_energy_multiplier) {885GLES3::CubemapFilter *cubemap_filter = GLES3::CubemapFilter::get_singleton();886GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();887ERR_FAIL_COND(p_env.is_null());888889Sky *sky = sky_owner.get_or_null(environment_get_sky(p_env));890ERR_FAIL_NULL(sky);891892GLES3::SkyMaterialData *material_data = nullptr;893RID sky_material;894895RS::EnvironmentBG background = environment_get_background(p_env);896897if (sky) {898ERR_FAIL_NULL(sky);899sky_material = sky->material;900901if (sky_material.is_valid()) {902material_data = static_cast<GLES3::SkyMaterialData *>(material_storage->material_get_data(sky_material, RS::SHADER_SKY));903if (!material_data || !material_data->shader_data->valid) {904material_data = nullptr;905}906}907908if (!material_data) {909sky_material = sky_globals.default_material;910material_data = static_cast<GLES3::SkyMaterialData *>(material_storage->material_get_data(sky_material, RS::SHADER_SKY));911}912} else if (background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) {913sky_material = sky_globals.fog_material;914material_data = static_cast<GLES3::SkyMaterialData *>(material_storage->material_get_data(sky_material, RS::SHADER_SKY));915}916917ERR_FAIL_NULL(material_data);918material_data->bind_uniforms();919920GLES3::SkyShaderData *shader_data = material_data->shader_data;921922ERR_FAIL_NULL(shader_data);923924bool update_single_frame = sky->mode == RS::SKY_MODE_REALTIME || sky->mode == RS::SKY_MODE_QUALITY;925RS::SkyMode sky_mode = sky->mode;926927if (sky_mode == RS::SKY_MODE_AUTOMATIC) {928if ((shader_data->uses_time || shader_data->uses_position) && sky->radiance_size == 256) {929update_single_frame = true;930sky_mode = RS::SKY_MODE_REALTIME;931} else if (shader_data->uses_light || shader_data->ubo_size > 0) {932update_single_frame = false;933sky_mode = RS::SKY_MODE_INCREMENTAL;934} else {935update_single_frame = true;936sky_mode = RS::SKY_MODE_QUALITY;937}938}939940if (sky->processing_layer == 0 && sky_mode == RS::SKY_MODE_INCREMENTAL) {941// On the first frame after creating sky, rebuild in single frame942update_single_frame = true;943sky_mode = RS::SKY_MODE_QUALITY;944}945946int max_processing_layer = sky->mipmap_count;947948// Update radiance cubemap949if (sky->reflection_dirty && (sky->processing_layer >= max_processing_layer || update_single_frame)) {950static const Vector3 view_normals[6] = {951Vector3(+1, 0, 0),952Vector3(-1, 0, 0),953Vector3(0, +1, 0),954Vector3(0, -1, 0),955Vector3(0, 0, +1),956Vector3(0, 0, -1)957};958static const Vector3 view_up[6] = {959Vector3(0, -1, 0),960Vector3(0, -1, 0),961Vector3(0, 0, +1),962Vector3(0, 0, -1),963Vector3(0, -1, 0),964Vector3(0, -1, 0)965};966967Projection cm;968cm.set_perspective(90, 1, 0.01, 10.0);969Projection correction;970correction.set_depth_correction(true, true, false);971cm = correction * cm;972973bool success = material_storage->shaders.sky_shader.version_bind_shader(shader_data->version, SkyShaderGLES3::MODE_CUBEMAP);974if (!success) {975return;976}977978material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::POSITION, p_transform.origin, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP);979material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::TIME, time, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP);980material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::PROJECTION, cm.columns[2][0], cm.columns[0][0], cm.columns[2][1], cm.columns[1][1], shader_data->version, SkyShaderGLES3::MODE_CUBEMAP);981material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::SKY_ENERGY_MULTIPLIER, p_sky_energy_multiplier, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP);982material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, 1.0, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP);983984glBindVertexArray(sky_globals.screen_triangle_array);985986glViewport(0, 0, sky->radiance_size, sky->radiance_size);987glBindFramebuffer(GL_FRAMEBUFFER, sky->radiance_framebuffer);988989scene_state.reset_gl_state();990scene_state.set_gl_cull_mode(RS::CULL_MODE_DISABLED);991scene_state.enable_gl_blend(false);992993for (int i = 0; i < 6; i++) {994Basis local_view = Basis::looking_at(view_normals[i], view_up[i]);995material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::ORIENTATION, local_view, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP);996glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, sky->raw_radiance, 0);997glDrawArrays(GL_TRIANGLES, 0, 3);998}9991000if (update_single_frame) {1001for (int i = 0; i < max_processing_layer; i++) {1002cubemap_filter->filter_radiance(sky->raw_radiance, sky->radiance, sky->radiance_framebuffer, sky->radiance_size, sky->mipmap_count, i);1003}1004} else {1005cubemap_filter->filter_radiance(sky->raw_radiance, sky->radiance, sky->radiance_framebuffer, sky->radiance_size, sky->mipmap_count, 0); // Just copy over the first mipmap.1006}1007sky->processing_layer = 1;1008sky->baked_exposure = p_sky_energy_multiplier;1009sky->reflection_dirty = false;1010} else {1011if (sky_mode == RS::SKY_MODE_INCREMENTAL && sky->processing_layer < max_processing_layer) {1012scene_state.reset_gl_state();1013scene_state.set_gl_cull_mode(RS::CULL_MODE_DISABLED);1014scene_state.enable_gl_blend(false);10151016cubemap_filter->filter_radiance(sky->raw_radiance, sky->radiance, sky->radiance_framebuffer, sky->radiance_size, sky->mipmap_count, sky->processing_layer);1017sky->processing_layer++;1018}1019}1020glViewport(0, 0, sky->screen_size.x, sky->screen_size.y);1021}10221023Ref<Image> RasterizerSceneGLES3::sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) {1024Sky *sky = sky_owner.get_or_null(p_sky);1025ERR_FAIL_NULL_V(sky, Ref<Image>());10261027_update_dirty_skys();10281029if (sky->radiance == 0) {1030return Ref<Image>();1031}10321033GLES3::CopyEffects *copy_effects = GLES3::CopyEffects::get_singleton();1034GLES3::Config *config = GLES3::Config::get_singleton();10351036GLuint rad_tex = 0;1037glGenTextures(1, &rad_tex);1038glBindTexture(GL_TEXTURE_2D, rad_tex);1039if (config->float_texture_supported) {1040glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, p_size.width, p_size.height, 0, GL_RGBA, GL_FLOAT, nullptr);1041GLES3::Utilities::get_singleton()->texture_allocated_data(rad_tex, p_size.width * p_size.height * 16, "Temp sky panorama");1042} else {1043// Fallback to RGBA8 on devices that don't support rendering to floating point textures. This will look bad, but we have no choice.1044glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, p_size.width, p_size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);1045GLES3::Utilities::get_singleton()->texture_allocated_data(rad_tex, p_size.width * p_size.height * 4, "Temp sky panorama");1046}10471048GLuint rad_fbo = 0;1049glGenFramebuffers(1, &rad_fbo);1050glBindFramebuffer(GL_FRAMEBUFFER, rad_fbo);1051glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rad_tex, 0);1052glActiveTexture(GL_TEXTURE0);1053glBindTexture(GL_TEXTURE_CUBE_MAP, sky->radiance);1054glViewport(0, 0, p_size.width, p_size.height);10551056glClearColor(0.0, 0.0, 0.0, 1.0);1057glClear(GL_COLOR_BUFFER_BIT);10581059copy_effects->copy_cube_to_panorama(p_bake_irradiance ? float(sky->mipmap_count) : 0.0);10601061glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);1062glDeleteFramebuffers(1, &rad_fbo);1063// Create a dummy texture so we can use texture_2d_get.1064RID tex_rid = GLES3::TextureStorage::get_singleton()->texture_allocate();1065{1066GLES3::Texture texture;1067texture.width = p_size.width;1068texture.height = p_size.height;1069texture.alloc_width = p_size.width;1070texture.alloc_height = p_size.height;1071texture.format = Image::FORMAT_RGBAF;1072texture.real_format = Image::FORMAT_RGBAF;1073texture.gl_format_cache = GL_RGBA;1074texture.gl_type_cache = GL_FLOAT;1075texture.type = GLES3::Texture::TYPE_2D;1076texture.target = GL_TEXTURE_2D;1077texture.active = true;1078texture.tex_id = rad_tex;1079texture.is_render_target = true; // HACK: Prevent TextureStorage from retaining a cached copy of the texture.1080GLES3::TextureStorage::get_singleton()->texture_2d_initialize_from_texture(tex_rid, texture);1081}10821083Ref<Image> img = GLES3::TextureStorage::get_singleton()->texture_2d_get(tex_rid);1084GLES3::Utilities::get_singleton()->texture_free_data(rad_tex);10851086GLES3::Texture &texture = *GLES3::TextureStorage::get_singleton()->get_texture(tex_rid);1087texture.is_render_target = false; // HACK: Avoid an error when freeing the texture.1088texture.tex_id = 0;1089GLES3::TextureStorage::get_singleton()->texture_free(tex_rid);10901091for (int i = 0; i < p_size.width; i++) {1092for (int j = 0; j < p_size.height; j++) {1093Color c = img->get_pixel(i, j);1094c.r *= p_energy;1095c.g *= p_energy;1096c.b *= p_energy;1097img->set_pixel(i, j, c);1098}1099}1100return img;1101}11021103/* ENVIRONMENT API */11041105void RasterizerSceneGLES3::environment_glow_set_use_bicubic_upscale(bool p_enable) {1106glow_bicubic_upscale = p_enable;1107}11081109void RasterizerSceneGLES3::environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) {1110}11111112void RasterizerSceneGLES3::environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) {1113}11141115void RasterizerSceneGLES3::environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) {1116}11171118void RasterizerSceneGLES3::environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) {1119}11201121void RasterizerSceneGLES3::environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) {1122}11231124void RasterizerSceneGLES3::environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) {1125}11261127void RasterizerSceneGLES3::environment_set_volumetric_fog_volume_size(int p_size, int p_depth) {1128}11291130void RasterizerSceneGLES3::environment_set_volumetric_fog_filter_active(bool p_enable) {1131}11321133Ref<Image> RasterizerSceneGLES3::environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) {1134ERR_FAIL_COND_V(p_env.is_null(), Ref<Image>());11351136RS::EnvironmentBG environment_background = environment_get_background(p_env);11371138if (environment_background == RS::ENV_BG_CAMERA_FEED || environment_background == RS::ENV_BG_CANVAS || environment_background == RS::ENV_BG_KEEP) {1139return Ref<Image>(); // Nothing to bake.1140}11411142RS::EnvironmentAmbientSource ambient_source = environment_get_ambient_source(p_env);11431144bool use_ambient_light = false;1145bool use_cube_map = false;1146if (ambient_source == RS::ENV_AMBIENT_SOURCE_BG && (environment_background == RS::ENV_BG_CLEAR_COLOR || environment_background == RS::ENV_BG_COLOR)) {1147use_ambient_light = true;1148} else {1149use_cube_map = (ambient_source == RS::ENV_AMBIENT_SOURCE_BG && environment_background == RS::ENV_BG_SKY) || ambient_source == RS::ENV_AMBIENT_SOURCE_SKY;1150use_ambient_light = use_cube_map || ambient_source == RS::ENV_AMBIENT_SOURCE_COLOR;1151}11521153use_cube_map = use_cube_map || (environment_background == RS::ENV_BG_SKY && environment_get_sky(p_env).is_valid());11541155Color ambient_color;1156float ambient_color_sky_mix = 0.0;1157if (use_ambient_light) {1158ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_env);1159const float ambient_energy = environment_get_ambient_light_energy(p_env);1160ambient_color = environment_get_ambient_light(p_env);1161ambient_color = ambient_color.srgb_to_linear();1162ambient_color.r *= ambient_energy;1163ambient_color.g *= ambient_energy;1164ambient_color.b *= ambient_energy;1165}11661167if (use_cube_map) {1168Ref<Image> panorama = sky_bake_panorama(environment_get_sky(p_env), environment_get_bg_energy_multiplier(p_env), p_bake_irradiance, p_size);1169if (use_ambient_light) {1170for (int x = 0; x < p_size.width; x++) {1171for (int y = 0; y < p_size.height; y++) {1172panorama->set_pixel(x, y, ambient_color.lerp(panorama->get_pixel(x, y), ambient_color_sky_mix));1173}1174}1175}1176return panorama;1177} else {1178const float bg_energy_multiplier = environment_get_bg_energy_multiplier(p_env);1179Color panorama_color = ((environment_background == RS::ENV_BG_CLEAR_COLOR) ? RSG::texture_storage->get_default_clear_color() : environment_get_bg_color(p_env));1180panorama_color = panorama_color.srgb_to_linear();1181panorama_color.r *= bg_energy_multiplier;1182panorama_color.g *= bg_energy_multiplier;1183panorama_color.b *= bg_energy_multiplier;11841185if (use_ambient_light) {1186panorama_color = ambient_color.lerp(panorama_color, ambient_color_sky_mix);1187}11881189Ref<Image> panorama = Image::create_empty(p_size.width, p_size.height, false, Image::FORMAT_RGBAF);1190panorama->fill(panorama_color);1191return panorama;1192}1193}11941195void RasterizerSceneGLES3::positional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) {1196scene_state.positional_shadow_quality = p_quality;1197}11981199void RasterizerSceneGLES3::directional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) {1200scene_state.directional_shadow_quality = p_quality;1201}12021203RID RasterizerSceneGLES3::fog_volume_instance_create(RID p_fog_volume) {1204return RID();1205}12061207void RasterizerSceneGLES3::fog_volume_instance_set_transform(RID p_fog_volume_instance, const Transform3D &p_transform) {1208}12091210void RasterizerSceneGLES3::fog_volume_instance_set_active(RID p_fog_volume_instance, bool p_active) {1211}12121213RID RasterizerSceneGLES3::fog_volume_instance_get_volume(RID p_fog_volume_instance) const {1214return RID();1215}12161217Vector3 RasterizerSceneGLES3::fog_volume_instance_get_position(RID p_fog_volume_instance) const {1218return Vector3();1219}12201221RID RasterizerSceneGLES3::voxel_gi_instance_create(RID p_voxel_gi) {1222return RID();1223}12241225void RasterizerSceneGLES3::voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) {1226}12271228bool RasterizerSceneGLES3::voxel_gi_needs_update(RID p_probe) const {1229return false;1230}12311232void RasterizerSceneGLES3::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) {1233}12341235void RasterizerSceneGLES3::voxel_gi_set_quality(RS::VoxelGIQuality) {1236}12371238_FORCE_INLINE_ static uint32_t _indices_to_primitives(RS::PrimitiveType p_primitive, uint32_t p_indices) {1239static const uint32_t divisor[RS::PRIMITIVE_MAX] = { 1, 2, 1, 3, 1 };1240static const uint32_t subtractor[RS::PRIMITIVE_MAX] = { 0, 0, 1, 0, 2 };1241return (p_indices - subtractor[p_primitive]) / divisor[p_primitive];1242}1243void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const RenderDataGLES3 *p_render_data, PassMode p_pass_mode, bool p_append) {1244GLES3::MeshStorage *mesh_storage = GLES3::MeshStorage::get_singleton();1245GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton();12461247if (p_render_list == RENDER_LIST_OPAQUE) {1248scene_state.used_screen_texture = false;1249scene_state.used_normal_texture = false;1250scene_state.used_depth_texture = false;1251scene_state.used_opaque_stencil = false;1252}12531254Plane near_plane;1255if (p_render_data->cam_orthogonal) {1256near_plane = Plane(-p_render_data->cam_transform.basis.get_column(Vector3::AXIS_Z), p_render_data->cam_transform.origin);1257near_plane.d += p_render_data->cam_projection.get_z_near();1258}1259float z_max = p_render_data->cam_projection.get_z_far() - p_render_data->cam_projection.get_z_near();12601261RenderList *rl = &render_list[p_render_list];12621263// Parse any updates on our geometry, updates surface caches and such1264_update_dirty_geometry_instances();12651266if (!p_append) {1267rl->clear();1268if (p_render_list == RENDER_LIST_OPAQUE) {1269render_list[RENDER_LIST_ALPHA].clear(); //opaque fills alpha too1270}1271}12721273//fill list12741275for (int i = 0; i < (int)p_render_data->instances->size(); i++) {1276GeometryInstanceGLES3 *inst = static_cast<GeometryInstanceGLES3 *>((*p_render_data->instances)[i]);12771278Vector3 center = inst->transform.origin;1279if (p_render_data->cam_orthogonal) {1280if (inst->use_aabb_center) {1281center = inst->transformed_aabb.get_support(-near_plane.normal);1282}1283inst->depth = near_plane.distance_to(center) - inst->sorting_offset;1284} else {1285if (inst->use_aabb_center) {1286center = inst->transformed_aabb.position + (inst->transformed_aabb.size * 0.5);1287}1288inst->depth = p_render_data->cam_transform.origin.distance_to(center) - inst->sorting_offset;1289}1290uint32_t depth_layer = CLAMP(int(inst->depth * 16 / z_max), 0, 15);12911292uint32_t flags = inst->base_flags; //fill flags if appropriate12931294if (inst->non_uniform_scale) {1295flags |= INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE;1296}12971298// Sets the index values for lookup in the shader1299// This has to be done after _setup_lights was called this frame13001301if (p_pass_mode == PASS_MODE_COLOR) {1302inst->light_passes.clear();1303inst->spot_light_gl_cache.clear();1304inst->omni_light_gl_cache.clear();1305inst->reflection_probes_local_transform_cache.clear();1306inst->reflection_probe_rid_cache.clear();1307uint64_t current_frame = RSG::rasterizer->get_frame_number();13081309if (inst->paired_omni_light_count) {1310for (uint32_t j = 0; j < inst->paired_omni_light_count; j++) {1311RID light_instance = inst->paired_omni_lights[j];1312if (light_storage->light_instance_get_render_pass(light_instance) != current_frame) {1313continue;1314}1315RID light = light_storage->light_instance_get_base_light(light_instance);1316int32_t shadow_id = light_storage->light_instance_get_shadow_id(light_instance);13171318if (light_storage->light_has_shadow(light) && shadow_id >= 0) {1319GeometryInstanceGLES3::LightPass pass;1320pass.light_id = light_storage->light_instance_get_gl_id(light_instance);1321pass.shadow_id = shadow_id;1322pass.light_instance_rid = light_instance;1323pass.is_omni = true;1324inst->light_passes.push_back(pass);1325} else {1326// Lights without shadow can all go in base pass.1327inst->omni_light_gl_cache.push_back((uint32_t)light_storage->light_instance_get_gl_id(light_instance));1328}1329}1330}13311332if (inst->paired_spot_light_count) {1333for (uint32_t j = 0; j < inst->paired_spot_light_count; j++) {1334RID light_instance = inst->paired_spot_lights[j];1335if (light_storage->light_instance_get_render_pass(light_instance) != current_frame) {1336continue;1337}1338RID light = light_storage->light_instance_get_base_light(light_instance);1339int32_t shadow_id = light_storage->light_instance_get_shadow_id(light_instance);13401341if (light_storage->light_has_shadow(light) && shadow_id >= 0) {1342GeometryInstanceGLES3::LightPass pass;1343pass.light_id = light_storage->light_instance_get_gl_id(light_instance);1344pass.shadow_id = shadow_id;1345pass.light_instance_rid = light_instance;1346inst->light_passes.push_back(pass);1347} else {1348// Lights without shadow can all go in base pass.1349inst->spot_light_gl_cache.push_back((uint32_t)light_storage->light_instance_get_gl_id(light_instance));1350}1351}1352}13531354if (p_render_data->reflection_probe.is_null() && inst->paired_reflection_probes.size() > 0) {1355// Do not include if we're rendering reflection probes.1356// We only support two probes for now and we handle them first come, first serve.1357// This should be improved one day, at minimum the list should be sorted by priority.13581359for (uint32_t pi = 0; pi < inst->paired_reflection_probes.size(); pi++) {1360RID probe_instance = inst->paired_reflection_probes[pi];1361RID atlas = light_storage->reflection_probe_instance_get_atlas(probe_instance);1362RID probe = light_storage->reflection_probe_instance_get_probe(probe_instance);1363uint32_t reflection_mask = light_storage->reflection_probe_get_reflection_mask(probe);1364if (atlas.is_valid() && (inst->layer_mask & reflection_mask)) {1365Transform3D local_matrix = p_render_data->inv_cam_transform * light_storage->reflection_probe_instance_get_transform(probe_instance);1366inst->reflection_probes_local_transform_cache.push_back(local_matrix.affine_inverse());1367inst->reflection_probe_rid_cache.push_back(probe_instance);1368}1369}1370}1371}13721373inst->flags_cache = flags;13741375GeometryInstanceSurface *surf = inst->surface_caches;13761377float lod_distance = 0.0;13781379if (p_render_data->cam_orthogonal) {1380lod_distance = 1.0;1381} else {1382Vector3 aabb_min = inst->transformed_aabb.position;1383Vector3 aabb_max = inst->transformed_aabb.position + inst->transformed_aabb.size;1384Vector3 camera_position = p_render_data->main_cam_transform.origin;1385Vector3 surface_distance = Vector3(0.0, 0.0, 0.0).max(aabb_min - camera_position).max(camera_position - aabb_max);13861387lod_distance = surface_distance.length();1388}13891390while (surf) {1391// LOD13921393if (p_render_data->screen_mesh_lod_threshold > 0.0 && mesh_storage->mesh_surface_has_lod(surf->surface)) {1394uint32_t indices = 0;1395surf->lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, lod_distance * p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, indices);1396surf->index_count = indices;13971398if (p_render_data->render_info) {1399indices = _indices_to_primitives(surf->primitive, indices);1400if (p_render_list == RENDER_LIST_OPAQUE) { //opaque1401p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += indices;1402} else if (p_render_list == RENDER_LIST_SECONDARY) { //shadow1403p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += indices;1404}1405}14061407} else {1408surf->lod_index = 0;14091410if (p_render_data->render_info) {1411uint32_t to_draw = mesh_storage->mesh_surface_get_vertices_drawn_count(surf->surface);1412to_draw = _indices_to_primitives(surf->primitive, to_draw);1413to_draw *= inst->instance_count > 0 ? inst->instance_count : 1;1414if (p_render_list == RENDER_LIST_OPAQUE) { //opaque1415p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += to_draw;1416} else if (p_render_list == RENDER_LIST_SECONDARY) { //shadow1417p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += to_draw;1418}1419}1420}14211422// ADD Element1423if (p_pass_mode == PASS_MODE_COLOR) {1424#ifdef DEBUG_ENABLED1425bool force_alpha = unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW);1426#else1427bool force_alpha = false;1428#endif1429if (!force_alpha && (surf->flags & (GeometryInstanceSurface::FLAG_PASS_DEPTH | GeometryInstanceSurface::FLAG_PASS_OPAQUE))) {1430rl->add_element(surf);1431}1432if (force_alpha || (surf->flags & GeometryInstanceSurface::FLAG_PASS_ALPHA)) {1433render_list[RENDER_LIST_ALPHA].add_element(surf);1434}14351436if (surf->flags & GeometryInstanceSurface::FLAG_USES_SCREEN_TEXTURE) {1437scene_state.used_screen_texture = true;1438}1439if (surf->flags & GeometryInstanceSurface::FLAG_USES_NORMAL_TEXTURE) {1440scene_state.used_normal_texture = true;1441}1442if (surf->flags & GeometryInstanceSurface::FLAG_USES_DEPTH_TEXTURE) {1443scene_state.used_depth_texture = true;1444}1445if ((surf->flags & GeometryInstanceSurface::FLAG_USES_STENCIL) && !force_alpha && (surf->flags & (GeometryInstanceSurface::FLAG_PASS_DEPTH | GeometryInstanceSurface::FLAG_PASS_OPAQUE))) {1446scene_state.used_opaque_stencil = true;1447}14481449} else if (p_pass_mode == PASS_MODE_SHADOW) {1450if (surf->flags & GeometryInstanceSurface::FLAG_PASS_SHADOW) {1451rl->add_element(surf);1452}1453} else if (p_pass_mode == PASS_MODE_MATERIAL) {1454if (surf->flags & (GeometryInstanceSurface::FLAG_PASS_DEPTH | GeometryInstanceSurface::FLAG_PASS_OPAQUE | GeometryInstanceSurface::FLAG_PASS_ALPHA)) {1455rl->add_element(surf);1456}1457} else {1458if (surf->flags & (GeometryInstanceSurface::FLAG_PASS_DEPTH | GeometryInstanceSurface::FLAG_PASS_OPAQUE)) {1459rl->add_element(surf);1460}1461}14621463surf->sort.depth_layer = depth_layer;1464surf->finished_base_pass = false;1465surf->light_pass_index = 0;14661467surf = surf->next;1468}1469}1470}14711472// Needs to be called after _setup_lights so that directional_light_count is accurate.1473void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_pancake_shadows, float p_shadow_bias) {1474Projection correction;1475correction.set_depth_correction(p_flip_y, true, false);1476Projection projection = correction * p_render_data->cam_projection;1477//store camera into ubo1478GLES3::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix);1479GLES3::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix);1480GLES3::MaterialStorage::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix);1481GLES3::MaterialStorage::store_transform(p_render_data->inv_cam_transform, scene_state.ubo.view_matrix);1482GLES3::MaterialStorage::store_transform(p_render_data->main_cam_transform, scene_state.ubo.main_cam_inv_view_matrix);1483scene_state.ubo.camera_visible_layers = p_render_data->camera_visible_layers;14841485if (p_render_data->view_count > 1) {1486for (uint32_t v = 0; v < p_render_data->view_count; v++) {1487projection = correction * p_render_data->view_projection[v];1488GLES3::MaterialStorage::store_camera(projection, scene_state.multiview_ubo.projection_matrix_view[v]);1489GLES3::MaterialStorage::store_camera(projection.inverse(), scene_state.multiview_ubo.inv_projection_matrix_view[v]);14901491scene_state.multiview_ubo.eye_offset[v][0] = p_render_data->view_eye_offset[v].x;1492scene_state.multiview_ubo.eye_offset[v][1] = p_render_data->view_eye_offset[v].y;1493scene_state.multiview_ubo.eye_offset[v][2] = p_render_data->view_eye_offset[v].z;1494scene_state.multiview_ubo.eye_offset[v][3] = 0.0;1495}1496}14971498// Only render the lights without shadows in the base pass.1499scene_state.ubo.directional_light_count = p_render_data->directional_light_count - p_render_data->directional_shadow_count;15001501scene_state.ubo.z_far = p_render_data->z_far;1502scene_state.ubo.z_near = p_render_data->z_near;15031504scene_state.ubo.viewport_size[0] = p_screen_size.x;1505scene_state.ubo.viewport_size[1] = p_screen_size.y;15061507Size2 screen_pixel_size = Vector2(1.0, 1.0) / Size2(p_screen_size);1508scene_state.ubo.screen_pixel_size[0] = screen_pixel_size.x;1509scene_state.ubo.screen_pixel_size[1] = screen_pixel_size.y;15101511scene_state.ubo.luminance_multiplier = p_render_data->luminance_multiplier;15121513scene_state.ubo.shadow_bias = p_shadow_bias;1514scene_state.ubo.pancake_shadows = p_pancake_shadows;15151516//time global variables1517scene_state.ubo.time = time;15181519if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {1520scene_state.ubo.use_ambient_light = true;1521scene_state.ubo.ambient_light_color_energy[0] = 1;1522scene_state.ubo.ambient_light_color_energy[1] = 1;1523scene_state.ubo.ambient_light_color_energy[2] = 1;1524scene_state.ubo.ambient_light_color_energy[3] = 1.0;1525scene_state.ubo.use_ambient_cubemap = false;1526scene_state.ubo.use_reflection_cubemap = false;1527} else if (is_environment(p_render_data->environment)) {1528RS::EnvironmentBG env_bg = environment_get_background(p_render_data->environment);1529RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_render_data->environment);15301531float bg_energy_multiplier = environment_get_bg_energy_multiplier(p_render_data->environment);15321533scene_state.ubo.ambient_light_color_energy[3] = bg_energy_multiplier;15341535scene_state.ubo.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_render_data->environment);15361537//ambient1538if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) {1539Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_render_data->environment);1540color = color.srgb_to_linear();15411542scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy_multiplier;1543scene_state.ubo.ambient_light_color_energy[1] = color.g * bg_energy_multiplier;1544scene_state.ubo.ambient_light_color_energy[2] = color.b * bg_energy_multiplier;1545scene_state.ubo.use_ambient_light = true;1546scene_state.ubo.use_ambient_cubemap = false;1547} else {1548float energy = environment_get_ambient_light_energy(p_render_data->environment);1549Color color = environment_get_ambient_light(p_render_data->environment);1550color = color.srgb_to_linear();1551scene_state.ubo.ambient_light_color_energy[0] = color.r * energy;1552scene_state.ubo.ambient_light_color_energy[1] = color.g * energy;1553scene_state.ubo.ambient_light_color_energy[2] = color.b * energy;15541555Basis sky_transform = environment_get_sky_orientation(p_render_data->environment);1556sky_transform = sky_transform.inverse() * p_render_data->cam_transform.basis;1557GLES3::MaterialStorage::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform);1558scene_state.ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY;1559scene_state.ubo.use_ambient_light = scene_state.ubo.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR;1560}15611562//specular1563RS::EnvironmentReflectionSource ref_src = environment_get_reflection_source(p_render_data->environment);1564if ((ref_src == RS::ENV_REFLECTION_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ref_src == RS::ENV_REFLECTION_SOURCE_SKY) {1565scene_state.ubo.use_reflection_cubemap = true;1566} else {1567scene_state.ubo.use_reflection_cubemap = false;1568}15691570scene_state.ubo.fog_enabled = environment_get_fog_enabled(p_render_data->environment);1571scene_state.ubo.fog_mode = environment_get_fog_mode(p_render_data->environment);1572scene_state.ubo.fog_density = environment_get_fog_density(p_render_data->environment);1573scene_state.ubo.fog_height = environment_get_fog_height(p_render_data->environment);1574scene_state.ubo.fog_depth_curve = environment_get_fog_depth_curve(p_render_data->environment);1575scene_state.ubo.fog_depth_end = environment_get_fog_depth_end(p_render_data->environment) > 0.0 ? environment_get_fog_depth_end(p_render_data->environment) : scene_state.ubo.z_far;1576scene_state.ubo.fog_depth_begin = MIN(environment_get_fog_depth_begin(p_render_data->environment), scene_state.ubo.fog_depth_end - 0.001);1577scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment);1578scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment);15791580Color fog_color = environment_get_fog_light_color(p_render_data->environment).srgb_to_linear();1581float fog_energy = environment_get_fog_light_energy(p_render_data->environment);15821583scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy;1584scene_state.ubo.fog_light_color[1] = fog_color.g * fog_energy;1585scene_state.ubo.fog_light_color[2] = fog_color.b * fog_energy;15861587scene_state.ubo.fog_sun_scatter = environment_get_fog_sun_scatter(p_render_data->environment);15881589} else {1590}15911592if (p_render_data->camera_attributes.is_valid()) {1593scene_state.ubo.emissive_exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);1594scene_state.ubo.IBL_exposure_normalization = 1.0;1595if (is_environment(p_render_data->environment)) {1596RID sky_rid = environment_get_sky(p_render_data->environment);1597if (sky_rid.is_valid()) {1598float current_exposure = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes) * environment_get_bg_intensity(p_render_data->environment);1599scene_state.ubo.IBL_exposure_normalization = current_exposure / MAX(0.001, sky_get_baked_exposure(sky_rid));1600}1601}1602} else if (scene_state.ubo.emissive_exposure_normalization > 0.0) {1603// This branch is triggered when using render_material().1604// Emissive is set outside the function, so don't set it.1605// IBL isn't used don't set it.1606} else {1607scene_state.ubo.emissive_exposure_normalization = 1.0;1608scene_state.ubo.IBL_exposure_normalization = 1.0;1609}16101611if (scene_state.ubo_buffer == 0) {1612glGenBuffers(1, &scene_state.ubo_buffer);1613glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_DATA_UNIFORM_LOCATION, scene_state.ubo_buffer);1614GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.ubo_buffer, sizeof(SceneState::UBO), &scene_state.ubo, GL_STREAM_DRAW, "Scene state UBO");1615glBindBuffer(GL_UNIFORM_BUFFER, 0);1616} else {1617glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_DATA_UNIFORM_LOCATION, scene_state.ubo_buffer);1618glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::UBO), &scene_state.ubo, GL_STREAM_DRAW);1619}16201621glBindBuffer(GL_UNIFORM_BUFFER, 0);16221623if (p_render_data->view_count > 1) {1624if (scene_state.multiview_buffer == 0) {1625glGenBuffers(1, &scene_state.multiview_buffer);1626glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);1627GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.multiview_buffer, sizeof(SceneState::MultiviewUBO), &scene_state.multiview_ubo, GL_STREAM_DRAW, "Multiview UBO");1628} else {1629glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);1630glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::MultiviewUBO), &scene_state.multiview_ubo, GL_STREAM_DRAW);1631}16321633glBindBuffer(GL_UNIFORM_BUFFER, 0);1634}1635}16361637// Puts lights into Uniform Buffers. Needs to be called before _fill_list as this caches the index of each light in the Uniform Buffer1638void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_omni_light_count, uint32_t &r_spot_light_count, uint32_t &r_directional_shadow_count) {1639GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton();1640GLES3::Config *config = GLES3::Config::get_singleton();16411642const Transform3D inverse_transform = p_render_data->inv_cam_transform;16431644const PagedArray<RID> &lights = *p_render_data->lights;16451646r_directional_light_count = 0;1647r_omni_light_count = 0;1648r_spot_light_count = 0;1649r_directional_shadow_count = 0;16501651int num_lights = lights.size();16521653for (int i = 0; i < num_lights; i++) {1654GLES3::LightInstance *li = GLES3::LightStorage::get_singleton()->get_light_instance(lights[i]);1655if (!li) {1656continue;1657}1658RID base = li->light;16591660ERR_CONTINUE(base.is_null());16611662RS::LightType type = light_storage->light_get_type(base);1663switch (type) {1664case RS::LIGHT_DIRECTIONAL: {1665if (r_directional_light_count >= RendererSceneRender::MAX_DIRECTIONAL_LIGHTS || light_storage->light_directional_get_sky_mode(base) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) {1666continue;1667}16681669// If a DirectionalLight has shadows, we will add it to the end of the array and work in.1670bool has_shadow = light_storage->light_has_shadow(base);16711672int index = r_directional_light_count - r_directional_shadow_count;16731674if (has_shadow) {1675// Lights with shadow are incremented from the end of the array.1676index = MAX_DIRECTIONAL_LIGHTS - 1 - r_directional_shadow_count;1677}1678DirectionalLightData &light_data = scene_state.directional_lights[index];16791680Transform3D light_transform = li->transform;16811682Vector3 direction = inverse_transform.basis.xform(light_transform.basis.xform(Vector3(0, 0, 1))).normalized();16831684light_data.direction[0] = direction.x;1685light_data.direction[1] = direction.y;1686light_data.direction[2] = direction.z;16871688light_data.bake_mode = light_storage->light_get_bake_mode(base);16891690float sign = light_storage->light_is_negative(base) ? -1 : 1;16911692light_data.energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY);16931694if (is_using_physical_light_units()) {1695light_data.energy *= light_storage->light_get_param(base, RS::LIGHT_PARAM_INTENSITY);1696} else {1697light_data.energy *= Math::PI;1698}16991700if (p_render_data->camera_attributes.is_valid()) {1701light_data.energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);1702}17031704Color linear_col = light_storage->light_get_color(base).srgb_to_linear();1705light_data.color[0] = linear_col.r;1706light_data.color[1] = linear_col.g;1707light_data.color[2] = linear_col.b;17081709float size = light_storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);1710light_data.size = 1.0 - Math::cos(Math::deg_to_rad(size)); //angle to cosine offset17111712light_data.specular = light_storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR);17131714light_data.shadow_opacity = (p_using_shadows && light_storage->light_has_shadow(base))1715? light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_OPACITY)1716: 0.0;17171718if (has_shadow) {1719DirectionalShadowData &shadow_data = scene_state.directional_shadows[MAX_DIRECTIONAL_LIGHTS - 1 - r_directional_shadow_count];17201721RS::LightDirectionalShadowMode shadow_mode = light_storage->light_directional_get_shadow_mode(base);17221723int limit = shadow_mode == RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL ? 0 : (shadow_mode == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS ? 1 : 3);17241725shadow_data.shadow_atlas_pixel_size = 1.0 / light_storage->directional_shadow_get_size();17261727shadow_data.blend_splits = uint32_t((shadow_mode != RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL) && light_storage->light_directional_get_blend_splits(base));1728for (int j = 0; j < 4; j++) {1729Rect2 atlas_rect = li->shadow_transform[j].atlas_rect;1730Projection correction;1731correction.set_depth_correction(false, true, false);1732Projection matrix = correction * li->shadow_transform[j].camera;1733float split = li->shadow_transform[MIN(limit, j)].split;17341735Projection bias;1736bias.set_light_bias();1737Projection rectm;1738rectm.set_light_atlas_rect(atlas_rect);17391740Transform3D modelview = (inverse_transform * li->shadow_transform[j].transform).inverse();17411742shadow_data.direction[0] = light_data.direction[0];1743shadow_data.direction[1] = light_data.direction[1];1744shadow_data.direction[2] = light_data.direction[2];17451746Projection shadow_mtx = rectm * bias * matrix * modelview;1747shadow_data.shadow_split_offsets[j] = split;1748shadow_data.shadow_normal_bias[j] = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * li->shadow_transform[j].shadow_texel_size;1749GLES3::MaterialStorage::store_camera(shadow_mtx, shadow_data.shadow_matrices[j]);1750}1751float fade_start = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_FADE_START);1752shadow_data.fade_from = -shadow_data.shadow_split_offsets[3] * MIN(fade_start, 0.999);1753shadow_data.fade_to = -shadow_data.shadow_split_offsets[3];17541755r_directional_shadow_count++;1756}17571758r_directional_light_count++;1759} break;1760case RS::LIGHT_OMNI: {1761if (r_omni_light_count >= (uint32_t)config->max_renderable_lights) {1762continue;1763}17641765const real_t distance = p_render_data->cam_transform.origin.distance_to(li->transform.origin);17661767if (light_storage->light_is_distance_fade_enabled(li->light)) {1768const float fade_begin = light_storage->light_get_distance_fade_begin(li->light);1769const float fade_length = light_storage->light_get_distance_fade_length(li->light);17701771if (distance > fade_begin) {1772if (distance > fade_begin + fade_length) {1773// Out of range, don't draw this light to improve performance.1774continue;1775}1776}1777}17781779scene_state.omni_light_sort[r_omni_light_count].instance = li;1780scene_state.omni_light_sort[r_omni_light_count].depth = distance;1781r_omni_light_count++;1782} break;1783case RS::LIGHT_SPOT: {1784if (r_spot_light_count >= (uint32_t)config->max_renderable_lights) {1785continue;1786}17871788const real_t distance = p_render_data->cam_transform.origin.distance_to(li->transform.origin);17891790if (light_storage->light_is_distance_fade_enabled(li->light)) {1791const float fade_begin = light_storage->light_get_distance_fade_begin(li->light);1792const float fade_length = light_storage->light_get_distance_fade_length(li->light);17931794if (distance > fade_begin) {1795if (distance > fade_begin + fade_length) {1796// Out of range, don't draw this light to improve performance.1797continue;1798}1799}1800}18011802scene_state.spot_light_sort[r_spot_light_count].instance = li;1803scene_state.spot_light_sort[r_spot_light_count].depth = distance;1804r_spot_light_count++;1805} break;1806}18071808li->last_pass = RSG::rasterizer->get_frame_number();1809}18101811if (r_omni_light_count) {1812SortArray<InstanceSort<GLES3::LightInstance>> sorter;1813sorter.sort(scene_state.omni_light_sort, r_omni_light_count);1814}18151816if (r_spot_light_count) {1817SortArray<InstanceSort<GLES3::LightInstance>> sorter;1818sorter.sort(scene_state.spot_light_sort, r_spot_light_count);1819}18201821int num_positional_shadows = 0;18221823for (uint32_t i = 0; i < (r_omni_light_count + r_spot_light_count); i++) {1824uint32_t index = (i < r_omni_light_count) ? i : i - (r_omni_light_count);1825LightData &light_data = (i < r_omni_light_count) ? scene_state.omni_lights[index] : scene_state.spot_lights[index];1826RS::LightType type = (i < r_omni_light_count) ? RS::LIGHT_OMNI : RS::LIGHT_SPOT;1827GLES3::LightInstance *li = (i < r_omni_light_count) ? scene_state.omni_light_sort[index].instance : scene_state.spot_light_sort[index].instance;1828real_t distance = (i < r_omni_light_count) ? scene_state.omni_light_sort[index].depth : scene_state.spot_light_sort[index].depth;1829RID base = li->light;18301831li->gl_id = index;18321833Transform3D light_transform = li->transform;1834Vector3 pos = inverse_transform.xform(light_transform.origin);18351836light_data.position[0] = pos.x;1837light_data.position[1] = pos.y;1838light_data.position[2] = pos.z;18391840light_data.bake_mode = light_storage->light_get_bake_mode(base);18411842float radius = MAX(0.001, light_storage->light_get_param(base, RS::LIGHT_PARAM_RANGE));1843light_data.inv_radius = 1.0 / radius;18441845Vector3 direction = inverse_transform.basis.xform(light_transform.basis.xform(Vector3(0, 0, -1))).normalized();18461847light_data.direction[0] = direction.x;1848light_data.direction[1] = direction.y;1849light_data.direction[2] = direction.z;18501851float size = light_storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);18521853light_data.size = size;18541855float sign = light_storage->light_is_negative(base) ? -1 : 1;1856Color linear_col = light_storage->light_get_color(base).srgb_to_linear();18571858// Reuse fade begin, fade length and distance for shadow LOD determination later.1859float fade_begin = 0.0;1860float fade_shadow = 0.0;1861float fade_length = 0.0;18621863float fade = 1.0;1864float shadow_opacity_fade = 1.0;18651866if (light_storage->light_is_distance_fade_enabled(base)) {1867fade_begin = light_storage->light_get_distance_fade_begin(base);1868fade_shadow = light_storage->light_get_distance_fade_shadow(base);1869fade_length = light_storage->light_get_distance_fade_length(base);18701871if (distance > fade_begin) {1872// Use `smoothstep()` to make opacity changes more gradual and less noticeable to the player.1873fade = Math::smoothstep(0.0f, 1.0f, 1.0f - float(distance - fade_begin) / fade_length);1874}1875if (distance > fade_shadow) {1876shadow_opacity_fade = Math::smoothstep(0.0f, 1.0f, 1.0f - float(distance - fade_shadow) / fade_length);1877}1878}18791880float energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * fade;18811882if (is_using_physical_light_units()) {1883energy *= light_storage->light_get_param(base, RS::LIGHT_PARAM_INTENSITY);18841885// Convert from Luminous Power to Luminous Intensity1886if (type == RS::LIGHT_OMNI) {1887energy *= 1.0 / (Math::PI * 4.0);1888} else {1889// Spot Lights are not physically accurate, Luminous Intensity should change in relation to the cone angle.1890// We make this assumption to keep them easy to control.1891energy *= 1.0 / Math::PI;1892}1893} else {1894energy *= Math::PI;1895}18961897if (p_render_data->camera_attributes.is_valid()) {1898energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);1899}19001901light_data.color[0] = linear_col.r * energy;1902light_data.color[1] = linear_col.g * energy;1903light_data.color[2] = linear_col.b * energy;19041905light_data.attenuation = light_storage->light_get_param(base, RS::LIGHT_PARAM_ATTENUATION);19061907light_data.inv_spot_attenuation = 1.0f / light_storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ATTENUATION);19081909float spot_angle = light_storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ANGLE);1910light_data.cos_spot_angle = Math::cos(Math::deg_to_rad(spot_angle));19111912light_data.specular_amount = light_storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR) * 2.0;19131914// Setup shadows1915const bool needs_shadow =1916p_using_shadows &&1917light_storage->owns_shadow_atlas(p_render_data->shadow_atlas) &&1918light_storage->shadow_atlas_owns_light_instance(p_render_data->shadow_atlas, li->self) &&1919light_storage->light_has_shadow(base);19201921bool in_shadow_range = true;1922if (needs_shadow && light_storage->light_is_distance_fade_enabled(base)) {1923if (distance > fade_shadow + fade_length) {1924// Out of range, don't draw shadows to improve performance.1925in_shadow_range = false;1926}1927}19281929// Fill in the shadow information.1930if (needs_shadow && in_shadow_range) {1931if (num_positional_shadows >= config->max_renderable_lights) {1932continue;1933}1934ShadowData &shadow_data = scene_state.positional_shadows[num_positional_shadows];1935li->shadow_id = num_positional_shadows;1936num_positional_shadows++;19371938light_data.shadow_opacity = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_OPACITY) * shadow_opacity_fade;19391940float shadow_texel_size = light_storage->light_instance_get_shadow_texel_size(li->self, p_render_data->shadow_atlas);1941shadow_data.shadow_atlas_pixel_size = shadow_texel_size;1942shadow_data.shadow_normal_bias = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 10.0;19431944shadow_data.light_position[0] = light_data.position[0];1945shadow_data.light_position[1] = light_data.position[1];1946shadow_data.light_position[2] = light_data.position[2];19471948if (type == RS::LIGHT_OMNI) {1949Transform3D proj = (inverse_transform * light_transform).inverse();19501951GLES3::MaterialStorage::store_transform(proj, shadow_data.shadow_matrix);19521953} else if (type == RS::LIGHT_SPOT) {1954Transform3D modelview = (inverse_transform * light_transform).inverse();1955Projection bias;1956bias.set_light_bias();19571958Projection correction;1959correction.set_depth_correction(false, true, false);1960Projection cm = correction * li->shadow_transform[0].camera;1961Projection shadow_mtx = bias * cm * modelview;1962GLES3::MaterialStorage::store_camera(shadow_mtx, shadow_data.shadow_matrix);1963}1964}1965}19661967// TODO, to avoid stalls, should rotate between 3 buffers based on frame index.1968// TODO, consider mapping the buffer as in 2D1969glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_OMNILIGHT_UNIFORM_LOCATION, scene_state.omni_light_buffer);1970if (r_omni_light_count) {1971glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(LightData) * r_omni_light_count, scene_state.omni_lights);1972}19731974glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_SPOTLIGHT_UNIFORM_LOCATION, scene_state.spot_light_buffer);1975if (r_spot_light_count) {1976glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(LightData) * r_spot_light_count, scene_state.spot_lights);1977}19781979glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_DIRECTIONAL_LIGHT_UNIFORM_LOCATION, scene_state.directional_light_buffer);1980if (r_directional_light_count) {1981glBufferData(GL_UNIFORM_BUFFER, sizeof(DirectionalLightData) * MAX_DIRECTIONAL_LIGHTS, scene_state.directional_lights, GL_STREAM_DRAW);1982}19831984glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_POSITIONAL_SHADOW_UNIFORM_LOCATION, scene_state.positional_shadow_buffer);1985if (num_positional_shadows) {1986glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(ShadowData) * num_positional_shadows, scene_state.positional_shadows);1987}19881989glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_DIRECTIONAL_SHADOW_UNIFORM_LOCATION, scene_state.directional_shadow_buffer);1990if (r_directional_shadow_count) {1991glBufferData(GL_UNIFORM_BUFFER, sizeof(DirectionalShadowData) * MAX_DIRECTIONAL_LIGHTS, scene_state.directional_shadows, GL_STREAM_DRAW);1992}1993glBindBuffer(GL_UNIFORM_BUFFER, 0);1994}19951996// Render shadows1997void RasterizerSceneGLES3::_render_shadows(const RenderDataGLES3 *p_render_data, const Size2i &p_viewport_size) {1998GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton();19992000LocalVector<int> cube_shadows;2001LocalVector<int> shadows;2002LocalVector<int> directional_shadows;20032004float lod_distance_multiplier = p_render_data->cam_projection.get_lod_multiplier();20052006// Put lights into buckets for omni (cube shadows), directional, and spot.2007{2008for (int i = 0; i < p_render_data->render_shadow_count; i++) {2009RID li = p_render_data->render_shadows[i].light;2010RID base = light_storage->light_instance_get_base_light(li);20112012if (light_storage->light_get_type(base) == RS::LIGHT_DIRECTIONAL) {2013directional_shadows.push_back(i);2014} else if (light_storage->light_get_type(base) == RS::LIGHT_OMNI && light_storage->light_omni_get_shadow_mode(base) == RS::LIGHT_OMNI_SHADOW_CUBE) {2015cube_shadows.push_back(i);2016} else {2017shadows.push_back(i);2018}2019}2020if (directional_shadows.size()) {2021light_storage->update_directional_shadow_atlas();2022}2023}20242025bool render_shadows = directional_shadows.size() || shadows.size() || cube_shadows.size();20262027if (render_shadows) {2028RENDER_TIMESTAMP("Render Shadows");20292030// Render cubemap shadows.2031for (const int &index : cube_shadows) {2032_render_shadow_pass(p_render_data->render_shadows[index].light, p_render_data->shadow_atlas, p_render_data->render_shadows[index].pass, p_render_data->render_shadows[index].instances, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info, p_viewport_size, p_render_data->cam_transform);2033}2034// Render directional shadows.2035for (uint32_t i = 0; i < directional_shadows.size(); i++) {2036_render_shadow_pass(p_render_data->render_shadows[directional_shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[directional_shadows[i]].pass, p_render_data->render_shadows[directional_shadows[i]].instances, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info, p_viewport_size, p_render_data->cam_transform);2037}2038// Render positional shadows (Spotlight and Omnilight with dual-paraboloid).2039for (uint32_t i = 0; i < shadows.size(); i++) {2040_render_shadow_pass(p_render_data->render_shadows[shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[shadows[i]].pass, p_render_data->render_shadows[shadows[i]].instances, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->render_info, p_viewport_size, p_render_data->cam_transform);2041}2042}2043}20442045void RasterizerSceneGLES3::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, RenderingMethod::RenderInfo *p_render_info, const Size2i &p_viewport_size, const Transform3D &p_main_cam_transform) {2046GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton();20472048ERR_FAIL_COND(!light_storage->owns_light_instance(p_light));20492050RID base = light_storage->light_instance_get_base_light(p_light);20512052float zfar = 0.0;2053bool use_pancake = false;2054float shadow_bias = 0.0;2055bool reverse_cull = false;2056bool needs_clear = false;20572058Projection light_projection;2059Transform3D light_transform;2060GLuint shadow_fb = 0;2061Rect2i atlas_rect;20622063if (light_storage->light_get_type(base) == RS::LIGHT_DIRECTIONAL) {2064// Set pssm stuff.2065uint64_t last_scene_shadow_pass = light_storage->light_instance_get_shadow_pass(p_light);2066if (last_scene_shadow_pass != get_scene_pass()) {2067light_storage->light_instance_set_directional_rect(p_light, light_storage->get_directional_shadow_rect());2068light_storage->directional_shadow_increase_current_light();2069light_storage->light_instance_set_shadow_pass(p_light, get_scene_pass());2070}20712072atlas_rect = light_storage->light_instance_get_directional_rect(p_light);20732074if (light_storage->light_directional_get_shadow_mode(base) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) {2075atlas_rect.size.width /= 2;2076atlas_rect.size.height /= 2;20772078if (p_pass == 1) {2079atlas_rect.position.x += atlas_rect.size.width;2080} else if (p_pass == 2) {2081atlas_rect.position.y += atlas_rect.size.height;2082} else if (p_pass == 3) {2083atlas_rect.position += atlas_rect.size;2084}2085} else if (light_storage->light_directional_get_shadow_mode(base) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) {2086atlas_rect.size.height /= 2;20872088if (p_pass == 0) {2089} else {2090atlas_rect.position.y += atlas_rect.size.height;2091}2092}20932094use_pancake = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE) > 0;2095light_projection = light_storage->light_instance_get_shadow_camera(p_light, p_pass);2096light_transform = light_storage->light_instance_get_shadow_transform(p_light, p_pass);20972098float directional_shadow_size = light_storage->directional_shadow_get_size();2099Rect2 atlas_rect_norm = atlas_rect;2100atlas_rect_norm.position /= directional_shadow_size;2101atlas_rect_norm.size /= directional_shadow_size;2102light_storage->light_instance_set_directional_shadow_atlas_rect(p_light, p_pass, atlas_rect_norm);21032104zfar = RSG::light_storage->light_get_param(base, RS::LIGHT_PARAM_RANGE);2105shadow_fb = light_storage->direction_shadow_get_fb();2106reverse_cull = !light_storage->light_get_reverse_cull_face_mode(base);21072108float bias_scale = light_storage->light_instance_get_shadow_bias_scale(p_light, p_pass);2109shadow_bias = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0 * bias_scale;21102111} else {2112// Set from shadow atlas.21132114ERR_FAIL_COND(!light_storage->owns_shadow_atlas(p_shadow_atlas));2115ERR_FAIL_COND(!light_storage->shadow_atlas_owns_light_instance(p_shadow_atlas, p_light));21162117uint32_t key = light_storage->shadow_atlas_get_light_instance_key(p_shadow_atlas, p_light);21182119uint32_t quadrant = (key >> GLES3::LightStorage::QUADRANT_SHIFT) & 0x3;2120uint32_t shadow = key & GLES3::LightStorage::SHADOW_INDEX_MASK;21212122ERR_FAIL_INDEX((int)shadow, light_storage->shadow_atlas_get_quadrant_shadows_length(p_shadow_atlas, quadrant));21232124int shadow_size = light_storage->shadow_atlas_get_quadrant_shadow_size(p_shadow_atlas, quadrant);21252126shadow_fb = light_storage->shadow_atlas_get_quadrant_shadow_fb(p_shadow_atlas, quadrant, shadow);21272128zfar = light_storage->light_get_param(base, RS::LIGHT_PARAM_RANGE);2129reverse_cull = !light_storage->light_get_reverse_cull_face_mode(base);21302131if (light_storage->light_get_type(base) == RS::LIGHT_OMNI) {2132if (light_storage->light_omni_get_shadow_mode(base) == RS::LIGHT_OMNI_SHADOW_CUBE) {2133GLuint shadow_texture = light_storage->shadow_atlas_get_quadrant_shadow_texture(p_shadow_atlas, quadrant, shadow);2134glBindFramebuffer(GL_FRAMEBUFFER, shadow_fb);21352136static GLenum cube_map_faces[6] = {2137GL_TEXTURE_CUBE_MAP_POSITIVE_X,2138GL_TEXTURE_CUBE_MAP_NEGATIVE_X,2139// Flipped order for Y to match what the RD renderer expects2140// (and thus what is given to us by the Rendering Server).2141GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,2142GL_TEXTURE_CUBE_MAP_POSITIVE_Y,2143GL_TEXTURE_CUBE_MAP_POSITIVE_Z,2144GL_TEXTURE_CUBE_MAP_NEGATIVE_Z2145};21462147glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, cube_map_faces[p_pass], shadow_texture, 0);21482149light_projection = light_storage->light_instance_get_shadow_camera(p_light, p_pass);2150light_transform = light_storage->light_instance_get_shadow_transform(p_light, p_pass);2151shadow_size = shadow_size / 2;2152} else {2153ERR_FAIL_MSG("Dual paraboloid shadow mode not supported in the Compatibility renderer. Please use CubeMap shadow mode instead.");2154}21552156shadow_bias = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS);21572158} else if (light_storage->light_get_type(base) == RS::LIGHT_SPOT) {2159light_projection = light_storage->light_instance_get_shadow_camera(p_light, 0);2160light_transform = light_storage->light_instance_get_shadow_transform(p_light, 0);21612162shadow_bias = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) / 10.0;2163// Prebake range into bias so we can scale based on distance easily.2164shadow_bias *= light_storage->light_get_param(base, RS::LIGHT_PARAM_RANGE);2165}2166atlas_rect.size.x = shadow_size;2167atlas_rect.size.y = shadow_size;21682169needs_clear = true;2170}21712172RenderDataGLES3 render_data;2173render_data.cam_projection = light_projection;2174render_data.cam_transform = light_transform;2175render_data.inv_cam_transform = light_transform.affine_inverse();2176render_data.z_far = zfar; // Only used by OmniLights.2177render_data.z_near = 0.0;2178render_data.lod_distance_multiplier = p_lod_distance_multiplier;2179render_data.main_cam_transform = p_main_cam_transform;21802181render_data.instances = &p_instances;2182render_data.render_info = p_render_info;21832184_setup_environment(&render_data, true, p_viewport_size, false, Color(), use_pancake, shadow_bias);21852186if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {2187render_data.screen_mesh_lod_threshold = 0.0;2188} else {2189render_data.screen_mesh_lod_threshold = p_screen_mesh_lod_threshold;2190}21912192_fill_render_list(RENDER_LIST_SECONDARY, &render_data, PASS_MODE_SHADOW);2193render_list[RENDER_LIST_SECONDARY].sort_by_key();21942195glBindFramebuffer(GL_FRAMEBUFFER, shadow_fb);2196glViewport(atlas_rect.position.x, atlas_rect.position.y, atlas_rect.size.x, atlas_rect.size.y);21972198GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_shader_parameters_get_uniform_buffer();21992200glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_GLOBALS_UNIFORM_LOCATION, global_buffer);2201glBindBuffer(GL_UNIFORM_BUFFER, 0);22022203scene_state.reset_gl_state();2204scene_state.enable_gl_depth_test(true);2205scene_state.enable_gl_depth_draw(true);2206scene_state.set_gl_depth_func(GL_GREATER);22072208glColorMask(0, 0, 0, 0);2209glDrawBuffers(0, nullptr);2210RasterizerGLES3::clear_depth(0.0);2211if (needs_clear) {2212glClear(GL_DEPTH_BUFFER_BIT);2213}22142215uint64_t spec_constant_base_flags = SceneShaderGLES3::DISABLE_LIGHTMAP |2216SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL |2217SceneShaderGLES3::DISABLE_LIGHT_OMNI |2218SceneShaderGLES3::DISABLE_LIGHT_SPOT |2219SceneShaderGLES3::DISABLE_FOG |2220SceneShaderGLES3::RENDER_SHADOWS;22212222if (light_storage->light_get_type(base) == RS::LIGHT_OMNI) {2223spec_constant_base_flags |= SceneShaderGLES3::RENDER_SHADOWS_LINEAR;2224}22252226RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), reverse_cull, spec_constant_base_flags, false);22272228_render_list_template<PASS_MODE_SHADOW>(&render_list_params, &render_data, 0, render_list[RENDER_LIST_SECONDARY].elements.size());22292230glColorMask(1, 1, 1, 1);2231scene_state.enable_gl_depth_test(false);2232scene_state.enable_gl_depth_draw(true);2233glDisable(GL_CULL_FACE);2234scene_state.cull_mode = RS::CULL_MODE_DISABLED;2235glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);2236}22372238void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_compositor, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RenderingMethod::RenderInfo *r_render_info) {2239GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();2240GLES3::Config *config = GLES3::Config::get_singleton();2241RENDER_TIMESTAMP("Setup 3D Scene");22422243bool apply_color_adjustments_in_post = false;2244bool is_reflection_probe = p_reflection_probe.is_valid();22452246Ref<RenderSceneBuffersGLES3> rb = p_render_buffers;2247ERR_FAIL_COND(rb.is_null());22482249if (rb->get_scaling_3d_mode() != RS::VIEWPORT_SCALING_3D_MODE_OFF) {2250// If we're scaling, we apply tonemapping etc. in post, so disable it during rendering2251apply_color_adjustments_in_post = true;2252}22532254GLES3::RenderTarget *rt = nullptr; // No render target for reflection probe2255if (!is_reflection_probe) {2256rt = texture_storage->get_render_target(rb->render_target);2257ERR_FAIL_NULL(rt);2258}22592260bool glow_enabled = false;2261if (p_environment.is_valid()) {2262glow_enabled = environment_get_glow_enabled(p_environment);2263if (glow_enabled) {2264// If glow is enabled, we apply tonemapping etc. in post, so disable it during rendering2265apply_color_adjustments_in_post = true;2266}2267}22682269// Assign render data2270// Use the format from rendererRD2271RenderDataGLES3 render_data;2272{2273render_data.render_buffers = rb;22742275if (rt) {2276render_data.transparent_bg = rt->is_transparent;2277render_data.render_region = rt->render_region;2278}22792280// Our first camera is used by default2281render_data.cam_transform = p_camera_data->main_transform;2282render_data.inv_cam_transform = render_data.cam_transform.affine_inverse();2283render_data.cam_projection = p_camera_data->main_projection;2284render_data.cam_orthogonal = p_camera_data->is_orthogonal;2285render_data.cam_frustum = p_camera_data->is_frustum;2286render_data.camera_visible_layers = p_camera_data->visible_layers;2287render_data.main_cam_transform = p_camera_data->main_transform;22882289render_data.view_count = p_camera_data->view_count;2290for (uint32_t v = 0; v < p_camera_data->view_count; v++) {2291render_data.view_eye_offset[v] = p_camera_data->view_offset[v].origin;2292render_data.view_projection[v] = p_camera_data->view_projection[v];2293}22942295render_data.z_near = p_camera_data->main_projection.get_z_near();2296render_data.z_far = p_camera_data->main_projection.get_z_far();22972298render_data.instances = &p_instances;2299render_data.lights = &p_lights;2300render_data.reflection_probes = &p_reflection_probes;2301render_data.environment = p_environment;2302render_data.camera_attributes = p_camera_attributes;2303render_data.shadow_atlas = p_shadow_atlas;2304render_data.reflection_probe = p_reflection_probe;2305render_data.reflection_probe_pass = p_reflection_probe_pass;23062307// this should be the same for all cameras..2308render_data.lod_distance_multiplier = p_camera_data->main_projection.get_lod_multiplier();23092310if (rt != nullptr && rt->color_type == GL_UNSIGNED_INT_2_10_10_10_REV && glow_enabled) {2311// As our output is in sRGB and we're using 10bit color space, we can fake a little HDR to do glow...2312render_data.luminance_multiplier = 0.25;2313} else {2314render_data.luminance_multiplier = 1.0;2315}23162317if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {2318render_data.screen_mesh_lod_threshold = 0.0;2319} else {2320render_data.screen_mesh_lod_threshold = p_screen_mesh_lod_threshold;2321}2322render_data.render_info = r_render_info;2323render_data.render_shadows = p_render_shadows;2324render_data.render_shadow_count = p_render_shadow_count;2325}23262327PagedArray<RID> empty;23282329if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {2330render_data.lights = ∅2331render_data.reflection_probes = ∅2332}23332334bool reverse_cull = render_data.cam_transform.basis.determinant() < 0;23352336///////////2337// Fill Light lists here2338//////////23392340GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_shader_parameters_get_uniform_buffer();2341glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_GLOBALS_UNIFORM_LOCATION, global_buffer);23422343Color clear_color;2344if (!is_reflection_probe && rb->render_target.is_valid()) {2345clear_color = texture_storage->render_target_get_clear_request_color(rb->render_target);2346} else {2347clear_color = texture_storage->get_default_clear_color();2348}23492350bool fb_cleared = false;23512352Size2i screen_size = rb->internal_size;23532354bool use_wireframe = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME;23552356SceneState::TonemapUBO tonemap_ubo;2357if (render_data.environment.is_valid()) {2358bool use_bcs = environment_get_adjustments_enabled(render_data.environment);2359if (use_bcs) {2360apply_color_adjustments_in_post = true;2361}23622363tonemap_ubo.exposure = environment_get_exposure(render_data.environment);2364tonemap_ubo.white = environment_get_white(render_data.environment);2365tonemap_ubo.tonemapper = int32_t(environment_get_tone_mapper(render_data.environment));23662367tonemap_ubo.brightness = environment_get_adjustments_brightness(render_data.environment);2368tonemap_ubo.contrast = environment_get_adjustments_contrast(render_data.environment);2369tonemap_ubo.saturation = environment_get_adjustments_saturation(render_data.environment);2370}23712372if (scene_state.tonemap_buffer == 0) {2373// Only create if using 3D2374glGenBuffers(1, &scene_state.tonemap_buffer);2375glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_TONEMAP_UNIFORM_LOCATION, scene_state.tonemap_buffer);2376GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.tonemap_buffer, sizeof(SceneState::TonemapUBO), &tonemap_ubo, GL_STREAM_DRAW, "Tonemap UBO");2377} else {2378glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_TONEMAP_UNIFORM_LOCATION, scene_state.tonemap_buffer);2379glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::TonemapUBO), &tonemap_ubo, GL_STREAM_DRAW);2380}23812382glBindBuffer(GL_UNIFORM_BUFFER, 0);23832384scene_state.ubo.emissive_exposure_normalization = -1.0; // Use default exposure normalization.23852386bool flip_y = !is_reflection_probe;23872388if (rt && rt->overridden.color.is_valid()) {2389// If we've overridden the render target's color texture, then don't render upside down.2390// We're probably rendering directly to an XR device.2391flip_y = false;2392}2393if (!flip_y) {2394// If we're rendering right-side up, then we need to change the winding order.2395glFrontFace(GL_CW);2396}2397_render_shadows(&render_data, screen_size);23982399_setup_lights(&render_data, true, render_data.directional_light_count, render_data.omni_light_count, render_data.spot_light_count, render_data.directional_shadow_count);2400_setup_environment(&render_data, is_reflection_probe, screen_size, flip_y, clear_color, false);24012402_fill_render_list(RENDER_LIST_OPAQUE, &render_data, PASS_MODE_COLOR);2403render_list[RENDER_LIST_OPAQUE].sort_by_key();2404render_list[RENDER_LIST_ALPHA].sort_by_reverse_depth_and_priority();24052406bool draw_sky = false;2407bool draw_sky_fog_only = false;2408bool keep_color = false;2409bool draw_canvas = false;2410bool draw_feed = false;2411float sky_energy_multiplier = 1.0;2412int camera_feed_id = -1;24132414if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW)) {2415clear_color = Color(0, 0, 0, 1); //in overdraw mode, BG should always be black2416} else if (render_data.environment.is_valid()) {2417RS::EnvironmentBG bg_mode = environment_get_background(render_data.environment);2418float bg_energy_multiplier = environment_get_bg_energy_multiplier(render_data.environment);2419bg_energy_multiplier *= environment_get_bg_intensity(render_data.environment);2420RS::EnvironmentReflectionSource reflection_source = environment_get_reflection_source(render_data.environment);2421RS::EnvironmentAmbientSource ambient_source = environment_get_ambient_source(render_data.environment);24222423if (render_data.camera_attributes.is_valid()) {2424bg_energy_multiplier *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(render_data.camera_attributes);2425}24262427switch (bg_mode) {2428case RS::ENV_BG_CLEAR_COLOR: {2429clear_color.r *= bg_energy_multiplier;2430clear_color.g *= bg_energy_multiplier;2431clear_color.b *= bg_energy_multiplier;2432if (!render_data.transparent_bg && environment_get_fog_enabled(render_data.environment)) {2433draw_sky_fog_only = true;2434GLES3::MaterialStorage::get_singleton()->material_set_param(sky_globals.fog_material, "clear_color", Variant(clear_color));2435}2436} break;2437case RS::ENV_BG_COLOR: {2438clear_color = environment_get_bg_color(render_data.environment);2439clear_color.r *= bg_energy_multiplier;2440clear_color.g *= bg_energy_multiplier;2441clear_color.b *= bg_energy_multiplier;2442if (!render_data.transparent_bg && environment_get_fog_enabled(render_data.environment)) {2443draw_sky_fog_only = true;2444GLES3::MaterialStorage::get_singleton()->material_set_param(sky_globals.fog_material, "clear_color", Variant(clear_color));2445}2446} break;2447case RS::ENV_BG_SKY: {2448draw_sky = !render_data.transparent_bg;2449} break;2450case RS::ENV_BG_CANVAS: {2451draw_canvas = true;2452} break;2453case RS::ENV_BG_KEEP: {2454keep_color = true;2455} break;2456case RS::ENV_BG_CAMERA_FEED: {2457camera_feed_id = environment_get_camera_feed_id(render_data.environment);2458draw_feed = true;2459keep_color = true;2460} break;2461default: {2462}2463}24642465bool sky_reflections = reflection_source == RS::ENV_REFLECTION_SOURCE_SKY;2466sky_reflections |= reflection_source == RS::ENV_REFLECTION_SOURCE_BG && bg_mode == RS::ENV_BG_SKY;2467bool sky_ambient = ambient_source == RS::ENV_AMBIENT_SOURCE_SKY;2468sky_ambient |= ambient_source == RS::ENV_AMBIENT_SOURCE_BG && bg_mode == RS::ENV_BG_SKY;24692470// setup sky if used for ambient, reflections, or background2471if (draw_sky || draw_sky_fog_only || sky_reflections || sky_ambient) {2472RENDER_TIMESTAMP("Setup Sky");2473Projection projection = render_data.cam_projection;2474if (is_reflection_probe) {2475Projection correction;2476correction.set_depth_correction(true, true, false);2477projection = correction * render_data.cam_projection;2478}24792480sky_energy_multiplier *= bg_energy_multiplier;24812482_setup_sky(&render_data, *render_data.lights, projection, render_data.cam_transform, screen_size);24832484if (environment_get_sky(render_data.environment).is_valid()) {2485if (sky_reflections || sky_ambient) {2486_update_sky_radiance(render_data.environment, projection, render_data.cam_transform, sky_energy_multiplier);2487}2488} else {2489// do not try to draw sky if invalid2490draw_sky = false;2491}2492}2493}24942495GLuint fbo = 0;2496if (is_reflection_probe && GLES3::LightStorage::get_singleton()->reflection_probe_has_atlas_index(render_data.reflection_probe)) {2497fbo = GLES3::LightStorage::get_singleton()->reflection_probe_instance_get_framebuffer(render_data.reflection_probe, render_data.reflection_probe_pass);2498} else {2499rb->set_apply_color_adjustments_in_post(apply_color_adjustments_in_post);2500fbo = rb->get_render_fbo();2501}25022503glBindFramebuffer(GL_FRAMEBUFFER, fbo);2504glViewport(0, 0, rb->internal_size.x, rb->internal_size.y);25052506scene_state.reset_gl_state();25072508// Do depth prepass if it's explicitly enabled2509bool use_depth_prepass = config->use_depth_prepass;25102511// Forcibly enable depth prepass if opaque stencil writes are used.2512use_depth_prepass = use_depth_prepass || scene_state.used_opaque_stencil;25132514// Don't do depth prepass we are rendering overdraw2515use_depth_prepass = use_depth_prepass && get_debug_draw_mode() != RS::VIEWPORT_DEBUG_DRAW_OVERDRAW;25162517if (use_depth_prepass) {2518RENDER_TIMESTAMP("Depth Prepass");2519//pre z pass25202521if (render_data.render_region != Rect2i()) {2522glViewport(render_data.render_region.position.x, render_data.render_region.position.y, render_data.render_region.size.width, render_data.render_region.size.height);2523}25242525scene_state.enable_gl_depth_test(true);2526scene_state.enable_gl_depth_draw(true);2527scene_state.enable_gl_blend(false);2528scene_state.set_gl_depth_func(GL_GEQUAL);2529scene_state.enable_gl_scissor_test(false);2530scene_state.enable_gl_stencil_test(false);25312532glColorMask(0, 0, 0, 0);2533RasterizerGLES3::clear_depth(0.0);2534RasterizerGLES3::clear_stencil(0);2535glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);2536// Some desktop GL implementations fall apart when using Multiview with GL_NONE.2537GLuint db = p_camera_data->view_count > 1 ? GL_COLOR_ATTACHMENT0 : GL_NONE;2538glDrawBuffers(1, &db);25392540uint64_t spec_constant = SceneShaderGLES3::DISABLE_FOG | SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL |2541SceneShaderGLES3::DISABLE_LIGHTMAP | SceneShaderGLES3::DISABLE_LIGHT_OMNI |2542SceneShaderGLES3::DISABLE_LIGHT_SPOT;25432544RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, spec_constant, use_wireframe);2545_render_list_template<PASS_MODE_DEPTH>(&render_list_params, &render_data, 0, render_list[RENDER_LIST_OPAQUE].elements.size());25462547glColorMask(1, 1, 1, 1);25482549fb_cleared = true;2550scene_state.used_depth_prepass = true;2551} else {2552scene_state.used_depth_prepass = false;2553}25542555glBlendEquation(GL_FUNC_ADD);2556if (render_data.transparent_bg) {2557glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);2558scene_state.enable_gl_blend(true);2559} else {2560glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);2561scene_state.enable_gl_blend(false);2562}2563scene_state.current_blend_mode = GLES3::SceneShaderData::BLEND_MODE_MIX;25642565scene_state.enable_gl_scissor_test(false);2566scene_state.enable_gl_depth_test(true);2567scene_state.enable_gl_depth_draw(true);2568scene_state.set_gl_depth_func(GL_GEQUAL);25692570{2571GLuint db = GL_COLOR_ATTACHMENT0;2572glDrawBuffers(1, &db);2573}25742575scene_state.enable_gl_stencil_test(false);25762577if (!fb_cleared) {2578RasterizerGLES3::clear_depth(0.0);2579RasterizerGLES3::clear_stencil(0);2580glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);2581}25822583// Need to clear framebuffer unless:2584// a) We explicitly request not to (i.e. ENV_BG_KEEP).2585// b) We are rendering to a non-intermediate framebuffer with ENV_BG_CANVAS (shared between 2D and 3D).2586if (!keep_color && (!draw_canvas || fbo != rt->fbo)) {2587clear_color.a = render_data.transparent_bg ? 0.0f : 1.0f;2588glClearBufferfv(GL_COLOR, 0, clear_color.components);2589}2590if ((keep_color || draw_canvas) && fbo != rt->fbo) {2591// Need to copy our current contents to our intermediate/MSAA buffer2592GLES3::CopyEffects *copy_effects = GLES3::CopyEffects::get_singleton();25932594scene_state.enable_gl_depth_test(false);2595scene_state.enable_gl_depth_draw(false);25962597glActiveTexture(GL_TEXTURE0);2598glBindTexture(rt->view_count > 1 ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D, rt->color);25992600copy_effects->copy_screen(render_data.luminance_multiplier);26012602scene_state.enable_gl_depth_test(true);2603scene_state.enable_gl_depth_draw(true);2604}26052606RENDER_TIMESTAMP("Render Opaque Pass");2607uint64_t spec_constant_base_flags = 0;26082609if (render_data.render_region != Rect2i()) {2610glViewport(render_data.render_region.position.x, render_data.render_region.position.y, render_data.render_region.size.width, render_data.render_region.size.height);2611}26122613{2614// Specialization Constants that apply for entire rendering pass.2615if (render_data.directional_light_count == 0) {2616spec_constant_base_flags |= SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL;2617}26182619if (render_data.environment.is_null() || (render_data.environment.is_valid() && !environment_get_fog_enabled(render_data.environment))) {2620spec_constant_base_flags |= SceneShaderGLES3::DISABLE_FOG;2621}26222623if (render_data.environment.is_valid() && environment_get_fog_mode(render_data.environment) == RS::EnvironmentFogMode::ENV_FOG_MODE_DEPTH) {2624spec_constant_base_flags |= SceneShaderGLES3::USE_DEPTH_FOG;2625}26262627if (!apply_color_adjustments_in_post) {2628spec_constant_base_flags |= SceneShaderGLES3::APPLY_TONEMAPPING;2629}2630}26312632if (draw_feed && camera_feed_id > -1) {2633RENDER_TIMESTAMP("Render Camera feed");26342635scene_state.enable_gl_depth_draw(false);2636scene_state.enable_gl_depth_test(false);2637scene_state.enable_gl_blend(false);2638scene_state.set_gl_cull_mode(RS::CULL_MODE_BACK);26392640Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);26412642if (feed.is_valid()) {2643RID camera_YCBCR = feed->get_texture(CameraServer::FEED_YCBCR_IMAGE);2644GLES3::TextureStorage::get_singleton()->texture_bind(camera_YCBCR, 0);26452646GLES3::FeedEffects *feed_effects = GLES3::FeedEffects::get_singleton();2647feed_effects->draw();2648}2649scene_state.enable_gl_depth_draw(true);2650scene_state.enable_gl_depth_test(true);2651scene_state.enable_gl_blend(true);2652}26532654// Render Opaque Objects.2655RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, spec_constant_base_flags, use_wireframe);26562657_render_list_template<PASS_MODE_COLOR>(&render_list_params, &render_data, 0, render_list[RENDER_LIST_OPAQUE].elements.size());26582659scene_state.enable_gl_depth_draw(false);2660scene_state.enable_gl_stencil_test(false);26612662if (draw_sky || draw_sky_fog_only) {2663RENDER_TIMESTAMP("Render Sky");26642665scene_state.enable_gl_depth_test(true);2666scene_state.set_gl_depth_func(GL_GEQUAL);2667scene_state.enable_gl_blend(false);2668scene_state.set_gl_cull_mode(RS::CULL_MODE_BACK);26692670Transform3D transform = render_data.cam_transform;2671Projection projection = render_data.cam_projection;2672if (is_reflection_probe) {2673Projection correction;2674correction.columns[1][1] = -1.0;2675projection = correction * render_data.cam_projection;2676} else if (render_data.cam_frustum) {2677// Sky is drawn upside down, the frustum offset doesn't know the image is upside down so needs a flip.2678projection[2].y = -projection[2].y;2679}26802681_draw_sky(render_data.environment, projection, transform, sky_energy_multiplier, render_data.luminance_multiplier, p_camera_data->view_count > 1, flip_y, apply_color_adjustments_in_post);2682}26832684if (rt && (scene_state.used_screen_texture || scene_state.used_depth_texture)) {2685Size2i size;2686GLuint backbuffer_fbo = 0;2687GLuint backbuffer = 0;2688GLuint backbuffer_depth = 0;26892690if (rb->get_scaling_3d_mode() == RS::VIEWPORT_SCALING_3D_MODE_OFF) {2691texture_storage->check_backbuffer(rt, scene_state.used_screen_texture, scene_state.used_depth_texture); // note, badly names, this just allocates!26922693size = rt->size;2694backbuffer_fbo = rt->backbuffer_fbo;2695backbuffer = rt->backbuffer;2696backbuffer_depth = rt->backbuffer_depth;2697} else {2698rb->check_backbuffer(scene_state.used_screen_texture, scene_state.used_depth_texture);2699size = rb->get_internal_size();2700backbuffer_fbo = rb->get_backbuffer_fbo();2701backbuffer = rb->get_backbuffer();2702backbuffer_depth = rb->get_backbuffer_depth();2703}27042705if (backbuffer_fbo != 0) {2706glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);2707glReadBuffer(GL_COLOR_ATTACHMENT0);2708glBindFramebuffer(GL_DRAW_FRAMEBUFFER, backbuffer_fbo);2709if (scene_state.used_screen_texture) {2710glBlitFramebuffer(0, 0, size.x, size.y,27110, 0, size.x, size.y,2712GL_COLOR_BUFFER_BIT, GL_NEAREST);2713glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 6);2714glBindTexture(GL_TEXTURE_2D, backbuffer);2715}2716if (scene_state.used_depth_texture) {2717glBlitFramebuffer(0, 0, size.x, size.y,27180, 0, size.x, size.y,2719GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);2720glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 7);2721glBindTexture(GL_TEXTURE_2D, backbuffer_depth);2722}2723}27242725// Bound framebuffer may have changed, so change it back2726glBindFramebuffer(GL_FRAMEBUFFER, fbo);2727}27282729RENDER_TIMESTAMP("Render 3D Transparent Pass");2730scene_state.enable_gl_blend(true);27312732//Render transparent pass2733RenderListParameters render_list_params_alpha(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, spec_constant_base_flags, use_wireframe);27342735_render_list_template<PASS_MODE_COLOR_TRANSPARENT>(&render_list_params_alpha, &render_data, 0, render_list[RENDER_LIST_ALPHA].elements.size(), true);27362737scene_state.enable_gl_stencil_test(false);27382739if (!flip_y) {2740// Restore the default winding order.2741glFrontFace(GL_CCW);2742}27432744if (!is_reflection_probe && rb.is_valid()) {2745_render_buffers_debug_draw(rb, p_shadow_atlas, fbo);2746}27472748// Reset stuff that may trip up the next process.2749scene_state.reset_gl_state();2750glUseProgram(0);27512752if (!is_reflection_probe) {2753_render_post_processing(&render_data);27542755texture_storage->render_target_disable_clear_request(rb->render_target);2756}27572758glActiveTexture(GL_TEXTURE0);2759}27602761void RasterizerSceneGLES3::_render_post_processing(const RenderDataGLES3 *p_render_data) {2762GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();2763GLES3::Glow *glow = GLES3::Glow::get_singleton();2764GLES3::PostEffects *post_effects = GLES3::PostEffects::get_singleton();27652766Ref<RenderSceneBuffersGLES3> rb = p_render_data->render_buffers;2767ERR_FAIL_COND(rb.is_null());27682769RID render_target = rb->get_render_target();2770Size2i internal_size = rb->get_internal_size();2771Size2i target_size = rb->get_target_size();2772uint32_t view_count = rb->get_view_count();27732774// bool msaa2d_needs_resolve = texture_storage->render_target_get_msaa(render_target) != RS::VIEWPORT_MSAA_DISABLED && !GLES3::Config::get_singleton()->rt_msaa_supported;2775bool msaa3d_needs_resolve = rb->get_msaa_needs_resolve();2776GLuint fbo_msaa_3d = rb->get_msaa3d_fbo();2777GLuint fbo_int = rb->get_internal_fbo();2778GLuint fbo_rt = texture_storage->render_target_get_fbo(render_target); // TODO if MSAA 2D is enabled and we're not using rt_msaa, get 2D render target here.27792780// Check if we have glow enabled and if so, check if our buffers were allocated2781bool glow_enabled = false;2782float glow_intensity = 1.0;2783float glow_bloom = 0.0;2784float glow_hdr_bleed_threshold = 1.0;2785float glow_hdr_bleed_scale = 2.0;2786float glow_hdr_luminance_cap = 12.0;2787if (p_render_data->environment.is_valid()) {2788glow_enabled = environment_get_glow_enabled(p_render_data->environment);2789glow_intensity = environment_get_glow_intensity(p_render_data->environment);2790glow_bloom = environment_get_glow_bloom(p_render_data->environment);2791glow_hdr_bleed_threshold = environment_get_glow_hdr_bleed_threshold(p_render_data->environment);2792glow_hdr_bleed_scale = environment_get_glow_hdr_bleed_scale(p_render_data->environment);2793glow_hdr_luminance_cap = environment_get_glow_hdr_luminance_cap(p_render_data->environment);2794}27952796if (glow_enabled) {2797rb->check_glow_buffers();2798}27992800uint64_t bcs_spec_constants = 0;2801if (p_render_data->environment.is_valid()) {2802bool use_bcs = environment_get_adjustments_enabled(p_render_data->environment);2803RID color_correction_texture = environment_get_color_correction(p_render_data->environment);2804if (use_bcs) {2805bcs_spec_constants |= PostShaderGLES3::USE_BCS;28062807if (color_correction_texture.is_valid()) {2808bcs_spec_constants |= PostShaderGLES3::USE_COLOR_CORRECTION;28092810bool use_1d_lut = environment_get_use_1d_color_correction(p_render_data->environment);2811GLenum texture_target = GL_TEXTURE_3D;2812if (use_1d_lut) {2813bcs_spec_constants |= PostShaderGLES3::USE_1D_LUT;2814texture_target = GL_TEXTURE_2D;2815}28162817glActiveTexture(GL_TEXTURE2);2818glBindTexture(texture_target, texture_storage->texture_get_texid(color_correction_texture));2819glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);2820glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);2821glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);2822glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);2823glTexParameteri(texture_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);2824}2825}2826}28272828if (view_count == 1) {2829// Resolve if needed.2830if (fbo_msaa_3d != 0 && msaa3d_needs_resolve) {2831// We can use blit to copy things over2832glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_msaa_3d);28332834if (fbo_int != 0) {2835// We can't combine resolve and scaling, so resolve into our internal buffer2836glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_int);2837} else {2838glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_rt);2839}2840glBlitFramebuffer(0, 0, internal_size.x, internal_size.y, 0, 0, internal_size.x, internal_size.y, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);2841}28422843// Rendered to intermediate buffer, must copy to our render target2844if (fbo_int != 0) {2845// Apply glow/bloom if requested? then populate our glow buffers2846GLuint color = fbo_int != 0 ? rb->get_internal_color() : texture_storage->render_target_get_color(render_target);2847const GLES3::Glow::GLOWLEVEL *glow_buffers = nullptr;2848if (glow_enabled) {2849glow_buffers = rb->get_glow_buffers();28502851glow->set_luminance_multiplier(p_render_data->luminance_multiplier);28522853glow->set_intensity(glow_intensity);2854glow->set_glow_bloom(glow_bloom);2855glow->set_glow_hdr_bleed_threshold(glow_hdr_bleed_threshold);2856glow->set_glow_hdr_bleed_scale(glow_hdr_bleed_scale);2857glow->set_glow_hdr_luminance_cap(glow_hdr_luminance_cap);28582859glow->process_glow(color, internal_size, glow_buffers);2860}28612862// Copy color buffer2863post_effects->post_copy(fbo_rt, target_size, color, internal_size, p_render_data->luminance_multiplier, glow_buffers, glow_intensity, 0, false, bcs_spec_constants);28642865// Copy depth buffer2866glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_int);2867glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_rt);2868glBlitFramebuffer(0, 0, internal_size.x, internal_size.y, 0, 0, target_size.x, target_size.y, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);2869}28702871glBindFramebuffer(GL_FRAMEBUFFER, fbo_rt);2872} else if ((fbo_msaa_3d != 0 && msaa3d_needs_resolve) || (fbo_int != 0)) {2873// TODO investigate if it's smarter to cache these FBOs2874GLuint fbos[3]; // read, write and post2875glGenFramebuffers(3, fbos);28762877// Resolve if needed.2878if (fbo_msaa_3d != 0 && msaa3d_needs_resolve) {2879GLuint read_color = rb->get_msaa3d_color();2880GLuint read_depth = rb->get_msaa3d_depth();2881GLuint write_color = 0;2882GLuint write_depth = 0;28832884if (fbo_int != 0) {2885write_color = rb->get_internal_color();2886write_depth = rb->get_internal_depth();2887} else {2888write_color = texture_storage->render_target_get_color(render_target);2889write_depth = texture_storage->render_target_get_depth(render_target);2890}28912892glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[0]);2893glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]);28942895for (uint32_t v = 0; v < view_count; v++) {2896glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, read_color, 0, v);2897glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, read_depth, 0, v);2898glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, write_color, 0, v);2899glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, write_depth, 0, v);2900glBlitFramebuffer(0, 0, internal_size.x, internal_size.y, 0, 0, internal_size.x, internal_size.y, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);2901}2902}29032904// Rendered to intermediate buffer, must copy to our render target2905if (fbo_int != 0) {2906// Apply glow/bloom if requested? then populate our glow buffers2907const GLES3::Glow::GLOWLEVEL *glow_buffers = nullptr;2908GLuint source_color = fbo_int != 0 ? rb->get_internal_color() : texture_storage->render_target_get_color(render_target);29092910if (glow_enabled) {2911glow_buffers = rb->get_glow_buffers();29122913glow->set_luminance_multiplier(p_render_data->luminance_multiplier);29142915glow->set_intensity(glow_intensity);2916glow->set_glow_bloom(glow_bloom);2917glow->set_glow_hdr_bleed_threshold(glow_hdr_bleed_threshold);2918glow->set_glow_hdr_bleed_scale(glow_hdr_bleed_scale);2919glow->set_glow_hdr_luminance_cap(glow_hdr_luminance_cap);2920}29212922GLuint write_color = texture_storage->render_target_get_color(render_target);29232924for (uint32_t v = 0; v < view_count; v++) {2925if (glow_enabled) {2926glow->process_glow(source_color, internal_size, glow_buffers, v, true);2927}29282929glBindFramebuffer(GL_FRAMEBUFFER, fbos[2]);2930glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, write_color, 0, v);2931post_effects->post_copy(fbos[2], target_size, source_color, internal_size, p_render_data->luminance_multiplier, glow_buffers, glow_intensity, v, true, bcs_spec_constants);2932}29332934// Copy depth2935GLuint read_depth = rb->get_internal_depth();2936GLuint write_depth = texture_storage->render_target_get_depth(render_target);29372938glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[0]);2939glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]);29402941for (uint32_t v = 0; v < view_count; v++) {2942glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, read_depth, 0, v);2943glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, write_depth, 0, v);29442945glBlitFramebuffer(0, 0, internal_size.x, internal_size.y, 0, 0, target_size.x, target_size.y, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);2946}2947}29482949glBindFramebuffer(GL_FRAMEBUFFER, fbo_rt);2950glDeleteFramebuffers(3, fbos);2951}29522953glActiveTexture(GL_TEXTURE2);2954glBindTexture(GL_TEXTURE_2D, 0);2955}29562957template <PassMode p_pass_mode>2958void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, const RenderDataGLES3 *p_render_data, uint32_t p_from_element, uint32_t p_to_element, bool p_alpha_pass) {2959GLES3::MeshStorage *mesh_storage = GLES3::MeshStorage::get_singleton();2960GLES3::ParticlesStorage *particles_storage = GLES3::ParticlesStorage::get_singleton();2961GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();29622963GLuint prev_vertex_array_gl = 0;2964GLuint prev_index_array_gl = 0;29652966GLES3::SceneMaterialData *prev_material_data = nullptr;2967GLES3::SceneShaderData *prev_shader = nullptr;2968GeometryInstanceGLES3 *prev_inst = nullptr;2969SceneShaderGLES3::ShaderVariant prev_variant = SceneShaderGLES3::ShaderVariant::MODE_COLOR;2970SceneShaderGLES3::ShaderVariant shader_variant = SceneShaderGLES3::MODE_COLOR; // Assigned to silence wrong -Wmaybe-initialized2971uint64_t prev_spec_constants = 0;29722973// Specializations constants used by all instances in the scene.2974uint64_t base_spec_constants = p_params->spec_constant_base_flags;29752976if constexpr (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) {2977GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();2978GLES3::Config *config = GLES3::Config::get_singleton();2979glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 2);2980GLuint texture_to_bind = texture_storage->get_texture(texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_CUBEMAP_BLACK))->tex_id;2981if (p_render_data->environment.is_valid()) {2982Sky *sky = sky_owner.get_or_null(environment_get_sky(p_render_data->environment));2983if (sky && sky->radiance != 0) {2984texture_to_bind = sky->radiance;2985base_spec_constants |= SceneShaderGLES3::USE_RADIANCE_MAP;2986}2987glBindTexture(GL_TEXTURE_CUBE_MAP, texture_to_bind);2988}29892990} else if constexpr (p_pass_mode == PASS_MODE_DEPTH || p_pass_mode == PASS_MODE_SHADOW) {2991shader_variant = SceneShaderGLES3::MODE_DEPTH;2992}29932994if (p_render_data->view_count > 1) {2995base_spec_constants |= SceneShaderGLES3::USE_MULTIVIEW;2996}29972998bool should_request_redraw = false;2999if constexpr (p_pass_mode != PASS_MODE_DEPTH) {3000// Don't count elements during depth pre-pass to match the RD renderers.3001if (p_render_data->render_info) {3002p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] += p_to_element - p_from_element;3003}3004}30053006for (uint32_t i = p_from_element; i < p_to_element; i++) {3007GeometryInstanceSurface *surf = p_params->elements[i];3008GeometryInstanceGLES3 *inst = surf->owner;30093010if (p_pass_mode == PASS_MODE_COLOR && !(surf->flags & GeometryInstanceSurface::FLAG_PASS_OPAQUE)) {3011continue; // Objects with "Depth-prepass" transparency are included in both render lists, but should only be rendered in the transparent pass3012}30133014if (inst->instance_count == 0) {3015continue;3016}30173018GLES3::SceneShaderData *shader;3019GLES3::SceneMaterialData *material_data;3020void *mesh_surface;30213022if constexpr (p_pass_mode == PASS_MODE_SHADOW) {3023shader = surf->shader_shadow;3024material_data = surf->material_shadow;3025mesh_surface = surf->surface_shadow;3026} else {3027if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW)) {3028material_data = overdraw_material_data_ptr;3029shader = material_data->shader_data;3030} else if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING)) {3031material_data = default_material_data_ptr;3032shader = material_data->shader_data;3033} else {3034shader = surf->shader;3035material_data = surf->material;3036}3037mesh_surface = surf->surface;3038}30393040if (!mesh_surface) {3041continue;3042}30433044//request a redraw if one of the shaders uses TIME3045if (shader->uses_time) {3046should_request_redraw = true;3047}30483049if constexpr (p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) {3050scene_state.enable_gl_depth_test(shader->depth_test != GLES3::SceneShaderData::DEPTH_TEST_DISABLED);3051}30523053if (shader->depth_test == GLES3::SceneShaderData::DEPTH_TEST_ENABLED_INVERTED) {3054scene_state.set_gl_depth_func(GL_LESS);3055} else {3056scene_state.set_gl_depth_func(GL_GEQUAL);3057}30583059if constexpr (p_pass_mode != PASS_MODE_SHADOW) {3060if (shader->depth_draw == GLES3::SceneShaderData::DEPTH_DRAW_OPAQUE) {3061scene_state.enable_gl_depth_draw((p_pass_mode == PASS_MODE_COLOR && !GLES3::Config::get_singleton()->use_depth_prepass) || p_pass_mode == PASS_MODE_DEPTH);3062} else {3063scene_state.enable_gl_depth_draw(shader->depth_draw == GLES3::SceneShaderData::DEPTH_DRAW_ALWAYS);3064}3065}30663067bool uses_additive_lighting = (inst->light_passes.size() + p_render_data->directional_shadow_count) > 0;3068uses_additive_lighting = uses_additive_lighting && !shader->unshaded;30693070// TODOS3071/*3072* Still a bug when atlas space is limited. Somehow need to evict light when it doesn't have a spot on the atlas, current check isn't enough3073* Disable depth draw3074*/30753076for (int32_t pass = 0; pass < MAX(1, int32_t(inst->light_passes.size() + p_render_data->directional_shadow_count)); pass++) {3077if constexpr (p_pass_mode == PASS_MODE_DEPTH || p_pass_mode == PASS_MODE_SHADOW) {3078if (pass > 0) {3079// Don't render shadow passes when doing depth or shadow pass.3080break;3081}3082}30833084// Stencil.3085if (p_pass_mode != PASS_MODE_DEPTH && shader->stencil_enabled) {3086static const GLenum stencil_compare_table[GLES3::SceneShaderData::STENCIL_COMPARE_MAX] = {3087GL_LESS,3088GL_EQUAL,3089GL_LEQUAL,3090GL_GREATER,3091GL_NOTEQUAL,3092GL_GEQUAL,3093GL_ALWAYS,3094};30953096GLenum stencil_compare = stencil_compare_table[shader->stencil_compare];3097GLuint stencil_compare_mask = 0;3098GLuint stencil_write_mask = 0;3099GLenum stencil_op_dpfail = GL_KEEP;3100GLenum stencil_op_dppass = GL_KEEP;31013102if (shader->stencil_flags & GLES3::SceneShaderData::STENCIL_FLAG_READ) {3103stencil_compare_mask = 255;3104}31053106if (shader->stencil_flags & GLES3::SceneShaderData::STENCIL_FLAG_WRITE) {3107stencil_op_dppass = GL_REPLACE;3108stencil_write_mask = 255;3109}31103111if (shader->stencil_flags & GLES3::SceneShaderData::STENCIL_FLAG_WRITE_DEPTH_FAIL) {3112stencil_op_dpfail = GL_REPLACE;3113stencil_write_mask = 255;3114}31153116scene_state.enable_gl_stencil_test(true);3117scene_state.set_gl_stencil_func(stencil_compare, shader->stencil_reference, stencil_compare_mask);3118scene_state.set_gl_stencil_write_mask(stencil_write_mask);3119scene_state.set_gl_stencil_op(GL_KEEP, stencil_op_dpfail, stencil_op_dppass);3120} else {3121scene_state.enable_gl_stencil_test(false);3122}31233124if constexpr (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) {3125if (!uses_additive_lighting && pass == 1) {3126// Don't render additive passes if not using additive lighting.3127break;3128}3129if (uses_additive_lighting && pass == 1 && !p_render_data->transparent_bg) {3130// Enable blending if in opaque pass and not already enabled.3131scene_state.enable_gl_blend(true);3132}3133if (pass < int32_t(inst->light_passes.size())) {3134RID light_instance_rid = inst->light_passes[pass].light_instance_rid;3135if (!GLES3::LightStorage::get_singleton()->light_instance_has_shadow_atlas(light_instance_rid, p_render_data->shadow_atlas)) {3136// Shadow wasn't able to get a spot on the atlas. So skip it.3137continue;3138}3139} else if (pass > 0) {3140uint32_t shadow_id = MAX_DIRECTIONAL_LIGHTS - 1 - (pass - int32_t(inst->light_passes.size()));3141if (inst->lightmap_instance.is_valid() && scene_state.directional_lights[shadow_id].bake_mode == RenderingServer::LIGHT_BAKE_STATIC) {3142// Skip shadows for static lights on meshes with a lightmap.3143continue;3144}3145}3146}31473148if constexpr (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) {3149GLES3::SceneShaderData::BlendMode desired_blend_mode;3150if (pass > 0) {3151desired_blend_mode = GLES3::SceneShaderData::BLEND_MODE_ADD;3152} else {3153desired_blend_mode = shader->blend_mode;3154}31553156if (desired_blend_mode != scene_state.current_blend_mode) {3157switch (desired_blend_mode) {3158case GLES3::SceneShaderData::BLEND_MODE_MIX: {3159glBlendEquation(GL_FUNC_ADD);3160if (p_render_data->transparent_bg) {3161glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);3162} else {3163glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);3164}31653166} break;3167case GLES3::SceneShaderData::BLEND_MODE_ADD: {3168glBlendEquation(GL_FUNC_ADD);3169glBlendFunc(p_pass_mode == PASS_MODE_COLOR_TRANSPARENT ? GL_SRC_ALPHA : GL_ONE, GL_ONE);31703171} break;3172case GLES3::SceneShaderData::BLEND_MODE_SUB: {3173glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);3174glBlendFunc(GL_SRC_ALPHA, GL_ONE);31753176} break;3177case GLES3::SceneShaderData::BLEND_MODE_MUL: {3178glBlendEquation(GL_FUNC_ADD);3179if (p_render_data->transparent_bg) {3180glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_DST_ALPHA, GL_ZERO);3181} else {3182glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_ZERO, GL_ONE);3183}31843185} break;3186case GLES3::SceneShaderData::BLEND_MODE_PREMULT_ALPHA: {3187glBlendEquation(GL_FUNC_ADD);3188glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);31893190} break;3191case GLES3::SceneShaderData::BLEND_MODE_ALPHA_TO_COVERAGE: {3192// Do nothing for now.3193} break;3194}3195scene_state.current_blend_mode = desired_blend_mode;3196}3197}31983199// Find cull variant.3200RS::CullMode cull_mode = shader->cull_mode;32013202if (p_pass_mode == PASS_MODE_MATERIAL || (surf->flags & GeometryInstanceSurface::FLAG_USES_DOUBLE_SIDED_SHADOWS)) {3203cull_mode = RS::CULL_MODE_DISABLED;3204} else {3205bool mirror = inst->mirror;3206if (p_params->reverse_cull) {3207mirror = !mirror;3208}3209if (cull_mode == RS::CULL_MODE_FRONT && mirror) {3210cull_mode = RS::CULL_MODE_BACK;3211} else if (cull_mode == RS::CULL_MODE_BACK && mirror) {3212cull_mode = RS::CULL_MODE_FRONT;3213}3214}32153216scene_state.set_gl_cull_mode(cull_mode);32173218RS::PrimitiveType primitive = surf->primitive;3219if (shader->uses_point_size) {3220primitive = RS::PRIMITIVE_POINTS;3221}3222static const GLenum prim[5] = { GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP };3223GLenum primitive_gl = prim[int(primitive)];32243225GLuint vertex_array_gl = 0;3226GLuint index_array_gl = 0;3227uint64_t vertex_input_mask = shader->vertex_input_mask;3228if (inst->lightmap_instance.is_valid() || p_pass_mode == PASS_MODE_MATERIAL) {3229vertex_input_mask |= 1 << RS::ARRAY_TEX_UV2;3230}32313232// Skeleton and blend shapes.3233if (surf->owner->mesh_instance.is_valid()) {3234mesh_storage->mesh_instance_surface_get_vertex_arrays_and_format(surf->owner->mesh_instance, surf->surface_index, vertex_input_mask, vertex_array_gl);3235} else {3236mesh_storage->mesh_surface_get_vertex_arrays_and_format(mesh_surface, vertex_input_mask, vertex_array_gl);3237}32383239index_array_gl = mesh_storage->mesh_surface_get_index_buffer(mesh_surface, surf->lod_index);32403241if (prev_vertex_array_gl != vertex_array_gl) {3242if (vertex_array_gl != 0) {3243glBindVertexArray(vertex_array_gl);3244}3245prev_vertex_array_gl = vertex_array_gl;32463247// Invalidate the previous index array3248prev_index_array_gl = 0;3249}32503251bool use_wireframe = false;3252if (p_params->force_wireframe || shader->wireframe) {3253GLuint wireframe_index_array_gl = mesh_storage->mesh_surface_get_index_buffer_wireframe(mesh_surface);3254if (wireframe_index_array_gl) {3255index_array_gl = wireframe_index_array_gl;3256use_wireframe = true;3257}3258}32593260bool use_index_buffer = index_array_gl != 0;3261if (prev_index_array_gl != index_array_gl) {3262if (index_array_gl != 0) {3263// Bind index each time so we can use LODs3264glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_gl);3265}3266prev_index_array_gl = index_array_gl;3267}32683269Transform3D world_transform;3270if (inst->store_transform_cache) {3271world_transform = inst->transform;3272}32733274if (prev_material_data != material_data) {3275material_data->bind_uniforms();3276prev_material_data = material_data;3277}32783279SceneShaderGLES3::ShaderVariant instance_variant = shader_variant;32803281if (inst->instance_count > 0) {3282// Will need to use instancing to draw (either MultiMesh or Particles).3283instance_variant = SceneShaderGLES3::ShaderVariant(1 + int(instance_variant));3284}32853286uint64_t spec_constants = base_spec_constants;32873288// Set up spec constants for lighting.3289if constexpr (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) {3290// Only check during color passes as light shader code is compiled out during depth-only pass anyway.32913292if (pass == 0) {3293spec_constants |= SceneShaderGLES3::BASE_PASS;32943295if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {3296spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_OMNI;3297spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_SPOT;3298spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL;3299spec_constants |= SceneShaderGLES3::DISABLE_LIGHTMAP;3300} else {3301if (inst->omni_light_gl_cache.is_empty()) {3302spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_OMNI;3303}33043305if (inst->spot_light_gl_cache.is_empty()) {3306spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_SPOT;3307}33083309if (p_render_data->directional_light_count == p_render_data->directional_shadow_count) {3310spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL;3311}33123313if (inst->reflection_probe_rid_cache.is_empty()) {3314// We don't have any probes.3315spec_constants |= SceneShaderGLES3::DISABLE_REFLECTION_PROBE;3316} else if (inst->reflection_probe_rid_cache.size() > 1) {3317// We have a second probe.3318spec_constants |= SceneShaderGLES3::SECOND_REFLECTION_PROBE;3319}33203321if (inst->lightmap_instance.is_valid()) {3322spec_constants |= SceneShaderGLES3::USE_LIGHTMAP;33233324GLES3::LightmapInstance *li = GLES3::LightStorage::get_singleton()->get_lightmap_instance(inst->lightmap_instance);3325GLES3::Lightmap *lm = GLES3::LightStorage::get_singleton()->get_lightmap(li->lightmap);33263327if (lm->uses_spherical_harmonics) {3328spec_constants |= SceneShaderGLES3::USE_SH_LIGHTMAP;3329}33303331if (lightmap_bicubic_upscale) {3332spec_constants |= SceneShaderGLES3::LIGHTMAP_BICUBIC_FILTER;3333}3334} else if (inst->lightmap_sh) {3335spec_constants |= SceneShaderGLES3::USE_LIGHTMAP_CAPTURE;3336} else {3337spec_constants |= SceneShaderGLES3::DISABLE_LIGHTMAP;3338}3339}3340} else {3341// Only base pass uses the radiance map.3342spec_constants &= ~SceneShaderGLES3::USE_RADIANCE_MAP;3343spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_OMNI;3344spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_SPOT;3345spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL;3346spec_constants |= SceneShaderGLES3::DISABLE_REFLECTION_PROBE;33473348bool disable_lightmaps = true;33493350// Additive directional passes may use shadowmasks, so enable lightmaps for them.3351if (pass >= int32_t(inst->light_passes.size()) && inst->lightmap_instance.is_valid()) {3352GLES3::LightmapInstance *li = GLES3::LightStorage::get_singleton()->get_lightmap_instance(inst->lightmap_instance);3353GLES3::Lightmap *lm = GLES3::LightStorage::get_singleton()->get_lightmap(li->lightmap);33543355if (lm->shadowmask_mode != RS::SHADOWMASK_MODE_NONE) {3356spec_constants |= SceneShaderGLES3::USE_LIGHTMAP;3357disable_lightmaps = false;33583359if (lightmap_bicubic_upscale) {3360spec_constants |= SceneShaderGLES3::LIGHTMAP_BICUBIC_FILTER;3361}3362}3363}33643365if (disable_lightmaps) {3366spec_constants |= SceneShaderGLES3::DISABLE_LIGHTMAP;3367}3368}33693370if (uses_additive_lighting) {3371spec_constants |= SceneShaderGLES3::USE_ADDITIVE_LIGHTING;33723373if (pass < int32_t(inst->light_passes.size())) {3374// Rendering positional lights.3375if (inst->light_passes[pass].is_omni) {3376spec_constants |= SceneShaderGLES3::ADDITIVE_OMNI;3377} else {3378spec_constants |= SceneShaderGLES3::ADDITIVE_SPOT;3379}33803381if (scene_state.positional_shadow_quality >= RS::SHADOW_QUALITY_SOFT_HIGH) {3382spec_constants |= SceneShaderGLES3::SHADOW_MODE_PCF_13;3383} else if (scene_state.positional_shadow_quality >= RS::SHADOW_QUALITY_SOFT_LOW) {3384spec_constants |= SceneShaderGLES3::SHADOW_MODE_PCF_5;3385}3386} else {3387// Render directional lights.33883389uint32_t shadow_id = MAX_DIRECTIONAL_LIGHTS - 1 - (pass - int32_t(inst->light_passes.size()));3390if (pass == 0 && inst->lightmap_instance.is_valid() && scene_state.directional_lights[shadow_id].bake_mode == RenderingServer::LIGHT_BAKE_STATIC) {3391// Disable additive lighting with a static light and a lightmap.3392spec_constants &= ~SceneShaderGLES3::USE_ADDITIVE_LIGHTING;3393}3394if (scene_state.directional_shadows[shadow_id].shadow_split_offsets[0] == scene_state.directional_shadows[shadow_id].shadow_split_offsets[1]) {3395// Orthogonal, do nothing.3396} else if (scene_state.directional_shadows[shadow_id].shadow_split_offsets[1] == scene_state.directional_shadows[shadow_id].shadow_split_offsets[2]) {3397spec_constants |= SceneShaderGLES3::LIGHT_USE_PSSM2;3398} else {3399spec_constants |= SceneShaderGLES3::LIGHT_USE_PSSM4;3400}34013402if (scene_state.directional_shadows[shadow_id].blend_splits) {3403spec_constants |= SceneShaderGLES3::LIGHT_USE_PSSM_BLEND;3404}34053406if (scene_state.directional_shadow_quality >= RS::SHADOW_QUALITY_SOFT_HIGH) {3407spec_constants |= SceneShaderGLES3::SHADOW_MODE_PCF_13;3408} else if (scene_state.directional_shadow_quality >= RS::SHADOW_QUALITY_SOFT_LOW) {3409spec_constants |= SceneShaderGLES3::SHADOW_MODE_PCF_5;3410}3411}3412}3413}34143415if (prev_shader != shader || prev_variant != instance_variant || spec_constants != prev_spec_constants) {3416bool success = material_storage->shaders.scene_shader.version_bind_shader(shader->version, instance_variant, spec_constants);3417if (!success) {3418break;3419}34203421float opaque_prepass_threshold = 0.0;3422if constexpr (p_pass_mode == PASS_MODE_DEPTH) {3423opaque_prepass_threshold = 0.99;3424} else if constexpr (p_pass_mode == PASS_MODE_SHADOW) {3425opaque_prepass_threshold = 0.1;3426}34273428material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::OPAQUE_PREPASS_THRESHOLD, opaque_prepass_threshold, shader->version, instance_variant, spec_constants);3429}34303431// Pass in lighting uniforms.3432if constexpr (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) {3433GLES3::Config *config = GLES3::Config::get_singleton();3434// Pass light and shadow index and bind shadow texture.3435if (uses_additive_lighting) {3436if (pass < int32_t(inst->light_passes.size())) {3437int32_t shadow_id = inst->light_passes[pass].shadow_id;3438if (shadow_id >= 0) {3439uint32_t light_id = inst->light_passes[pass].light_id;3440bool is_omni = inst->light_passes[pass].is_omni;3441SceneShaderGLES3::Uniforms uniform_name = is_omni ? SceneShaderGLES3::OMNI_LIGHT_INDEX : SceneShaderGLES3::SPOT_LIGHT_INDEX;3442material_storage->shaders.scene_shader.version_set_uniform(uniform_name, uint32_t(light_id), shader->version, instance_variant, spec_constants);3443material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::POSITIONAL_SHADOW_INDEX, uint32_t(shadow_id), shader->version, instance_variant, spec_constants);34443445glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 3);3446RID light_instance_rid = inst->light_passes[pass].light_instance_rid;34473448GLuint tex = GLES3::LightStorage::get_singleton()->light_instance_get_shadow_texture(light_instance_rid, p_render_data->shadow_atlas);3449if (is_omni) {3450glBindTexture(GL_TEXTURE_CUBE_MAP, tex);3451} else {3452glBindTexture(GL_TEXTURE_2D, tex);3453}3454}3455} else {3456uint32_t shadow_id = MAX_DIRECTIONAL_LIGHTS - 1 - (pass - int32_t(inst->light_passes.size()));3457material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::DIRECTIONAL_SHADOW_INDEX, shadow_id, shader->version, instance_variant, spec_constants);34583459GLuint tex = GLES3::LightStorage::get_singleton()->directional_shadow_get_texture();3460glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 3);3461glBindTexture(GL_TEXTURE_2D, tex);34623463if (inst->lightmap_instance.is_valid()) {3464// Use shadowmasks for directional light passes.3465GLES3::LightmapInstance *li = GLES3::LightStorage::get_singleton()->get_lightmap_instance(inst->lightmap_instance);3466GLES3::Lightmap *lm = GLES3::LightStorage::get_singleton()->get_lightmap(li->lightmap);34673468material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::LIGHTMAP_SLICE, inst->lightmap_slice_index, shader->version, instance_variant, spec_constants);34693470Vector4 uv_scale(inst->lightmap_uv_scale.position.x, inst->lightmap_uv_scale.position.y, inst->lightmap_uv_scale.size.x, inst->lightmap_uv_scale.size.y);3471material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::LIGHTMAP_UV_SCALE, uv_scale, shader->version, instance_variant, spec_constants);34723473if (lightmap_bicubic_upscale) {3474Vector2 light_texture_size(lm->light_texture_size.x, lm->light_texture_size.y);3475material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::LIGHTMAP_TEXTURE_SIZE, light_texture_size, shader->version, instance_variant, spec_constants);3476}34773478material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::LIGHTMAP_SHADOWMASK_MODE, (uint32_t)lm->shadowmask_mode, shader->version, instance_variant, spec_constants);34793480if (lm->shadow_texture.is_valid()) {3481tex = GLES3::TextureStorage::get_singleton()->texture_get_texid(lm->shadow_texture);3482} else {3483tex = GLES3::TextureStorage::get_singleton()->texture_get_texid(GLES3::TextureStorage::get_singleton()->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_2D_ARRAY_WHITE));3484}34853486glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 5);3487glBindTexture(GL_TEXTURE_2D_ARRAY, tex);3488}3489}3490}34913492// Pass light count and array of light indices for base pass.3493if ((prev_inst != inst || prev_shader != shader || prev_variant != instance_variant || prev_spec_constants != spec_constants) && pass == 0) {3494// Rebind the light indices.3495material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::OMNI_LIGHT_COUNT, inst->omni_light_gl_cache.size(), shader->version, instance_variant, spec_constants);3496material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::SPOT_LIGHT_COUNT, inst->spot_light_gl_cache.size(), shader->version, instance_variant, spec_constants);34973498if (inst->omni_light_gl_cache.size()) {3499glUniform1uiv(material_storage->shaders.scene_shader.version_get_uniform(SceneShaderGLES3::OMNI_LIGHT_INDICES, shader->version, instance_variant, spec_constants), inst->omni_light_gl_cache.size(), inst->omni_light_gl_cache.ptr());3500}35013502if (inst->spot_light_gl_cache.size()) {3503glUniform1uiv(material_storage->shaders.scene_shader.version_get_uniform(SceneShaderGLES3::SPOT_LIGHT_INDICES, shader->version, instance_variant, spec_constants), inst->spot_light_gl_cache.size(), inst->spot_light_gl_cache.ptr());3504}35053506if (inst->lightmap_instance.is_valid()) {3507GLES3::LightmapInstance *li = GLES3::LightStorage::get_singleton()->get_lightmap_instance(inst->lightmap_instance);3508GLES3::Lightmap *lm = GLES3::LightStorage::get_singleton()->get_lightmap(li->lightmap);35093510GLuint tex = GLES3::TextureStorage::get_singleton()->texture_get_texid(lm->light_texture);3511glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 4);3512glBindTexture(GL_TEXTURE_2D_ARRAY, tex);35133514material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::LIGHTMAP_SLICE, inst->lightmap_slice_index, shader->version, instance_variant, spec_constants);35153516Vector4 uv_scale(inst->lightmap_uv_scale.position.x, inst->lightmap_uv_scale.position.y, inst->lightmap_uv_scale.size.x, inst->lightmap_uv_scale.size.y);3517material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::LIGHTMAP_UV_SCALE, uv_scale, shader->version, instance_variant, spec_constants);35183519if (lightmap_bicubic_upscale) {3520Vector2 light_texture_size(lm->light_texture_size.x, lm->light_texture_size.y);3521material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::LIGHTMAP_TEXTURE_SIZE, light_texture_size, shader->version, instance_variant, spec_constants);3522}35233524float exposure_normalization = 1.0;3525if (p_render_data->camera_attributes.is_valid()) {3526float enf = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);3527exposure_normalization = enf / lm->baked_exposure;3528}3529material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::LIGHTMAP_EXPOSURE_NORMALIZATION, exposure_normalization, shader->version, instance_variant, spec_constants);35303531if (lm->uses_spherical_harmonics) {3532Basis to_lm = li->transform.basis.inverse() * p_render_data->cam_transform.basis;3533to_lm = to_lm.inverse().transposed();3534GLfloat matrix[9] = {3535(GLfloat)to_lm.rows[0][0],3536(GLfloat)to_lm.rows[1][0],3537(GLfloat)to_lm.rows[2][0],3538(GLfloat)to_lm.rows[0][1],3539(GLfloat)to_lm.rows[1][1],3540(GLfloat)to_lm.rows[2][1],3541(GLfloat)to_lm.rows[0][2],3542(GLfloat)to_lm.rows[1][2],3543(GLfloat)to_lm.rows[2][2],3544};3545glUniformMatrix3fv(material_storage->shaders.scene_shader.version_get_uniform(SceneShaderGLES3::LIGHTMAP_NORMAL_XFORM, shader->version, instance_variant, spec_constants), 1, GL_FALSE, matrix);3546}35473548} else if (inst->lightmap_sh) {3549glUniform4fv(material_storage->shaders.scene_shader.version_get_uniform(SceneShaderGLES3::LIGHTMAP_CAPTURES, shader->version, instance_variant, spec_constants), 9, reinterpret_cast<const GLfloat *>(inst->lightmap_sh->sh));3550}3551prev_inst = inst;3552}3553}35543555prev_shader = shader;3556prev_variant = instance_variant;3557prev_spec_constants = spec_constants;35583559// Pass in reflection probe data3560if constexpr (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) {3561if (pass == 0 && inst->reflection_probe_rid_cache.size() > 0) {3562GLES3::Config *config = GLES3::Config::get_singleton();3563GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton();35643565// Setup first probe.3566{3567RID probe_rid = light_storage->reflection_probe_instance_get_probe(inst->reflection_probe_rid_cache[0]);3568GLES3::ReflectionProbe *probe = light_storage->get_reflection_probe(probe_rid);35693570material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE1_USE_BOX_PROJECT, probe->box_projection, shader->version, instance_variant, spec_constants);3571material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE1_BOX_EXTENTS, probe->size * 0.5, shader->version, instance_variant, spec_constants);3572material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE1_BOX_OFFSET, probe->origin_offset, shader->version, instance_variant, spec_constants);3573material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE1_EXTERIOR, !probe->interior, shader->version, instance_variant, spec_constants);3574material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE1_INTENSITY, probe->intensity, shader->version, instance_variant, spec_constants);3575material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE1_AMBIENT_MODE, int(probe->ambient_mode), shader->version, instance_variant, spec_constants);3576material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE1_AMBIENT_COLOR, probe->ambient_color * probe->ambient_color_energy, shader->version, instance_variant, spec_constants);3577material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE1_LOCAL_MATRIX, inst->reflection_probes_local_transform_cache[0], shader->version, instance_variant, spec_constants);3578material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE1_BLEND_DISTANCE, probe->blend_distance, shader->version, instance_variant, spec_constants);35793580glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 8);3581glBindTexture(GL_TEXTURE_CUBE_MAP, light_storage->reflection_probe_instance_get_texture(inst->reflection_probe_rid_cache[0]));3582}35833584if (inst->reflection_probe_rid_cache.size() > 1) {3585// Setup second probe.3586RID probe_rid = light_storage->reflection_probe_instance_get_probe(inst->reflection_probe_rid_cache[1]);3587GLES3::ReflectionProbe *probe = light_storage->get_reflection_probe(probe_rid);35883589material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE2_USE_BOX_PROJECT, probe->box_projection, shader->version, instance_variant, spec_constants);3590material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE2_BOX_EXTENTS, probe->size * 0.5, shader->version, instance_variant, spec_constants);3591material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE2_BOX_OFFSET, probe->origin_offset, shader->version, instance_variant, spec_constants);3592material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE2_EXTERIOR, !probe->interior, shader->version, instance_variant, spec_constants);3593material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE2_INTENSITY, probe->intensity, shader->version, instance_variant, spec_constants);3594material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE2_AMBIENT_MODE, int(probe->ambient_mode), shader->version, instance_variant, spec_constants);3595material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE2_AMBIENT_COLOR, probe->ambient_color * probe->ambient_color_energy, shader->version, instance_variant, spec_constants);3596material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE2_LOCAL_MATRIX, inst->reflection_probes_local_transform_cache[1], shader->version, instance_variant, spec_constants);3597material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE2_BLEND_DISTANCE, probe->blend_distance, shader->version, instance_variant, spec_constants);35983599glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 9);3600glBindTexture(GL_TEXTURE_CUBE_MAP, light_storage->reflection_probe_instance_get_texture(inst->reflection_probe_rid_cache[1]));36013602spec_constants |= SceneShaderGLES3::SECOND_REFLECTION_PROBE;3603}3604}3605}36063607material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, world_transform, shader->version, instance_variant, spec_constants);3608{3609GLES3::Mesh::Surface *s = reinterpret_cast<GLES3::Mesh::Surface *>(surf->surface);3610if (s->format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) {3611material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::COMPRESSED_AABB_POSITION, s->aabb.position, shader->version, instance_variant, spec_constants);3612material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::COMPRESSED_AABB_SIZE, s->aabb.size, shader->version, instance_variant, spec_constants);3613material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::UV_SCALE, s->uv_scale, shader->version, instance_variant, spec_constants);3614} else {3615material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::COMPRESSED_AABB_POSITION, Vector3(0.0, 0.0, 0.0), shader->version, instance_variant, spec_constants);3616material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::COMPRESSED_AABB_SIZE, Vector3(1.0, 1.0, 1.0), shader->version, instance_variant, spec_constants);3617material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::UV_SCALE, Vector4(0.0, 0.0, 0.0, 0.0), shader->version, instance_variant, spec_constants);3618}3619}36203621material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::MODEL_FLAGS, inst->flags_cache, shader->version, instance_variant, spec_constants);3622material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::INSTANCE_OFFSET, uint32_t(inst->shader_uniforms_offset), shader->version, instance_variant, spec_constants);36233624if (p_pass_mode == PASS_MODE_MATERIAL) {3625material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::UV_OFFSET, p_params->uv_offset, shader->version, instance_variant, spec_constants);3626}36273628// Can be index count or vertex count3629uint32_t count = 0;3630if (surf->lod_index > 0) {3631count = surf->index_count;3632} else {3633count = mesh_storage->mesh_surface_get_vertices_drawn_count(mesh_surface);3634}36353636if (use_wireframe) {3637// In this case we are using index count, and we need double the indices for the wireframe mesh.3638count = count * 2;3639}36403641if constexpr (p_pass_mode != PASS_MODE_DEPTH) {3642// Don't count draw calls during depth pre-pass to match the RD renderers.3643if (p_render_data->render_info) {3644p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME]++;3645}3646}36473648if (inst->instance_count > 0) {3649// Using MultiMesh or Particles.3650// Bind instance buffers.36513652GLuint instance_buffer = 0;3653uint32_t stride = 0;3654if (inst->flags_cache & INSTANCE_DATA_FLAG_PARTICLES) {3655instance_buffer = particles_storage->particles_get_gl_buffer(inst->data->base);3656stride = 16; // 12 bytes for instance transform and 4 bytes for packed color and custom.3657} else {3658instance_buffer = mesh_storage->multimesh_get_gl_buffer(inst->data->base);3659stride = mesh_storage->multimesh_get_stride(inst->data->base);3660}36613662if (instance_buffer == 0) {3663// Instance buffer not initialized yet. Skip rendering for now.3664break;3665}36663667glBindBuffer(GL_ARRAY_BUFFER, instance_buffer);36683669glEnableVertexAttribArray(12);3670glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(0));3671glVertexAttribDivisor(12, 1);3672glEnableVertexAttribArray(13);3673glVertexAttribPointer(13, 4, GL_FLOAT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4));3674glVertexAttribDivisor(13, 1);3675if (!(inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D)) {3676glEnableVertexAttribArray(14);3677glVertexAttribPointer(14, 4, GL_FLOAT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(sizeof(float) * 8));3678glVertexAttribDivisor(14, 1);3679}36803681if ((inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR) || (inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA)) {3682uint32_t color_custom_offset = inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D ? 8 : 12;3683glEnableVertexAttribArray(15);3684glVertexAttribIPointer(15, 4, GL_UNSIGNED_INT, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(color_custom_offset * sizeof(float)));3685glVertexAttribDivisor(15, 1);3686} else {3687// Set all default instance color and custom data values to 1.0 or 0.0 using a compressed format.3688uint16_t zero = Math::make_half_float(0.0f);3689uint16_t one = Math::make_half_float(1.0f);3690GLuint default_color = (uint32_t(one) << 16) | one;3691GLuint default_custom = (uint32_t(zero) << 16) | zero;3692glVertexAttribI4ui(15, default_color, default_color, default_custom, default_custom);3693}36943695if (use_wireframe) {3696glDrawElementsInstanced(GL_LINES, count, GL_UNSIGNED_INT, nullptr, inst->instance_count);3697} else {3698if (use_index_buffer) {3699glDrawElementsInstanced(primitive_gl, count, mesh_storage->mesh_surface_get_index_type(mesh_surface), nullptr, inst->instance_count);3700} else {3701glDrawArraysInstanced(primitive_gl, 0, count, inst->instance_count);3702}3703}3704} else {3705// Using regular Mesh.3706if (use_wireframe) {3707glDrawElements(GL_LINES, count, GL_UNSIGNED_INT, nullptr);3708} else {3709if (use_index_buffer) {3710glDrawElements(primitive_gl, count, mesh_storage->mesh_surface_get_index_type(mesh_surface), nullptr);3711} else {3712glDrawArrays(primitive_gl, 0, count);3713}3714}3715}37163717if (inst->instance_count > 0) {3718glDisableVertexAttribArray(12);3719glDisableVertexAttribArray(13);3720glDisableVertexAttribArray(14);3721glDisableVertexAttribArray(15);3722}3723}3724if constexpr (p_pass_mode == PASS_MODE_COLOR) {3725if (uses_additive_lighting && !p_render_data->transparent_bg) {3726// Disable additive blending if enabled for additive lights.3727scene_state.enable_gl_blend(false);3728}3729}3730}37313732// Make the actual redraw request3733if (should_request_redraw) {3734RenderingServerDefault::redraw_request();3735}3736}37373738void RasterizerSceneGLES3::render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {3739}37403741void RasterizerSceneGLES3::render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) {3742GLES3::ParticlesStorage *particles_storage = GLES3::ParticlesStorage::get_singleton();37433744ERR_FAIL_COND(!particles_storage->particles_collision_is_heightfield(p_collider));3745Vector3 extents = particles_storage->particles_collision_get_extents(p_collider) * p_transform.basis.get_scale();3746Projection cm;3747cm.set_orthogonal(-extents.x, extents.x, -extents.z, extents.z, 0, extents.y * 2.0);37483749Vector3 cam_pos = p_transform.origin;3750cam_pos.y += extents.y;37513752Transform3D cam_xform;3753cam_xform.set_look_at(cam_pos, cam_pos - p_transform.basis.get_column(Vector3::AXIS_Y), -p_transform.basis.get_column(Vector3::AXIS_Z).normalized());37543755GLuint fb = particles_storage->particles_collision_get_heightfield_framebuffer(p_collider);3756Size2i fb_size = particles_storage->particles_collision_get_heightfield_size(p_collider);37573758RENDER_TIMESTAMP("Setup GPUParticlesCollisionHeightField3D");37593760RenderDataGLES3 render_data;37613762render_data.cam_projection = cm;3763render_data.cam_transform = cam_xform;3764render_data.view_projection[0] = cm;3765render_data.inv_cam_transform = render_data.cam_transform.affine_inverse();3766render_data.cam_orthogonal = true;3767render_data.z_near = 0.0;3768render_data.z_far = cm.get_z_far();3769render_data.main_cam_transform = cam_xform;37703771render_data.instances = &p_instances;37723773_setup_environment(&render_data, true, Vector2(fb_size), true, Color(), false);37743775PassMode pass_mode = PASS_MODE_SHADOW;37763777_fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode);3778render_list[RENDER_LIST_SECONDARY].sort_by_key();37793780RENDER_TIMESTAMP("Render Collider Heightfield");37813782glBindFramebuffer(GL_FRAMEBUFFER, fb);3783glViewport(0, 0, fb_size.width, fb_size.height);37843785GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_shader_parameters_get_uniform_buffer();37863787glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_GLOBALS_UNIFORM_LOCATION, global_buffer);3788glBindBuffer(GL_UNIFORM_BUFFER, 0);37893790scene_state.reset_gl_state();3791scene_state.enable_gl_depth_test(true);3792scene_state.enable_gl_depth_draw(true);3793scene_state.set_gl_depth_func(GL_GREATER);37943795glDrawBuffers(0, nullptr);37963797glColorMask(0, 0, 0, 0);3798RasterizerGLES3::clear_depth(0.0);37993800glClear(GL_DEPTH_BUFFER_BIT);38013802RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), false, 31, false);38033804_render_list_template<PASS_MODE_SHADOW>(&render_list_params, &render_data, 0, render_list[RENDER_LIST_SECONDARY].elements.size());38053806glColorMask(1, 1, 1, 1);3807glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);3808}38093810void RasterizerSceneGLES3::_render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, GLuint p_framebuffer, const Rect2i &p_region) {3811RENDER_TIMESTAMP("Setup Rendering UV2");38123813RenderDataGLES3 render_data;3814render_data.instances = &p_instances;38153816scene_state.ubo.emissive_exposure_normalization = -1.0; // Use default exposure normalization.38173818_setup_environment(&render_data, true, Vector2(1, 1), true, Color(), false);38193820PassMode pass_mode = PASS_MODE_MATERIAL;38213822_fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode);3823render_list[RENDER_LIST_SECONDARY].sort_by_key();38243825RENDER_TIMESTAMP("Render 3D Material");38263827{3828glBindFramebuffer(GL_FRAMEBUFFER, p_framebuffer);3829glViewport(p_region.position.x, p_region.position.y, p_region.size.x, p_region.size.y);38303831GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_shader_parameters_get_uniform_buffer();38323833glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_GLOBALS_UNIFORM_LOCATION, global_buffer);3834glBindBuffer(GL_UNIFORM_BUFFER, 0);38353836scene_state.reset_gl_state();3837scene_state.enable_gl_depth_test(true);3838scene_state.enable_gl_depth_draw(true);3839scene_state.set_gl_depth_func(GL_GREATER);38403841TightLocalVector<GLenum> draw_buffers;3842draw_buffers.push_back(GL_COLOR_ATTACHMENT0);3843draw_buffers.push_back(GL_COLOR_ATTACHMENT1);3844draw_buffers.push_back(GL_COLOR_ATTACHMENT2);3845draw_buffers.push_back(GL_COLOR_ATTACHMENT3);3846glDrawBuffers(draw_buffers.size(), draw_buffers.ptr());38473848glClearColor(0.0, 0.0, 0.0, 0.0);3849RasterizerGLES3::clear_depth(0.0);3850glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);38513852uint64_t base_spec_constant = 0;3853base_spec_constant |= SceneShaderGLES3::RENDER_MATERIAL;3854base_spec_constant |= SceneShaderGLES3::DISABLE_FOG;3855base_spec_constant |= SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL;3856base_spec_constant |= SceneShaderGLES3::DISABLE_LIGHT_OMNI;3857base_spec_constant |= SceneShaderGLES3::DISABLE_LIGHT_SPOT;3858base_spec_constant |= SceneShaderGLES3::DISABLE_LIGHTMAP;38593860RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), false, base_spec_constant, true, Vector2(0, 0));38613862const int uv_offset_count = 9;3863static const Vector2 uv_offsets[uv_offset_count] = {3864Vector2(-1, 1),3865Vector2(1, 1),3866Vector2(1, -1),3867Vector2(-1, -1),3868Vector2(-1, 0),3869Vector2(1, 0),3870Vector2(0, -1),3871Vector2(0, 1),3872Vector2(0, 0),3873};38743875for (int i = 0; i < uv_offset_count; i++) {3876Vector2 ofs = uv_offsets[i];3877ofs.x /= p_region.size.width;3878ofs.y /= p_region.size.height;3879render_list_params.uv_offset = ofs;3880_render_list_template<PASS_MODE_MATERIAL>(&render_list_params, &render_data, 0, render_list[RENDER_LIST_SECONDARY].elements.size());3881}38823883render_list_params.uv_offset = Vector2(0, 0);3884render_list_params.force_wireframe = false;3885_render_list_template<PASS_MODE_MATERIAL>(&render_list_params, &render_data, 0, render_list[RENDER_LIST_SECONDARY].elements.size());38863887GLuint db = GL_COLOR_ATTACHMENT0;3888glDrawBuffers(1, &db);3889glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);3890}3891}38923893void RasterizerSceneGLES3::set_time(double p_time, double p_step) {3894time = p_time;3895time_step = p_step;3896}38973898void RasterizerSceneGLES3::set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) {3899debug_draw = p_debug_draw;3900}39013902Ref<RenderSceneBuffers> RasterizerSceneGLES3::render_buffers_create() {3903Ref<RenderSceneBuffersGLES3> rb;3904rb.instantiate();3905return rb;3906}39073908void RasterizerSceneGLES3::_render_buffers_debug_draw(Ref<RenderSceneBuffersGLES3> p_render_buffers, RID p_shadow_atlas, GLuint p_fbo) {3909GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();3910GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton();3911GLES3::CopyEffects *copy_effects = GLES3::CopyEffects::get_singleton();39123913ERR_FAIL_COND(p_render_buffers.is_null());39143915RID render_target = p_render_buffers->render_target;3916GLES3::RenderTarget *rt = texture_storage->get_render_target(render_target);3917ERR_FAIL_NULL(rt);39183919if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SHADOW_ATLAS) {3920if (p_shadow_atlas.is_valid()) {3921// Get or create debug textures to display shadow maps as an atlas.3922GLuint shadow_atlas_texture = light_storage->shadow_atlas_get_debug_texture(p_shadow_atlas);3923GLuint shadow_atlas_fb = light_storage->shadow_atlas_get_debug_fb(p_shadow_atlas);39243925uint32_t shadow_atlas_size = light_storage->shadow_atlas_get_size(p_shadow_atlas);3926uint32_t quadrant_size = shadow_atlas_size >> 1;39273928glBindFramebuffer(GL_FRAMEBUFFER, shadow_atlas_fb);3929glViewport(0, 0, shadow_atlas_size, shadow_atlas_size);3930glActiveTexture(GL_TEXTURE0);3931scene_state.enable_gl_depth_draw(true);3932scene_state.set_gl_depth_func(GL_ALWAYS);3933scene_state.set_gl_cull_mode(RS::CULL_MODE_DISABLED);39343935// Loop through quadrants and copy shadows over.3936for (int quadrant = 0; quadrant < 4; quadrant++) {3937uint32_t subdivision = light_storage->shadow_atlas_get_quadrant_subdivision(p_shadow_atlas, quadrant);3938if (subdivision == 0) {3939continue;3940}39413942Rect2i atlas_rect;3943Rect2 atlas_uv_rect;39443945uint32_t shadow_size = (quadrant_size / subdivision);3946float size = float(shadow_size) / float(shadow_atlas_size);39473948uint32_t length = light_storage->shadow_atlas_get_quadrant_shadows_allocated(p_shadow_atlas, quadrant);3949for (uint32_t shadow_idx = 0; shadow_idx < length; shadow_idx++) {3950bool is_omni = light_storage->shadow_atlas_get_quadrant_shadow_is_omni(p_shadow_atlas, quadrant, shadow_idx);39513952// Calculate shadow's position in the debug atlas.3953atlas_rect.position.x = (quadrant & 1) * quadrant_size;3954atlas_rect.position.y = (quadrant >> 1) * quadrant_size;39553956atlas_rect.position.x += (shadow_idx % subdivision) * shadow_size;3957atlas_rect.position.y += (shadow_idx / subdivision) * shadow_size;39583959atlas_uv_rect.position = Vector2(atlas_rect.position) / float(shadow_atlas_size);39603961atlas_uv_rect.size = Vector2(size, size);39623963GLuint shadow_tex = light_storage->shadow_atlas_get_quadrant_shadow_texture(p_shadow_atlas, quadrant, shadow_idx);3964// Copy from shadowmap to debug atlas.3965if (is_omni) {3966glBindTexture(GL_TEXTURE_CUBE_MAP, shadow_tex);3967glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_NONE);39683969copy_effects->copy_cube_to_rect(atlas_uv_rect);39703971glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);3972glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);3973} else {3974glBindTexture(GL_TEXTURE_2D, shadow_tex);3975glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);39763977copy_effects->copy_to_rect(atlas_uv_rect);39783979glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);3980glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);3981}3982}3983}39843985// Set back to FBO3986glBindFramebuffer(GL_FRAMEBUFFER, p_fbo);3987Size2i size = p_render_buffers->get_internal_size();3988glViewport(0, 0, size.width, size.height);3989glBindTexture(GL_TEXTURE_2D, shadow_atlas_texture);39903991copy_effects->copy_to_rect(Rect2(Vector2(), Vector2(0.5, 0.5)));3992glBindTexture(GL_TEXTURE_2D, 0);3993glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);3994}3995}3996if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS) {3997if (light_storage->directional_shadow_get_texture() != 0) {3998GLuint shadow_atlas_texture = light_storage->directional_shadow_get_texture();3999glActiveTexture(GL_TEXTURE0);4000glBindTexture(GL_TEXTURE_2D, shadow_atlas_texture);4001glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);4002glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);4003glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED);4004glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);4005glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE);40064007scene_state.enable_gl_depth_test(false);4008scene_state.enable_gl_depth_draw(false);40094010copy_effects->copy_to_rect(Rect2(Vector2(), Vector2(0.5, 0.5)));4011glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);4012glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN);4013glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE);4014glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);4015glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);4016glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);4017glBindTexture(GL_TEXTURE_2D, 0);4018}4019}4020}40214022void RasterizerSceneGLES3::gi_set_use_half_resolution(bool p_enable) {4023}40244025void RasterizerSceneGLES3::screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_curve) {4026}40274028bool RasterizerSceneGLES3::screen_space_roughness_limiter_is_active() const {4029return false;4030}40314032void RasterizerSceneGLES3::sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) {4033}40344035void RasterizerSceneGLES3::sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) {4036}40374038TypedArray<Image> RasterizerSceneGLES3::bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size) {4039GLES3::Config *config = GLES3::Config::get_singleton();4040ERR_FAIL_COND_V_MSG(p_image_size.width <= 0, TypedArray<Image>(), "Image width must be greater than 0.");4041ERR_FAIL_COND_V_MSG(p_image_size.height <= 0, TypedArray<Image>(), "Image height must be greater than 0.");40424043GLuint albedo_alpha_tex = 0;4044GLuint normal_tex = 0;4045GLuint orm_tex = 0;4046GLuint emission_tex = 0;4047GLuint depth_tex = 0;4048glGenTextures(1, &albedo_alpha_tex);4049glGenTextures(1, &normal_tex);4050glGenTextures(1, &orm_tex);4051glGenTextures(1, &emission_tex);4052glGenTextures(1, &depth_tex);40534054glBindTexture(GL_TEXTURE_2D, albedo_alpha_tex);4055glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, p_image_size.width, p_image_size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);4056GLES3::Utilities::get_singleton()->texture_allocated_data(albedo_alpha_tex, p_image_size.width * p_image_size.height * 4, "Lightmap albedo texture");40574058glBindTexture(GL_TEXTURE_2D, normal_tex);4059glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, p_image_size.width, p_image_size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);4060GLES3::Utilities::get_singleton()->texture_allocated_data(normal_tex, p_image_size.width * p_image_size.height * 4, "Lightmap normal texture");40614062glBindTexture(GL_TEXTURE_2D, orm_tex);4063glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, p_image_size.width, p_image_size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);4064GLES3::Utilities::get_singleton()->texture_allocated_data(orm_tex, p_image_size.width * p_image_size.height * 4, "Lightmap ORM texture");40654066// Consider rendering to RGBA8 encoded as RGBE, then manually convert to RGBAH on CPU.4067glBindTexture(GL_TEXTURE_2D, emission_tex);4068if (config->float_texture_supported) {4069glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, p_image_size.width, p_image_size.height, 0, GL_RGBA, GL_FLOAT, nullptr);4070GLES3::Utilities::get_singleton()->texture_allocated_data(emission_tex, p_image_size.width * p_image_size.height * 16, "Lightmap emission texture");4071} else {4072// Fallback to RGBA8 on devices that don't support rendering to floating point textures. This will look bad, but we have no choice.4073glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, p_image_size.width, p_image_size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);4074GLES3::Utilities::get_singleton()->texture_allocated_data(emission_tex, p_image_size.width * p_image_size.height * 4, "Lightmap emission texture");4075}40764077glBindTexture(GL_TEXTURE_2D, depth_tex);4078glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, p_image_size.width, p_image_size.height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);4079GLES3::Utilities::get_singleton()->texture_allocated_data(depth_tex, p_image_size.width * p_image_size.height * 3, "Lightmap depth texture");40804081GLuint fbo = 0;4082glGenFramebuffers(1, &fbo);4083glBindFramebuffer(GL_FRAMEBUFFER, fbo);40844085glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, albedo_alpha_tex, 0);4086glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, normal_tex, 0);4087glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, orm_tex, 0);4088glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, emission_tex, 0);4089glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_tex, 0);40904091GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);4092if (status != GL_FRAMEBUFFER_COMPLETE) {4093glDeleteFramebuffers(1, &fbo);4094GLES3::Utilities::get_singleton()->texture_free_data(albedo_alpha_tex);4095GLES3::Utilities::get_singleton()->texture_free_data(normal_tex);4096GLES3::Utilities::get_singleton()->texture_free_data(orm_tex);4097GLES3::Utilities::get_singleton()->texture_free_data(emission_tex);4098GLES3::Utilities::get_singleton()->texture_free_data(depth_tex);40994100WARN_PRINT("Could not create render target, status: " + GLES3::TextureStorage::get_singleton()->get_framebuffer_error(status));4101return TypedArray<Image>();4102}41034104RenderGeometryInstance *gi_inst = geometry_instance_create(p_base);4105ERR_FAIL_NULL_V(gi_inst, TypedArray<Image>());41064107uint32_t sc = RSG::mesh_storage->mesh_get_surface_count(p_base);4108Vector<RID> materials;4109materials.resize(sc);41104111for (uint32_t i = 0; i < sc; i++) {4112if (i < (uint32_t)p_material_overrides.size()) {4113materials.write[i] = p_material_overrides[i];4114}4115}41164117gi_inst->set_surface_materials(materials);41184119if (cull_argument.size() == 0) {4120cull_argument.push_back(nullptr);4121}4122cull_argument[0] = gi_inst;4123_render_uv2(cull_argument, fbo, Rect2i(0, 0, p_image_size.width, p_image_size.height));41244125geometry_instance_free(gi_inst);41264127TypedArray<Image> ret;41284129// Create a dummy texture so we can use texture_2d_get.4130RID tex_rid = GLES3::TextureStorage::get_singleton()->texture_allocate();4131GLES3::Texture texture;4132texture.width = p_image_size.width;4133texture.height = p_image_size.height;4134texture.alloc_width = p_image_size.width;4135texture.alloc_height = p_image_size.height;4136texture.format = Image::FORMAT_RGBA8;4137texture.real_format = Image::FORMAT_RGBA8;4138texture.gl_format_cache = GL_RGBA;4139texture.gl_type_cache = GL_UNSIGNED_BYTE;4140texture.type = GLES3::Texture::TYPE_2D;4141texture.target = GL_TEXTURE_2D;4142texture.active = true;4143texture.is_render_target = true; // Enable this so the texture isn't cached in the editor.41444145GLES3::TextureStorage::get_singleton()->texture_2d_initialize_from_texture(tex_rid, texture);4146GLES3::Texture *tex = GLES3::TextureStorage::get_singleton()->get_texture(tex_rid);41474148{4149tex->tex_id = albedo_alpha_tex;4150Ref<Image> img = GLES3::TextureStorage::get_singleton()->texture_2d_get(tex_rid);4151GLES3::Utilities::get_singleton()->texture_free_data(albedo_alpha_tex);4152ret.push_back(img);4153}41544155{4156tex->tex_id = normal_tex;4157Ref<Image> img = GLES3::TextureStorage::get_singleton()->texture_2d_get(tex_rid);4158GLES3::Utilities::get_singleton()->texture_free_data(normal_tex);4159ret.push_back(img);4160}41614162{4163tex->tex_id = orm_tex;4164Ref<Image> img = GLES3::TextureStorage::get_singleton()->texture_2d_get(tex_rid);4165GLES3::Utilities::get_singleton()->texture_free_data(orm_tex);4166ret.push_back(img);4167}41684169{4170tex->tex_id = emission_tex;4171if (config->float_texture_supported) {4172tex->format = Image::FORMAT_RGBAH;4173tex->real_format = Image::FORMAT_RGBAH;4174tex->gl_type_cache = GL_HALF_FLOAT;4175}4176Ref<Image> img = GLES3::TextureStorage::get_singleton()->texture_2d_get(tex_rid);4177GLES3::Utilities::get_singleton()->texture_free_data(emission_tex);4178ret.push_back(img);4179}41804181tex->is_render_target = false;4182tex->tex_id = 0;4183GLES3::TextureStorage::get_singleton()->texture_free(tex_rid);41844185GLES3::Utilities::get_singleton()->texture_free_data(depth_tex);4186glDeleteFramebuffers(1, &fbo);4187return ret;4188}41894190bool RasterizerSceneGLES3::free(RID p_rid) {4191if (is_environment(p_rid)) {4192environment_free(p_rid);4193} else if (sky_owner.owns(p_rid)) {4194Sky *sky = sky_owner.get_or_null(p_rid);4195ERR_FAIL_NULL_V(sky, false);4196_free_sky_data(sky);4197sky_owner.free(p_rid);4198} else if (GLES3::LightStorage::get_singleton()->owns_light_instance(p_rid)) {4199GLES3::LightStorage::get_singleton()->light_instance_free(p_rid);4200} else if (RSG::camera_attributes->owns_camera_attributes(p_rid)) {4201//not much to delete, just free it4202RSG::camera_attributes->camera_attributes_free(p_rid);4203} else if (is_compositor(p_rid)) {4204compositor_free(p_rid);4205} else if (is_compositor_effect(p_rid)) {4206compositor_effect_free(p_rid);4207} else {4208return false;4209}4210return true;4211}42124213void RasterizerSceneGLES3::update() {4214_update_dirty_skys();4215}42164217void RasterizerSceneGLES3::sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) {4218}42194220void RasterizerSceneGLES3::decals_set_filter(RS::DecalFilter p_filter) {4221}42224223void RasterizerSceneGLES3::light_projectors_set_filter(RS::LightProjectorFilter p_filter) {4224}42254226void RasterizerSceneGLES3::lightmaps_set_bicubic_filter(bool p_enable) {4227lightmap_bicubic_upscale = p_enable;4228}42294230RasterizerSceneGLES3::RasterizerSceneGLES3() {4231singleton = this;42324233GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();4234GLES3::Config *config = GLES3::Config::get_singleton();42354236cull_argument.set_page_pool(&cull_argument_pool);42374238// Quality settings.4239use_physical_light_units = GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units");42404241positional_soft_shadow_filter_set_quality((RS::ShadowQuality)(int)GLOBAL_GET("rendering/lights_and_shadows/positional_shadow/soft_shadow_filter_quality"));4242directional_soft_shadow_filter_set_quality((RS::ShadowQuality)(int)GLOBAL_GET("rendering/lights_and_shadows/directional_shadow/soft_shadow_filter_quality"));4243lightmaps_set_bicubic_filter(GLOBAL_GET("rendering/lightmapping/lightmap_gi/use_bicubic_filter"));42444245{4246// Setup Lights42474248config->max_renderable_lights = MIN(config->max_renderable_lights, config->max_uniform_buffer_size / (int)sizeof(RasterizerSceneGLES3::LightData));4249config->max_lights_per_object = MIN(config->max_lights_per_object, config->max_renderable_lights);42504251uint32_t light_buffer_size = config->max_renderable_lights * sizeof(LightData);4252scene_state.omni_lights = memnew_arr(LightData, config->max_renderable_lights);4253scene_state.omni_light_sort = memnew_arr(InstanceSort<GLES3::LightInstance>, config->max_renderable_lights);4254glGenBuffers(1, &scene_state.omni_light_buffer);4255glBindBuffer(GL_UNIFORM_BUFFER, scene_state.omni_light_buffer);4256GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.omni_light_buffer, light_buffer_size, nullptr, GL_STREAM_DRAW, "OmniLight UBO");42574258scene_state.spot_lights = memnew_arr(LightData, config->max_renderable_lights);4259scene_state.spot_light_sort = memnew_arr(InstanceSort<GLES3::LightInstance>, config->max_renderable_lights);4260glGenBuffers(1, &scene_state.spot_light_buffer);4261glBindBuffer(GL_UNIFORM_BUFFER, scene_state.spot_light_buffer);4262GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.spot_light_buffer, light_buffer_size, nullptr, GL_STREAM_DRAW, "SpotLight UBO");42634264uint32_t directional_light_buffer_size = MAX_DIRECTIONAL_LIGHTS * sizeof(DirectionalLightData);4265scene_state.directional_lights = memnew_arr(DirectionalLightData, MAX_DIRECTIONAL_LIGHTS);4266glGenBuffers(1, &scene_state.directional_light_buffer);4267glBindBuffer(GL_UNIFORM_BUFFER, scene_state.directional_light_buffer);4268GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.directional_light_buffer, directional_light_buffer_size, nullptr, GL_STREAM_DRAW, "DirectionalLight UBO");42694270uint32_t shadow_buffer_size = config->max_renderable_lights * sizeof(ShadowData) * 2;4271scene_state.positional_shadows = memnew_arr(ShadowData, config->max_renderable_lights * 2);4272glGenBuffers(1, &scene_state.positional_shadow_buffer);4273glBindBuffer(GL_UNIFORM_BUFFER, scene_state.positional_shadow_buffer);4274GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.positional_shadow_buffer, shadow_buffer_size, nullptr, GL_STREAM_DRAW, "Positional Shadow UBO");42754276uint32_t directional_shadow_buffer_size = MAX_DIRECTIONAL_LIGHTS * sizeof(DirectionalShadowData);4277scene_state.directional_shadows = memnew_arr(DirectionalShadowData, MAX_DIRECTIONAL_LIGHTS);4278glGenBuffers(1, &scene_state.directional_shadow_buffer);4279glBindBuffer(GL_UNIFORM_BUFFER, scene_state.directional_shadow_buffer);4280GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.directional_shadow_buffer, directional_shadow_buffer_size, nullptr, GL_STREAM_DRAW, "Directional Shadow UBO");42814282glBindBuffer(GL_UNIFORM_BUFFER, 0);4283}42844285{4286sky_globals.max_directional_lights = 4;4287uint32_t directional_light_buffer_size = sky_globals.max_directional_lights * sizeof(DirectionalLightData);4288sky_globals.directional_lights = memnew_arr(DirectionalLightData, sky_globals.max_directional_lights);4289sky_globals.last_frame_directional_lights = memnew_arr(DirectionalLightData, sky_globals.max_directional_lights);4290sky_globals.last_frame_directional_light_count = sky_globals.max_directional_lights + 1;4291glGenBuffers(1, &sky_globals.directional_light_buffer);4292glBindBuffer(GL_UNIFORM_BUFFER, sky_globals.directional_light_buffer);4293GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, sky_globals.directional_light_buffer, directional_light_buffer_size, nullptr, GL_STREAM_DRAW, "Sky DirectionalLight UBO");42944295glBindBuffer(GL_UNIFORM_BUFFER, 0);4296}42974298{4299String global_defines;4300global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now4301global_defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(config->max_renderable_lights) + "\n";4302global_defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(MAX_DIRECTIONAL_LIGHTS) + "\n";4303global_defines += "\n#define MAX_FORWARD_LIGHTS " + itos(config->max_lights_per_object) + "u\n";4304global_defines += "\n#define MAX_ROUGHNESS_LOD " + itos(sky_globals.roughness_layers - 1) + ".0\n";4305if (config->force_vertex_shading) {4306global_defines += "\n#define USE_VERTEX_LIGHTING\n";4307}4308if (!config->specular_occlusion) {4309global_defines += "\n#define SPECULAR_OCCLUSION_DISABLED\n";4310}4311material_storage->shaders.scene_shader.initialize(global_defines);4312scene_globals.shader_default_version = material_storage->shaders.scene_shader.version_create();4313material_storage->shaders.scene_shader.version_bind_shader(scene_globals.shader_default_version, SceneShaderGLES3::MODE_COLOR);4314}43154316{4317//default material and shader4318scene_globals.default_shader = material_storage->shader_allocate();4319material_storage->shader_initialize(scene_globals.default_shader);4320material_storage->shader_set_code(scene_globals.default_shader, R"(4321// Default 3D material shader (Compatibility).43224323shader_type spatial;43244325void vertex() {4326ROUGHNESS = 0.8;4327}43284329void fragment() {4330ALBEDO = vec3(0.6);4331ROUGHNESS = 0.8;4332METALLIC = 0.2;4333}4334)");4335scene_globals.default_material = material_storage->material_allocate();4336material_storage->material_initialize(scene_globals.default_material);4337material_storage->material_set_shader(scene_globals.default_material, scene_globals.default_shader);4338default_material_data_ptr = static_cast<GLES3::SceneMaterialData *>(GLES3::MaterialStorage::get_singleton()->material_get_data(scene_globals.default_material, RS::SHADER_SPATIAL));4339}43404341{4342// Overdraw material and shader.4343scene_globals.overdraw_shader = material_storage->shader_allocate();4344material_storage->shader_initialize(scene_globals.overdraw_shader);4345material_storage->shader_set_code(scene_globals.overdraw_shader, R"(4346// 3D editor Overdraw debug draw mode shader (Compatibility).43474348shader_type spatial;43494350render_mode blend_add, unshaded, fog_disabled;43514352void fragment() {4353ALBEDO = vec3(0.4, 0.8, 0.8);4354ALPHA = 0.2;4355}4356)");4357scene_globals.overdraw_material = material_storage->material_allocate();4358material_storage->material_initialize(scene_globals.overdraw_material);4359material_storage->material_set_shader(scene_globals.overdraw_material, scene_globals.overdraw_shader);4360overdraw_material_data_ptr = static_cast<GLES3::SceneMaterialData *>(GLES3::MaterialStorage::get_singleton()->material_get_data(scene_globals.overdraw_material, RS::SHADER_SPATIAL));4361}43624363{4364// Initialize Sky stuff4365sky_globals.roughness_layers = GLOBAL_GET("rendering/reflections/sky_reflections/roughness_layers");43664367String global_defines;4368global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now4369global_defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(sky_globals.max_directional_lights) + "\n";4370material_storage->shaders.sky_shader.initialize(global_defines);4371sky_globals.shader_default_version = material_storage->shaders.sky_shader.version_create();4372}43734374{4375sky_globals.default_shader = material_storage->shader_allocate();43764377material_storage->shader_initialize(sky_globals.default_shader);43784379material_storage->shader_set_code(sky_globals.default_shader, R"(4380// Default sky shader.43814382shader_type sky;43834384void sky() {4385COLOR = vec3(0.0);4386}4387)");4388sky_globals.default_material = material_storage->material_allocate();4389material_storage->material_initialize(sky_globals.default_material);43904391material_storage->material_set_shader(sky_globals.default_material, sky_globals.default_shader);4392}4393{4394sky_globals.fog_shader = material_storage->shader_allocate();4395material_storage->shader_initialize(sky_globals.fog_shader);43964397material_storage->shader_set_code(sky_globals.fog_shader, R"(4398// Default clear color sky shader.43994400shader_type sky;44014402uniform vec4 clear_color;44034404void sky() {4405COLOR = clear_color.rgb;4406}4407)");4408sky_globals.fog_material = material_storage->material_allocate();4409material_storage->material_initialize(sky_globals.fog_material);44104411material_storage->material_set_shader(sky_globals.fog_material, sky_globals.fog_shader);4412}44134414{4415glGenVertexArrays(1, &sky_globals.screen_triangle_array);4416glBindVertexArray(sky_globals.screen_triangle_array);4417glGenBuffers(1, &sky_globals.screen_triangle);4418glBindBuffer(GL_ARRAY_BUFFER, sky_globals.screen_triangle);44194420const float qv[6] = {4421-1.0f,4422-1.0f,44233.0f,4424-1.0f,4425-1.0f,44263.0f,4427};44284429GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, sky_globals.screen_triangle, sizeof(float) * 6, qv, GL_STATIC_DRAW, "Screen triangle vertex buffer");44304431glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, nullptr);4432glEnableVertexAttribArray(RS::ARRAY_VERTEX);4433glBindVertexArray(0);4434glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind4435}44364437#ifdef GL_API_ENABLED4438if (RasterizerGLES3::is_gles_over_gl()) {4439glEnable(_EXT_TEXTURE_CUBE_MAP_SEAMLESS);4440}4441#endif // GL_API_ENABLED44424443// MultiMesh may read from color when color is disabled, so make sure that the color defaults to white instead of black;4444glVertexAttrib4f(RS::ARRAY_COLOR, 1.0, 1.0, 1.0, 1.0);4445}44464447RasterizerSceneGLES3::~RasterizerSceneGLES3() {4448GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.directional_light_buffer);4449GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.omni_light_buffer);4450GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.spot_light_buffer);4451GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.positional_shadow_buffer);4452GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.directional_shadow_buffer);4453memdelete_arr(scene_state.directional_lights);4454memdelete_arr(scene_state.omni_lights);4455memdelete_arr(scene_state.spot_lights);4456memdelete_arr(scene_state.omni_light_sort);4457memdelete_arr(scene_state.spot_light_sort);4458memdelete_arr(scene_state.positional_shadows);4459memdelete_arr(scene_state.directional_shadows);44604461// Scene Shader4462GLES3::MaterialStorage::get_singleton()->shaders.scene_shader.version_free(scene_globals.shader_default_version);4463RSG::material_storage->material_free(scene_globals.default_material);4464RSG::material_storage->shader_free(scene_globals.default_shader);44654466// Overdraw Shader4467RSG::material_storage->material_free(scene_globals.overdraw_material);4468RSG::material_storage->shader_free(scene_globals.overdraw_shader);44694470// Sky Shader4471GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_free(sky_globals.shader_default_version);4472RSG::material_storage->material_free(sky_globals.default_material);4473RSG::material_storage->shader_free(sky_globals.default_shader);4474RSG::material_storage->material_free(sky_globals.fog_material);4475RSG::material_storage->shader_free(sky_globals.fog_shader);4476GLES3::Utilities::get_singleton()->buffer_free_data(sky_globals.screen_triangle);4477glDeleteVertexArrays(1, &sky_globals.screen_triangle_array);4478GLES3::Utilities::get_singleton()->buffer_free_data(sky_globals.directional_light_buffer);4479memdelete_arr(sky_globals.directional_lights);4480memdelete_arr(sky_globals.last_frame_directional_lights);44814482// UBOs4483if (scene_state.ubo_buffer != 0) {4484GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.ubo_buffer);4485}44864487if (scene_state.multiview_buffer != 0) {4488GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.multiview_buffer);4489}44904491if (scene_state.tonemap_buffer != 0) {4492GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.tonemap_buffer);4493}44944495singleton = nullptr;4496}44974498#endif // GLES3_ENABLED449945004501