Path: blob/master/drivers/gles3/rasterizer_scene_gles3.cpp
21403 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/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}7374uint32_t RasterizerSceneGLES3::get_max_lights_total() {75return (uint32_t)GLES3::Config::get_singleton()->max_renderable_lights;76}7778uint32_t RasterizerSceneGLES3::get_max_lights_per_mesh() {79return (uint32_t)GLES3::Config::get_singleton()->max_lights_per_object;80}8182void RasterizerSceneGLES3::GeometryInstanceGLES3::clear_light_instances() {83paired_omni_light_count = 0;84paired_spot_light_count = 0;85paired_omni_lights.clear();86paired_spot_lights.clear();87}8889void RasterizerSceneGLES3::GeometryInstanceGLES3::pair_light_instance(90const RID p_light_instance, RS::LightType light_type, uint32_t placement_idx) {91if (placement_idx < GLES3::Config::get_singleton()->max_lights_per_object) {92switch (light_type) {93case RS::LIGHT_OMNI: {94if (placement_idx >= paired_omni_light_count) {95paired_omni_lights.push_back(p_light_instance);96++paired_omni_light_count;97} else {98paired_omni_lights[placement_idx] = p_light_instance;99}100} break;101case RS::LIGHT_SPOT: {102if (placement_idx >= paired_spot_light_count) {103paired_spot_lights.push_back(p_light_instance);104++paired_spot_light_count;105} else {106paired_spot_lights[placement_idx] = p_light_instance;107}108} break;109default:110break;111}112}113}114115void RasterizerSceneGLES3::GeometryInstanceGLES3::pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) {116paired_reflection_probes.clear();117118for (uint32_t i = 0; i < p_reflection_probe_instance_count; i++) {119paired_reflection_probes.push_back(p_reflection_probe_instances[i]);120}121}122123void RasterizerSceneGLES3::geometry_instance_free(RenderGeometryInstance *p_geometry_instance) {124GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);125ERR_FAIL_NULL(ginstance);126GeometryInstanceSurface *surf = ginstance->surface_caches;127while (surf) {128GeometryInstanceSurface *next = surf->next;129geometry_instance_surface_alloc.free(surf);130surf = next;131}132memdelete(ginstance->data);133geometry_instance_alloc.free(ginstance);134}135136void RasterizerSceneGLES3::GeometryInstanceGLES3::_mark_dirty() {137if (dirty_list_element.in_list()) {138return;139}140141//clear surface caches142GeometryInstanceSurface *surf = surface_caches;143144while (surf) {145GeometryInstanceSurface *next = surf->next;146RasterizerSceneGLES3::get_singleton()->geometry_instance_surface_alloc.free(surf);147surf = next;148}149150surface_caches = nullptr;151152RasterizerSceneGLES3::get_singleton()->geometry_instance_dirty_list.add(&dirty_list_element);153}154155void RasterizerSceneGLES3::GeometryInstanceGLES3::set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) {156lightmap_instance = p_lightmap_instance;157lightmap_uv_scale = p_lightmap_uv_scale;158lightmap_slice_index = p_lightmap_slice_index;159160_mark_dirty();161}162163void RasterizerSceneGLES3::GeometryInstanceGLES3::set_lightmap_capture(const Color *p_sh9) {164if (p_sh9) {165if (lightmap_sh == nullptr) {166lightmap_sh = memnew(GeometryInstanceLightmapSH);167}168169memcpy(lightmap_sh->sh, p_sh9, sizeof(Color) * 9);170} else {171if (lightmap_sh != nullptr) {172memdelete(lightmap_sh);173lightmap_sh = nullptr;174}175}176_mark_dirty();177}178179void RasterizerSceneGLES3::_update_dirty_geometry_instances() {180while (geometry_instance_dirty_list.first()) {181_geometry_instance_update(geometry_instance_dirty_list.first()->self());182}183}184185void RasterizerSceneGLES3::_geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker) {186switch (p_notification) {187case Dependency::DEPENDENCY_CHANGED_MATERIAL:188case Dependency::DEPENDENCY_CHANGED_MESH:189case Dependency::DEPENDENCY_CHANGED_PARTICLES:190case Dependency::DEPENDENCY_CHANGED_MULTIMESH:191case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: {192static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty();193static_cast<GeometryInstanceGLES3 *>(p_tracker->userdata)->data->dirty_dependencies = true;194} break;195case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: {196GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_tracker->userdata);197if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) {198ginstance->instance_count = GLES3::MeshStorage::get_singleton()->multimesh_get_instances_to_draw(ginstance->data->base);199}200} break;201default: {202//rest of notifications of no interest203} break;204}205}206207void RasterizerSceneGLES3::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) {208static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty();209static_cast<GeometryInstanceGLES3 *>(p_tracker->userdata)->data->dirty_dependencies = true;210}211212void 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) {213GLES3::MeshStorage *mesh_storage = GLES3::MeshStorage::get_singleton();214215bool 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;216bool has_base_alpha = ((p_material->shader_data->uses_alpha && !p_material->shader_data->uses_alpha_clip) || has_read_screen_alpha);217bool has_blend_alpha = p_material->shader_data->uses_blend_alpha;218bool has_alpha = has_base_alpha || has_blend_alpha;219220uint32_t flags = 0;221222if (p_material->shader_data->uses_screen_texture) {223flags |= GeometryInstanceSurface::FLAG_USES_SCREEN_TEXTURE;224}225226if (p_material->shader_data->uses_depth_texture) {227flags |= GeometryInstanceSurface::FLAG_USES_DEPTH_TEXTURE;228}229230if (p_material->shader_data->uses_normal_texture) {231flags |= GeometryInstanceSurface::FLAG_USES_NORMAL_TEXTURE;232}233234if (ginstance->data->cast_double_sided_shadows) {235flags |= GeometryInstanceSurface::FLAG_USES_DOUBLE_SIDED_SHADOWS;236}237238if (p_material->shader_data->stencil_enabled) {239flags |= GeometryInstanceSurface::FLAG_USES_STENCIL;240}241242if (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) {243//material is only meant for alpha pass244flags |= GeometryInstanceSurface::FLAG_PASS_ALPHA;245if (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)) {246flags |= GeometryInstanceSurface::FLAG_PASS_DEPTH;247flags |= GeometryInstanceSurface::FLAG_PASS_SHADOW;248}249} else {250flags |= GeometryInstanceSurface::FLAG_PASS_OPAQUE;251flags |= GeometryInstanceSurface::FLAG_PASS_DEPTH;252flags |= GeometryInstanceSurface::FLAG_PASS_SHADOW;253}254255if (p_material->shader_data->stencil_enabled) {256if (p_material->shader_data->stencil_flags & GLES3::SceneShaderData::STENCIL_FLAG_READ) {257// Stencil materials which read from the stencil buffer must be in the alpha pass.258// This is critical to preserve compatibility once we'll have the compositor.259if (!(flags & GeometryInstanceSurface::FLAG_PASS_ALPHA)) {260String shader_path = p_material->shader_data->path.is_empty() ? "" : "(" + p_material->shader_data->path + ")";261ERR_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));262}263}264}265266GLES3::SceneMaterialData *material_shadow = nullptr;267void *surface_shadow = nullptr;268if (!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) {269flags |= GeometryInstanceSurface::FLAG_USES_SHARED_SHADOW_MATERIAL;270material_shadow = static_cast<GLES3::SceneMaterialData *>(GLES3::MaterialStorage::get_singleton()->material_get_data(scene_globals.default_material, RS::SHADER_SPATIAL));271272RID shadow_mesh = mesh_storage->mesh_get_shadow_mesh(p_mesh);273274if (shadow_mesh.is_valid()) {275surface_shadow = mesh_storage->mesh_get_surface(shadow_mesh, p_surface);276}277278} else {279material_shadow = p_material;280}281282GeometryInstanceSurface *sdcache = geometry_instance_surface_alloc.alloc();283284sdcache->flags = flags;285286sdcache->shader = p_material->shader_data;287sdcache->material = p_material;288sdcache->surface = mesh_storage->mesh_get_surface(p_mesh, p_surface);289sdcache->primitive = mesh_storage->mesh_surface_get_primitive(sdcache->surface);290sdcache->surface_index = p_surface;291292if (ginstance->data->dirty_dependencies) {293RSG::utilities->base_update_dependency(p_mesh, &ginstance->data->dependency_tracker);294}295296//shadow297sdcache->shader_shadow = material_shadow->shader_data;298sdcache->material_shadow = material_shadow;299300sdcache->surface_shadow = surface_shadow ? surface_shadow : sdcache->surface;301302sdcache->owner = ginstance;303304sdcache->next = ginstance->surface_caches;305ginstance->surface_caches = sdcache;306307//sortkey308309sdcache->sort.sort_key1 = 0;310sdcache->sort.sort_key2 = 0;311312sdcache->sort.surface_index = p_surface;313sdcache->sort.material_id_low = p_material_id & 0x0000FFFF;314sdcache->sort.material_id_hi = p_material_id >> 16;315sdcache->sort.shader_id = p_shader_id;316sdcache->sort.geometry_id = p_mesh.get_local_index();317sdcache->sort.priority = p_material->priority;318319GLES3::Mesh::Surface *s = reinterpret_cast<GLES3::Mesh::Surface *>(sdcache->surface);320if (p_material->shader_data->uses_tangent && !(s->format & RS::ARRAY_FORMAT_TANGENT)) {321String shader_path = p_material->shader_data->path.is_empty() ? "" : "(" + p_material->shader_data->path + ")";322String mesh_path = mesh_storage->mesh_get_path(p_mesh).is_empty() ? "" : "(" + mesh_storage->mesh_get_path(p_mesh) + ")";323WARN_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));324}325}326327void 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) {328GLES3::SceneMaterialData *material_data = p_material_data;329GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();330331_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);332333while (material_data->next_pass.is_valid()) {334RID next_pass = material_data->next_pass;335material_data = static_cast<GLES3::SceneMaterialData *>(material_storage->material_get_data(next_pass, RS::SHADER_SPATIAL));336if (!material_data || !material_data->shader_data->valid) {337break;338}339if (ginstance->data->dirty_dependencies) {340material_storage->material_update_dependency(next_pass, &ginstance->data->dependency_tracker);341}342_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);343}344}345346void RasterizerSceneGLES3::_geometry_instance_add_surface(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, RID p_material, RID p_mesh) {347GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();348RID m_src;349350m_src = ginstance->data->material_override.is_valid() ? ginstance->data->material_override : p_material;351352GLES3::SceneMaterialData *material_data = nullptr;353354if (m_src.is_valid()) {355material_data = static_cast<GLES3::SceneMaterialData *>(material_storage->material_get_data(m_src, RS::SHADER_SPATIAL));356if (!material_data || !material_data->shader_data->valid) {357material_data = nullptr;358}359}360361if (material_data) {362if (ginstance->data->dirty_dependencies) {363material_storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker);364}365} else {366material_data = static_cast<GLES3::SceneMaterialData *>(material_storage->material_get_data(scene_globals.default_material, RS::SHADER_SPATIAL));367m_src = scene_globals.default_material;368}369370ERR_FAIL_NULL(material_data);371372_geometry_instance_add_surface_with_material_chain(ginstance, p_surface, material_data, m_src, p_mesh);373374if (ginstance->data->material_overlay.is_valid()) {375m_src = ginstance->data->material_overlay;376377material_data = static_cast<GLES3::SceneMaterialData *>(material_storage->material_get_data(m_src, RS::SHADER_SPATIAL));378if (material_data && material_data->shader_data->valid) {379if (ginstance->data->dirty_dependencies) {380material_storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker);381}382383_geometry_instance_add_surface_with_material_chain(ginstance, p_surface, material_data, m_src, p_mesh);384}385}386}387388void RasterizerSceneGLES3::_geometry_instance_update(RenderGeometryInstance *p_geometry_instance) {389GLES3::MeshStorage *mesh_storage = GLES3::MeshStorage::get_singleton();390GLES3::ParticlesStorage *particles_storage = GLES3::ParticlesStorage::get_singleton();391392GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance);393394if (ginstance->data->dirty_dependencies) {395ginstance->data->dependency_tracker.update_begin();396}397398//add geometry for drawing399switch (ginstance->data->base_type) {400case RS::INSTANCE_MESH: {401const RID *materials = nullptr;402uint32_t surface_count;403RID mesh = ginstance->data->base;404405materials = mesh_storage->mesh_get_surface_count_and_materials(mesh, surface_count);406if (materials) {407//if no materials, no surfaces.408const RID *inst_materials = ginstance->data->surface_materials.ptr();409uint32_t surf_mat_count = ginstance->data->surface_materials.size();410411for (uint32_t j = 0; j < surface_count; j++) {412RID material = (j < surf_mat_count && inst_materials[j].is_valid()) ? inst_materials[j] : materials[j];413_geometry_instance_add_surface(ginstance, j, material, mesh);414}415}416417ginstance->instance_count = -1;418419} break;420421case RS::INSTANCE_MULTIMESH: {422RID mesh = mesh_storage->multimesh_get_mesh(ginstance->data->base);423if (mesh.is_valid()) {424const RID *materials = nullptr;425uint32_t surface_count;426427materials = mesh_storage->mesh_get_surface_count_and_materials(mesh, surface_count);428if (materials) {429for (uint32_t j = 0; j < surface_count; j++) {430_geometry_instance_add_surface(ginstance, j, materials[j], mesh);431}432}433434ginstance->instance_count = mesh_storage->multimesh_get_instances_to_draw(ginstance->data->base);435}436437} break;438case RS::INSTANCE_PARTICLES: {439int draw_passes = particles_storage->particles_get_draw_passes(ginstance->data->base);440441for (int j = 0; j < draw_passes; j++) {442RID mesh = particles_storage->particles_get_draw_pass_mesh(ginstance->data->base, j);443if (!mesh.is_valid()) {444continue;445}446447const RID *materials = nullptr;448uint32_t surface_count;449450materials = mesh_storage->mesh_get_surface_count_and_materials(mesh, surface_count);451if (materials) {452for (uint32_t k = 0; k < surface_count; k++) {453_geometry_instance_add_surface(ginstance, k, materials[k], mesh);454}455}456}457458ginstance->instance_count = particles_storage->particles_get_amount(ginstance->data->base);459} break;460461default: {462}463}464465bool store_transform = true;466ginstance->base_flags = 0;467468if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) {469ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH;470if (mesh_storage->multimesh_get_transform_format(ginstance->data->base) == RS::MULTIMESH_TRANSFORM_2D) {471ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D;472}473if (mesh_storage->multimesh_uses_colors(ginstance->data->base)) {474ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR;475}476if (mesh_storage->multimesh_uses_custom_data(ginstance->data->base)) {477ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA;478}479480} else if (ginstance->data->base_type == RS::INSTANCE_PARTICLES) {481ginstance->base_flags |= INSTANCE_DATA_FLAG_PARTICLES;482ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH;483484ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR;485ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA;486487if (!particles_storage->particles_is_using_local_coords(ginstance->data->base)) {488store_transform = false;489}490491} else if (ginstance->data->base_type == RS::INSTANCE_MESH) {492if (mesh_storage->skeleton_is_valid(ginstance->data->skeleton)) {493if (ginstance->data->dirty_dependencies) {494mesh_storage->skeleton_update_dependency(ginstance->data->skeleton, &ginstance->data->dependency_tracker);495}496}497}498499ginstance->store_transform_cache = store_transform;500501if (ginstance->data->dirty_dependencies) {502ginstance->data->dependency_tracker.update_end();503ginstance->data->dirty_dependencies = false;504}505506ginstance->dirty_list_element.remove_from_list();507}508509/* SKY API */510511void RasterizerSceneGLES3::_free_sky_data(Sky *p_sky) {512if (p_sky->radiance != 0) {513GLES3::Utilities::get_singleton()->texture_free_data(p_sky->radiance);514p_sky->radiance = 0;515GLES3::Utilities::get_singleton()->texture_free_data(p_sky->raw_radiance);516p_sky->raw_radiance = 0;517glDeleteFramebuffers(1, &p_sky->radiance_framebuffer);518p_sky->radiance_framebuffer = 0;519}520}521522RID RasterizerSceneGLES3::sky_allocate() {523return sky_owner.allocate_rid();524}525526void RasterizerSceneGLES3::sky_initialize(RID p_rid) {527sky_owner.initialize_rid(p_rid);528}529530void RasterizerSceneGLES3::sky_set_radiance_size(RID p_sky, int p_radiance_size) {531Sky *sky = sky_owner.get_or_null(p_sky);532ERR_FAIL_NULL(sky);533ERR_FAIL_COND_MSG(p_radiance_size < 32 || p_radiance_size > 2048, "Sky radiance size must be between 32 and 2048");534535if (sky->radiance_size == p_radiance_size) {536return; // No need to update537}538539sky->radiance_size = p_radiance_size;540541_free_sky_data(sky);542_invalidate_sky(sky);543}544545void RasterizerSceneGLES3::sky_set_mode(RID p_sky, RS::SkyMode p_mode) {546Sky *sky = sky_owner.get_or_null(p_sky);547ERR_FAIL_NULL(sky);548549if (sky->mode == p_mode) {550return;551}552553sky->mode = p_mode;554_invalidate_sky(sky);555}556557void RasterizerSceneGLES3::sky_set_material(RID p_sky, RID p_material) {558Sky *sky = sky_owner.get_or_null(p_sky);559ERR_FAIL_NULL(sky);560561if (sky->material == p_material) {562return;563}564565sky->material = p_material;566_invalidate_sky(sky);567}568569float RasterizerSceneGLES3::sky_get_baked_exposure(RID p_sky) const {570Sky *sky = sky_owner.get_or_null(p_sky);571ERR_FAIL_NULL_V(sky, 1.0);572573return sky->baked_exposure;574}575576void RasterizerSceneGLES3::_invalidate_sky(Sky *p_sky) {577if (!p_sky->dirty) {578p_sky->dirty = true;579p_sky->dirty_list = dirty_sky_list;580dirty_sky_list = p_sky;581}582}583584GLuint _init_radiance_texture(int p_size, int p_mipmaps, String p_name) {585GLuint radiance_id = 0;586587glGenTextures(1, &radiance_id);588glBindTexture(GL_TEXTURE_CUBE_MAP, radiance_id);589#ifdef GL_API_ENABLED590if (RasterizerGLES3::is_gles_over_gl()) {591//TODO, on low-end compare this to allocating each face of each mip individually592// see: https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glTexStorage2D.xhtml593for (int i = 0; i < 6; i++) {594glTexImage2D(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);595}596597glGenerateMipmap(GL_TEXTURE_CUBE_MAP);598}599#endif // GL_API_ENABLED600#ifdef GLES_API_ENABLED601if (!RasterizerGLES3::is_gles_over_gl()) {602glTexStorage2D(GL_TEXTURE_CUBE_MAP, p_mipmaps, GL_RGB10_A2, p_size, p_size);603}604#endif // GLES_API_ENABLED605glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);606glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);607glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);608glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);609glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);610glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, p_mipmaps - 1);611612GLES3::Utilities::get_singleton()->texture_allocated_data(radiance_id, Image::get_image_data_size(p_size, p_size, Image::FORMAT_RGBA8, true), p_name);613return radiance_id;614}615616void RasterizerSceneGLES3::_update_dirty_skys() {617Sky *sky = dirty_sky_list;618619while (sky) {620if (sky->radiance == 0) {621sky->mipmap_count = Image::get_image_required_mipmaps(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBA8) - 1;622// Left uninitialized, will attach a texture at render time623glGenFramebuffers(1, &sky->radiance_framebuffer);624sky->radiance = _init_radiance_texture(sky->radiance_size, sky->mipmap_count, "Sky radiance texture");625sky->raw_radiance = _init_radiance_texture(sky->radiance_size, sky->mipmap_count, "Sky raw radiance texture");626}627628sky->reflection_dirty = true;629sky->processing_layer = 0;630631Sky *next = sky->dirty_list;632sky->dirty_list = nullptr;633sky->dirty = false;634sky = next;635}636637dirty_sky_list = nullptr;638}639640void 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) {641GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton();642GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();643ERR_FAIL_COND(p_render_data->environment.is_null());644645GLES3::SkyMaterialData *material = nullptr;646Sky *sky = sky_owner.get_or_null(environment_get_sky(p_render_data->environment));647648RID sky_material;649650GLES3::SkyShaderData *shader_data = nullptr;651652if (sky) {653sky_material = sky->material;654655if (sky_material.is_valid()) {656material = static_cast<GLES3::SkyMaterialData *>(material_storage->material_get_data(sky_material, RS::SHADER_SKY));657if (!material || !material->shader_data->valid) {658material = nullptr;659}660}661}662663if (!material) {664sky_material = sky_globals.default_material;665material = static_cast<GLES3::SkyMaterialData *>(material_storage->material_get_data(sky_material, RS::SHADER_SKY));666}667668ERR_FAIL_NULL(material);669670shader_data = material->shader_data;671672ERR_FAIL_NULL(shader_data);673674if (sky) {675if (shader_data->uses_time && time - sky->prev_time > 0.00001) {676sky->prev_time = time;677sky->reflection_dirty = true;678RenderingServerDefault::redraw_request();679}680681if (material != sky->prev_material) {682sky->prev_material = material;683sky->reflection_dirty = true;684}685686if (material->uniform_set_updated) {687material->uniform_set_updated = false;688sky->reflection_dirty = true;689}690691if (!p_transform.origin.is_equal_approx(sky->prev_position) && shader_data->uses_position) {692sky->prev_position = p_transform.origin;693sky->reflection_dirty = true;694}695}696697bool sun_scatter_enabled = environment_get_fog_enabled(p_render_data->environment) && environment_get_fog_sun_scatter(p_render_data->environment) > 0.001;698glBindBufferBase(GL_UNIFORM_BUFFER, SKY_DIRECTIONAL_LIGHT_UNIFORM_LOCATION, sky_globals.directional_light_buffer);699if (shader_data->uses_light || sun_scatter_enabled) {700sky_globals.directional_light_count = 0;701for (int i = 0; i < (int)p_lights.size(); i++) {702GLES3::LightInstance *li = GLES3::LightStorage::get_singleton()->get_light_instance(p_lights[i]);703if (!li) {704continue;705}706RID base = li->light;707708ERR_CONTINUE(base.is_null());709710RS::LightType type = light_storage->light_get_type(base);711if (type == RS::LIGHT_DIRECTIONAL && light_storage->light_directional_get_sky_mode(base) != RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_ONLY) {712DirectionalLightData &sky_light_data = sky_globals.directional_lights[sky_globals.directional_light_count];713Transform3D light_transform = li->transform;714Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized();715716sky_light_data.direction[0] = world_direction.x;717sky_light_data.direction[1] = world_direction.y;718sky_light_data.direction[2] = world_direction.z;719720float sign = light_storage->light_is_negative(base) ? -1 : 1;721sky_light_data.energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY);722723if (is_using_physical_light_units()) {724sky_light_data.energy *= light_storage->light_get_param(base, RS::LIGHT_PARAM_INTENSITY);725}726727if (p_render_data->camera_attributes.is_valid()) {728sky_light_data.energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);729}730731Color srgb_col = light_storage->light_get_color(base);732sky_light_data.color[0] = srgb_col.r;733sky_light_data.color[1] = srgb_col.g;734sky_light_data.color[2] = srgb_col.b;735736sky_light_data.enabled = true;737738float angular_diameter = light_storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);739sky_light_data.size = Math::deg_to_rad(angular_diameter);740sky_globals.directional_light_count++;741if (sky_globals.directional_light_count >= sky_globals.max_directional_lights) {742break;743}744}745}746// Check whether the directional_light_buffer changes747bool light_data_dirty = false;748749// Light buffer is dirty if we have fewer or more lights750// If we have fewer lights, make sure that old lights are disabled751if (sky_globals.directional_light_count != sky_globals.last_frame_directional_light_count) {752light_data_dirty = true;753for (uint32_t i = sky_globals.directional_light_count; i < sky_globals.max_directional_lights; i++) {754sky_globals.directional_lights[i].enabled = false;755sky_globals.last_frame_directional_lights[i].enabled = false;756}757}758759if (!light_data_dirty) {760for (uint32_t i = 0; i < sky_globals.directional_light_count; i++) {761if (sky_globals.directional_lights[i].direction[0] != sky_globals.last_frame_directional_lights[i].direction[0] ||762sky_globals.directional_lights[i].direction[1] != sky_globals.last_frame_directional_lights[i].direction[1] ||763sky_globals.directional_lights[i].direction[2] != sky_globals.last_frame_directional_lights[i].direction[2] ||764sky_globals.directional_lights[i].energy != sky_globals.last_frame_directional_lights[i].energy ||765sky_globals.directional_lights[i].color[0] != sky_globals.last_frame_directional_lights[i].color[0] ||766sky_globals.directional_lights[i].color[1] != sky_globals.last_frame_directional_lights[i].color[1] ||767sky_globals.directional_lights[i].color[2] != sky_globals.last_frame_directional_lights[i].color[2] ||768sky_globals.directional_lights[i].enabled != sky_globals.last_frame_directional_lights[i].enabled ||769sky_globals.directional_lights[i].size != sky_globals.last_frame_directional_lights[i].size) {770light_data_dirty = true;771break;772}773}774}775776if (light_data_dirty) {777glBufferData(GL_UNIFORM_BUFFER, sizeof(DirectionalLightData) * sky_globals.max_directional_lights, sky_globals.directional_lights, GL_STREAM_DRAW);778glBindBuffer(GL_UNIFORM_BUFFER, 0);779780DirectionalLightData *temp = sky_globals.last_frame_directional_lights;781sky_globals.last_frame_directional_lights = sky_globals.directional_lights;782sky_globals.directional_lights = temp;783sky_globals.last_frame_directional_light_count = sky_globals.directional_light_count;784if (sky) {785sky->reflection_dirty = true;786}787}788}789790if (p_render_data->view_count > 1) {791glBindBufferBase(GL_UNIFORM_BUFFER, SKY_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);792glBindBuffer(GL_UNIFORM_BUFFER, 0);793}794795if (sky && !sky->radiance) {796_invalidate_sky(sky);797_update_dirty_skys();798}799}800801void 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) {802GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();803ERR_FAIL_COND(p_env.is_null());804805Sky *sky = sky_owner.get_or_null(environment_get_sky(p_env));806807GLES3::SkyMaterialData *material_data = nullptr;808RID sky_material;809810uint64_t spec_constants = p_use_multiview ? SkyShaderGLES3::USE_MULTIVIEW : 0;811if (p_flip_y) {812spec_constants |= SkyShaderGLES3::USE_INVERTED_Y;813}814if (!p_apply_color_adjustments_in_post) {815spec_constants |= SkyShaderGLES3::APPLY_TONEMAPPING;816}817818RS::EnvironmentBG background = environment_get_background(p_env);819820if (sky) {821sky_material = sky->material;822823if (sky_material.is_valid()) {824material_data = static_cast<GLES3::SkyMaterialData *>(material_storage->material_get_data(sky_material, RS::SHADER_SKY));825if (!material_data || !material_data->shader_data->valid) {826material_data = nullptr;827}828}829830if (!material_data) {831sky_material = sky_globals.default_material;832material_data = static_cast<GLES3::SkyMaterialData *>(material_storage->material_get_data(sky_material, RS::SHADER_SKY));833}834} else if (background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) {835sky_material = sky_globals.fog_material;836material_data = static_cast<GLES3::SkyMaterialData *>(material_storage->material_get_data(sky_material, RS::SHADER_SKY));837}838839ERR_FAIL_NULL(material_data);840material_data->bind_uniforms();841842GLES3::SkyShaderData *shader_data = material_data->shader_data;843844ERR_FAIL_NULL(shader_data);845846// Camera847Projection camera;848849if (environment_get_sky_custom_fov(p_env)) {850float near_plane = p_projection.get_z_near();851float far_plane = p_projection.get_z_far();852float aspect = p_projection.get_aspect();853854camera.set_perspective(environment_get_sky_custom_fov(p_env), aspect, near_plane, far_plane);855} else {856camera = p_projection;857}858859Projection correction;860correction.set_depth_correction(false, true, false);861camera = correction * camera;862863Basis sky_transform = environment_get_sky_orientation(p_env);864sky_transform.invert();865sky_transform = sky_transform * p_transform.basis;866867bool success = material_storage->shaders.sky_shader.version_bind_shader(shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);868if (!success) {869return;870}871872material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::ORIENTATION, sky_transform, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);873material_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);874material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::POSITION, p_transform.origin, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);875material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::TIME, time, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);876material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::SKY_ENERGY_MULTIPLIER, p_sky_energy_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);877material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, p_luminance_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);878879Color fog_color = environment_get_fog_light_color(p_env).srgb_to_linear() * environment_get_fog_light_energy(p_env);880material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_ENABLED, environment_get_fog_enabled(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);881material_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);882material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_LIGHT_COLOR, fog_color, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);883material_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);884material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_DENSITY, environment_get_fog_density(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);885material_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);886material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::DIRECTIONAL_LIGHT_COUNT, sky_globals.directional_light_count, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);887888if (p_use_multiview) {889glBindBufferBase(GL_UNIFORM_BUFFER, SKY_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);890glBindBuffer(GL_UNIFORM_BUFFER, 0);891}892893glBindVertexArray(sky_globals.screen_triangle_array);894glDrawArrays(GL_TRIANGLES, 0, 3);895}896897void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_sky_energy_multiplier) {898GLES3::CubemapFilter *cubemap_filter = GLES3::CubemapFilter::get_singleton();899GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();900ERR_FAIL_COND(p_env.is_null());901902Sky *sky = sky_owner.get_or_null(environment_get_sky(p_env));903ERR_FAIL_NULL(sky);904905GLES3::SkyMaterialData *material_data = nullptr;906RID sky_material;907908RS::EnvironmentBG background = environment_get_background(p_env);909910if (sky) {911ERR_FAIL_NULL(sky);912sky_material = sky->material;913914if (sky_material.is_valid()) {915material_data = static_cast<GLES3::SkyMaterialData *>(material_storage->material_get_data(sky_material, RS::SHADER_SKY));916if (!material_data || !material_data->shader_data->valid) {917material_data = nullptr;918}919}920921if (!material_data) {922sky_material = sky_globals.default_material;923material_data = static_cast<GLES3::SkyMaterialData *>(material_storage->material_get_data(sky_material, RS::SHADER_SKY));924}925} else if (background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) {926sky_material = sky_globals.fog_material;927material_data = static_cast<GLES3::SkyMaterialData *>(material_storage->material_get_data(sky_material, RS::SHADER_SKY));928}929930ERR_FAIL_NULL(material_data);931material_data->bind_uniforms();932933GLES3::SkyShaderData *shader_data = material_data->shader_data;934935ERR_FAIL_NULL(shader_data);936937bool update_single_frame = sky->mode == RS::SKY_MODE_REALTIME || sky->mode == RS::SKY_MODE_QUALITY;938RS::SkyMode sky_mode = sky->mode;939940if (sky_mode == RS::SKY_MODE_AUTOMATIC) {941bool sun_scatter_enabled = environment_get_fog_enabled(p_env) && environment_get_fog_sun_scatter(p_env) > 0.001;942943if ((shader_data->uses_time || shader_data->uses_position) && sky->radiance_size == 256) {944update_single_frame = true;945sky_mode = RS::SKY_MODE_REALTIME;946} else if (shader_data->uses_light || sun_scatter_enabled || shader_data->ubo_size > 0) {947update_single_frame = false;948sky_mode = RS::SKY_MODE_INCREMENTAL;949} else {950update_single_frame = true;951sky_mode = RS::SKY_MODE_QUALITY;952}953}954955if (sky->processing_layer == 0 && sky_mode == RS::SKY_MODE_INCREMENTAL) {956// On the first frame after creating sky, rebuild in single frame957update_single_frame = true;958sky_mode = RS::SKY_MODE_QUALITY;959}960961int max_processing_layer = sky->mipmap_count;962963// Update radiance cubemap964if (sky->reflection_dirty && (sky->processing_layer >= max_processing_layer || update_single_frame)) {965static const Vector3 view_normals[6] = {966Vector3(+1, 0, 0),967Vector3(-1, 0, 0),968Vector3(0, +1, 0),969Vector3(0, -1, 0),970Vector3(0, 0, +1),971Vector3(0, 0, -1)972};973static const Vector3 view_up[6] = {974Vector3(0, -1, 0),975Vector3(0, -1, 0),976Vector3(0, 0, +1),977Vector3(0, 0, -1),978Vector3(0, -1, 0),979Vector3(0, -1, 0)980};981982Projection cm;983cm.set_perspective(90, 1, 0.01, 10.0);984Projection correction;985correction.set_depth_correction(true, true, false);986cm = correction * cm;987988bool success = material_storage->shaders.sky_shader.version_bind_shader(shader_data->version, SkyShaderGLES3::MODE_CUBEMAP);989if (!success) {990return;991}992993material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::POSITION, p_transform.origin, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP);994material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::TIME, time, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP);995material_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);996material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::SKY_ENERGY_MULTIPLIER, p_sky_energy_multiplier, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP);997material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, 1.0, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP);998999glBindVertexArray(sky_globals.screen_triangle_array);10001001glViewport(0, 0, sky->radiance_size, sky->radiance_size);1002glBindFramebuffer(GL_FRAMEBUFFER, sky->radiance_framebuffer);10031004scene_state.reset_gl_state();1005scene_state.set_gl_cull_mode(RS::CULL_MODE_DISABLED);1006scene_state.enable_gl_blend(false);10071008for (int i = 0; i < 6; i++) {1009Basis local_view = Basis::looking_at(view_normals[i], view_up[i]);1010material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::ORIENTATION, local_view, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP);1011glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, sky->raw_radiance, 0);1012glDrawArrays(GL_TRIANGLES, 0, 3);1013}10141015if (update_single_frame) {1016for (int i = 0; i < max_processing_layer; i++) {1017cubemap_filter->filter_radiance(sky->raw_radiance, sky->radiance, sky->radiance_framebuffer, sky->radiance_size, sky->mipmap_count, i);1018}1019} else {1020cubemap_filter->filter_radiance(sky->raw_radiance, sky->radiance, sky->radiance_framebuffer, sky->radiance_size, sky->mipmap_count, 0); // Just copy over the first mipmap.1021}1022sky->processing_layer = 1;1023sky->baked_exposure = p_sky_energy_multiplier;1024sky->reflection_dirty = false;1025} else {1026if (sky_mode == RS::SKY_MODE_INCREMENTAL && sky->processing_layer < max_processing_layer) {1027scene_state.reset_gl_state();1028scene_state.set_gl_cull_mode(RS::CULL_MODE_DISABLED);1029scene_state.enable_gl_blend(false);10301031cubemap_filter->filter_radiance(sky->raw_radiance, sky->radiance, sky->radiance_framebuffer, sky->radiance_size, sky->mipmap_count, sky->processing_layer);1032sky->processing_layer++;1033}1034}1035glViewport(0, 0, sky->screen_size.x, sky->screen_size.y);1036}10371038Ref<Image> RasterizerSceneGLES3::sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) {1039Sky *sky = sky_owner.get_or_null(p_sky);1040ERR_FAIL_NULL_V(sky, Ref<Image>());10411042_update_dirty_skys();10431044if (sky->radiance == 0) {1045return Ref<Image>();1046}10471048GLES3::CopyEffects *copy_effects = GLES3::CopyEffects::get_singleton();1049GLES3::Config *config = GLES3::Config::get_singleton();10501051GLuint rad_tex = 0;1052glGenTextures(1, &rad_tex);1053glBindTexture(GL_TEXTURE_2D, rad_tex);1054if (config->float_texture_supported) {1055glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, p_size.width, p_size.height, 0, GL_RGBA, GL_FLOAT, nullptr);1056GLES3::Utilities::get_singleton()->texture_allocated_data(rad_tex, p_size.width * p_size.height * 16, "Temp sky panorama");1057} else {1058// Fallback to RGBA8 on devices that don't support rendering to floating point textures. This will look bad, but we have no choice.1059glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, p_size.width, p_size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);1060GLES3::Utilities::get_singleton()->texture_allocated_data(rad_tex, p_size.width * p_size.height * 4, "Temp sky panorama");1061}10621063GLuint rad_fbo = 0;1064glGenFramebuffers(1, &rad_fbo);1065glBindFramebuffer(GL_FRAMEBUFFER, rad_fbo);1066glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rad_tex, 0);1067glActiveTexture(GL_TEXTURE0);1068glBindTexture(GL_TEXTURE_CUBE_MAP, sky->radiance);1069glViewport(0, 0, p_size.width, p_size.height);10701071glClearColor(0.0, 0.0, 0.0, 1.0);1072glClear(GL_COLOR_BUFFER_BIT);10731074copy_effects->copy_cube_to_panorama(p_bake_irradiance ? float(sky->mipmap_count) : 0.0);10751076glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);1077glDeleteFramebuffers(1, &rad_fbo);1078// Create a dummy texture so we can use texture_2d_get.1079RID tex_rid = GLES3::TextureStorage::get_singleton()->texture_allocate();1080{1081GLES3::Texture texture;1082texture.width = p_size.width;1083texture.height = p_size.height;1084texture.alloc_width = p_size.width;1085texture.alloc_height = p_size.height;1086texture.format = Image::FORMAT_RGBAF;1087texture.real_format = Image::FORMAT_RGBAF;1088texture.gl_format_cache = GL_RGBA;1089texture.gl_type_cache = GL_FLOAT;1090texture.type = GLES3::Texture::TYPE_2D;1091texture.target = GL_TEXTURE_2D;1092texture.active = true;1093texture.tex_id = rad_tex;1094texture.is_render_target = true; // HACK: Prevent TextureStorage from retaining a cached copy of the texture.1095GLES3::TextureStorage::get_singleton()->texture_2d_initialize_from_texture(tex_rid, texture);1096}10971098Ref<Image> img = GLES3::TextureStorage::get_singleton()->texture_2d_get(tex_rid);1099GLES3::Utilities::get_singleton()->texture_free_data(rad_tex);11001101GLES3::Texture &texture = *GLES3::TextureStorage::get_singleton()->get_texture(tex_rid);1102texture.is_render_target = false; // HACK: Avoid an error when freeing the texture.1103texture.tex_id = 0;1104GLES3::TextureStorage::get_singleton()->texture_free(tex_rid);11051106for (int i = 0; i < p_size.width; i++) {1107for (int j = 0; j < p_size.height; j++) {1108Color c = img->get_pixel(i, j);1109c.r *= p_energy;1110c.g *= p_energy;1111c.b *= p_energy;1112img->set_pixel(i, j, c);1113}1114}1115return img;1116}11171118/* ENVIRONMENT API */11191120void RasterizerSceneGLES3::environment_glow_set_use_bicubic_upscale(bool p_enable) {1121glow_bicubic_upscale = p_enable;1122}11231124void RasterizerSceneGLES3::environment_set_ssr_half_size(bool p_half_size) {1125}11261127void RasterizerSceneGLES3::environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) {1128}11291130void 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) {1131ssao_quality = p_quality;1132}11331134void 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) {1135}11361137void RasterizerSceneGLES3::environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) {1138}11391140void RasterizerSceneGLES3::environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) {1141}11421143void RasterizerSceneGLES3::environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) {1144}11451146void RasterizerSceneGLES3::environment_set_volumetric_fog_volume_size(int p_size, int p_depth) {1147}11481149void RasterizerSceneGLES3::environment_set_volumetric_fog_filter_active(bool p_enable) {1150}11511152Ref<Image> RasterizerSceneGLES3::environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) {1153ERR_FAIL_COND_V(p_env.is_null(), Ref<Image>());11541155RS::EnvironmentBG environment_background = environment_get_background(p_env);11561157if (environment_background == RS::ENV_BG_CAMERA_FEED || environment_background == RS::ENV_BG_CANVAS || environment_background == RS::ENV_BG_KEEP) {1158return Ref<Image>(); // Nothing to bake.1159}11601161RS::EnvironmentAmbientSource ambient_source = environment_get_ambient_source(p_env);11621163bool use_ambient_light = false;1164bool use_cube_map = false;1165if (ambient_source == RS::ENV_AMBIENT_SOURCE_BG && (environment_background == RS::ENV_BG_CLEAR_COLOR || environment_background == RS::ENV_BG_COLOR)) {1166use_ambient_light = true;1167} else {1168use_cube_map = (ambient_source == RS::ENV_AMBIENT_SOURCE_BG && environment_background == RS::ENV_BG_SKY) || ambient_source == RS::ENV_AMBIENT_SOURCE_SKY;1169use_ambient_light = use_cube_map || ambient_source == RS::ENV_AMBIENT_SOURCE_COLOR;1170}11711172use_cube_map = use_cube_map || (environment_background == RS::ENV_BG_SKY && environment_get_sky(p_env).is_valid());11731174Color ambient_color;1175float ambient_color_sky_mix = 0.0;1176if (use_ambient_light) {1177ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_env);1178const float ambient_energy = environment_get_ambient_light_energy(p_env);1179ambient_color = environment_get_ambient_light(p_env);1180ambient_color = ambient_color.srgb_to_linear();1181ambient_color.r *= ambient_energy;1182ambient_color.g *= ambient_energy;1183ambient_color.b *= ambient_energy;1184}11851186if (use_cube_map) {1187Ref<Image> panorama = sky_bake_panorama(environment_get_sky(p_env), environment_get_bg_energy_multiplier(p_env), p_bake_irradiance, p_size);1188if (use_ambient_light) {1189for (int x = 0; x < p_size.width; x++) {1190for (int y = 0; y < p_size.height; y++) {1191panorama->set_pixel(x, y, ambient_color.lerp(panorama->get_pixel(x, y), ambient_color_sky_mix));1192}1193}1194}1195return panorama;1196} else {1197const float bg_energy_multiplier = environment_get_bg_energy_multiplier(p_env);1198Color panorama_color = ((environment_background == RS::ENV_BG_CLEAR_COLOR) ? RSG::texture_storage->get_default_clear_color() : environment_get_bg_color(p_env));1199panorama_color = panorama_color.srgb_to_linear();1200panorama_color.r *= bg_energy_multiplier;1201panorama_color.g *= bg_energy_multiplier;1202panorama_color.b *= bg_energy_multiplier;12031204if (use_ambient_light) {1205panorama_color = ambient_color.lerp(panorama_color, ambient_color_sky_mix);1206}12071208Ref<Image> panorama = Image::create_empty(p_size.width, p_size.height, false, Image::FORMAT_RGBAF);1209panorama->fill(panorama_color);1210return panorama;1211}1212}12131214void RasterizerSceneGLES3::positional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) {1215scene_state.positional_shadow_quality = p_quality;1216}12171218void RasterizerSceneGLES3::directional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) {1219scene_state.directional_shadow_quality = p_quality;1220}12211222RID RasterizerSceneGLES3::fog_volume_instance_create(RID p_fog_volume) {1223return RID();1224}12251226void RasterizerSceneGLES3::fog_volume_instance_set_transform(RID p_fog_volume_instance, const Transform3D &p_transform) {1227}12281229void RasterizerSceneGLES3::fog_volume_instance_set_active(RID p_fog_volume_instance, bool p_active) {1230}12311232RID RasterizerSceneGLES3::fog_volume_instance_get_volume(RID p_fog_volume_instance) const {1233return RID();1234}12351236Vector3 RasterizerSceneGLES3::fog_volume_instance_get_position(RID p_fog_volume_instance) const {1237return Vector3();1238}12391240RID RasterizerSceneGLES3::voxel_gi_instance_create(RID p_voxel_gi) {1241return RID();1242}12431244void RasterizerSceneGLES3::voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) {1245}12461247bool RasterizerSceneGLES3::voxel_gi_needs_update(RID p_probe) const {1248return false;1249}12501251void RasterizerSceneGLES3::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) {1252}12531254void RasterizerSceneGLES3::voxel_gi_set_quality(RS::VoxelGIQuality) {1255}12561257_FORCE_INLINE_ static uint32_t _indices_to_primitives(RS::PrimitiveType p_primitive, uint32_t p_indices) {1258static const uint32_t divisor[RS::PRIMITIVE_MAX] = { 1, 2, 1, 3, 1 };1259static const uint32_t subtractor[RS::PRIMITIVE_MAX] = { 0, 0, 1, 0, 2 };1260return (p_indices - subtractor[p_primitive]) / divisor[p_primitive];1261}1262void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const RenderDataGLES3 *p_render_data, PassMode p_pass_mode, bool p_append) {1263GLES3::MeshStorage *mesh_storage = GLES3::MeshStorage::get_singleton();1264GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton();12651266if (p_render_list == RENDER_LIST_OPAQUE) {1267scene_state.used_screen_texture = false;1268scene_state.used_normal_texture = false;1269scene_state.used_depth_texture = false;1270scene_state.used_opaque_stencil = false;1271}12721273Plane near_plane;1274if (p_render_data->cam_orthogonal) {1275near_plane = Plane(-p_render_data->cam_transform.basis.get_column(Vector3::AXIS_Z), p_render_data->cam_transform.origin);1276near_plane.d += p_render_data->cam_projection.get_z_near();1277}1278float z_max = p_render_data->cam_projection.get_z_far() - p_render_data->cam_projection.get_z_near();12791280RenderList *rl = &render_list[p_render_list];12811282// Parse any updates on our geometry, updates surface caches and such1283_update_dirty_geometry_instances();12841285if (!p_append) {1286rl->clear();1287if (p_render_list == RENDER_LIST_OPAQUE) {1288render_list[RENDER_LIST_ALPHA].clear(); //opaque fills alpha too1289}1290}12911292//fill list12931294for (int i = 0; i < (int)p_render_data->instances->size(); i++) {1295GeometryInstanceGLES3 *inst = static_cast<GeometryInstanceGLES3 *>((*p_render_data->instances)[i]);12961297Vector3 center = inst->transform.origin;1298if (p_render_data->cam_orthogonal) {1299if (inst->use_aabb_center) {1300center = inst->transformed_aabb.get_support(-near_plane.normal);1301}1302inst->depth = near_plane.distance_to(center) - inst->sorting_offset;1303} else {1304if (inst->use_aabb_center) {1305center = inst->transformed_aabb.position + (inst->transformed_aabb.size * 0.5);1306}1307inst->depth = p_render_data->cam_transform.origin.distance_to(center) - inst->sorting_offset;1308}1309uint32_t depth_layer = CLAMP(int(inst->depth * 16 / z_max), 0, 15);13101311uint32_t flags = inst->base_flags; //fill flags if appropriate13121313if (inst->non_uniform_scale) {1314flags |= INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE;1315}13161317// Sets the index values for lookup in the shader1318// This has to be done after _setup_lights was called this frame13191320if (p_pass_mode == PASS_MODE_COLOR) {1321inst->light_passes.clear();1322inst->spot_light_gl_cache.clear();1323inst->omni_light_gl_cache.clear();1324inst->reflection_probes_local_transform_cache.clear();1325inst->reflection_probe_rid_cache.clear();1326uint64_t current_frame = RSG::rasterizer->get_frame_number();13271328if (inst->paired_omni_light_count) {1329for (uint32_t j = 0; j < inst->paired_omni_light_count; j++) {1330RID light_instance = inst->paired_omni_lights[j];1331if (light_storage->light_instance_get_render_pass(light_instance) != current_frame) {1332continue;1333}1334RID light = light_storage->light_instance_get_base_light(light_instance);1335int32_t shadow_id = light_storage->light_instance_get_shadow_id(light_instance);13361337if (light_storage->light_has_shadow(light) && shadow_id >= 0) {1338GeometryInstanceGLES3::LightPass pass;1339pass.light_id = light_storage->light_instance_get_gl_id(light_instance);1340pass.shadow_id = shadow_id;1341pass.light_instance_rid = light_instance;1342pass.is_omni = true;1343inst->light_passes.push_back(pass);1344} else {1345// Lights without shadow can all go in base pass.1346inst->omni_light_gl_cache.push_back((uint32_t)light_storage->light_instance_get_gl_id(light_instance));1347}1348}1349}13501351if (inst->paired_spot_light_count) {1352for (uint32_t j = 0; j < inst->paired_spot_light_count; j++) {1353RID light_instance = inst->paired_spot_lights[j];1354if (light_storage->light_instance_get_render_pass(light_instance) != current_frame) {1355continue;1356}1357RID light = light_storage->light_instance_get_base_light(light_instance);1358int32_t shadow_id = light_storage->light_instance_get_shadow_id(light_instance);13591360if (light_storage->light_has_shadow(light) && shadow_id >= 0) {1361GeometryInstanceGLES3::LightPass pass;1362pass.light_id = light_storage->light_instance_get_gl_id(light_instance);1363pass.shadow_id = shadow_id;1364pass.light_instance_rid = light_instance;1365inst->light_passes.push_back(pass);1366} else {1367// Lights without shadow can all go in base pass.1368inst->spot_light_gl_cache.push_back((uint32_t)light_storage->light_instance_get_gl_id(light_instance));1369}1370}1371}13721373if (p_render_data->reflection_probe.is_null() && inst->paired_reflection_probes.size() > 0) {1374// Do not include if we're rendering reflection probes.1375// We only support two probes for now and we handle them first come, first serve.1376// This should be improved one day, at minimum the list should be sorted by priority.13771378for (uint32_t pi = 0; pi < inst->paired_reflection_probes.size(); pi++) {1379RID probe_instance = inst->paired_reflection_probes[pi];1380RID atlas = light_storage->reflection_probe_instance_get_atlas(probe_instance);1381RID probe = light_storage->reflection_probe_instance_get_probe(probe_instance);1382uint32_t reflection_mask = light_storage->reflection_probe_get_reflection_mask(probe);1383if (atlas.is_valid() && (inst->layer_mask & reflection_mask)) {1384Transform3D local_matrix = p_render_data->inv_cam_transform * light_storage->reflection_probe_instance_get_transform(probe_instance);1385inst->reflection_probes_local_transform_cache.push_back(local_matrix.affine_inverse());1386inst->reflection_probe_rid_cache.push_back(probe_instance);1387}1388}1389}1390}13911392inst->flags_cache = flags;13931394GeometryInstanceSurface *surf = inst->surface_caches;13951396float lod_distance = 0.0;13971398if (p_render_data->cam_orthogonal) {1399lod_distance = 1.0;1400} else {1401Vector3 aabb_min = inst->transformed_aabb.position;1402Vector3 aabb_max = inst->transformed_aabb.position + inst->transformed_aabb.size;1403Vector3 camera_position = p_render_data->main_cam_transform.origin;1404Vector3 surface_distance = Vector3(0.0, 0.0, 0.0).max(aabb_min - camera_position).max(camera_position - aabb_max);14051406lod_distance = surface_distance.length();1407}14081409while (surf) {1410// LOD14111412if (p_render_data->screen_mesh_lod_threshold > 0.0 && mesh_storage->mesh_surface_has_lod(surf->surface)) {1413uint32_t indices = 0;1414surf->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);1415surf->index_count = indices;14161417if (p_render_data->render_info) {1418indices = _indices_to_primitives(surf->primitive, indices);1419if (p_render_list == RENDER_LIST_OPAQUE) { //opaque1420p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += indices;1421} else if (p_render_list == RENDER_LIST_SECONDARY) { //shadow1422p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += indices;1423}1424}14251426} else {1427surf->lod_index = 0;14281429if (p_render_data->render_info) {1430uint32_t to_draw = mesh_storage->mesh_surface_get_vertices_drawn_count(surf->surface);1431to_draw = _indices_to_primitives(surf->primitive, to_draw);1432to_draw *= inst->instance_count > 0 ? inst->instance_count : 1;1433if (p_render_list == RENDER_LIST_OPAQUE) { //opaque1434p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += to_draw;1435} else if (p_render_list == RENDER_LIST_SECONDARY) { //shadow1436p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += to_draw;1437}1438}1439}14401441// ADD Element1442if (p_pass_mode == PASS_MODE_COLOR) {1443#ifdef DEBUG_ENABLED1444bool force_alpha = unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW);1445#else1446bool force_alpha = false;1447#endif1448if (!force_alpha && (surf->flags & (GeometryInstanceSurface::FLAG_PASS_DEPTH | GeometryInstanceSurface::FLAG_PASS_OPAQUE))) {1449rl->add_element(surf);1450}1451if (force_alpha || (surf->flags & GeometryInstanceSurface::FLAG_PASS_ALPHA)) {1452render_list[RENDER_LIST_ALPHA].add_element(surf);1453}14541455if (surf->flags & GeometryInstanceSurface::FLAG_USES_SCREEN_TEXTURE) {1456scene_state.used_screen_texture = true;1457}1458if (surf->flags & GeometryInstanceSurface::FLAG_USES_NORMAL_TEXTURE) {1459scene_state.used_normal_texture = true;1460}1461if (surf->flags & GeometryInstanceSurface::FLAG_USES_DEPTH_TEXTURE) {1462scene_state.used_depth_texture = true;1463}1464if ((surf->flags & GeometryInstanceSurface::FLAG_USES_STENCIL) && !force_alpha && (surf->flags & (GeometryInstanceSurface::FLAG_PASS_DEPTH | GeometryInstanceSurface::FLAG_PASS_OPAQUE))) {1465scene_state.used_opaque_stencil = true;1466}14671468} else if (p_pass_mode == PASS_MODE_SHADOW) {1469if (surf->flags & GeometryInstanceSurface::FLAG_PASS_SHADOW) {1470rl->add_element(surf);1471}1472} else if (p_pass_mode == PASS_MODE_MATERIAL) {1473if (surf->flags & (GeometryInstanceSurface::FLAG_PASS_DEPTH | GeometryInstanceSurface::FLAG_PASS_OPAQUE | GeometryInstanceSurface::FLAG_PASS_ALPHA)) {1474rl->add_element(surf);1475}1476} else {1477if (surf->flags & (GeometryInstanceSurface::FLAG_PASS_DEPTH | GeometryInstanceSurface::FLAG_PASS_OPAQUE)) {1478rl->add_element(surf);1479}1480}14811482surf->sort.depth_layer = depth_layer;1483surf->finished_base_pass = false;1484surf->light_pass_index = 0;14851486surf = surf->next;1487}1488}1489}14901491void RasterizerSceneGLES3::_update_scene_ubo(GLuint &p_ubo_buffer, GLuint p_index, uint32_t p_size, const void *p_source_data, String p_name) {1492if (p_ubo_buffer == 0) {1493glGenBuffers(1, &p_ubo_buffer);1494glBindBufferBase(GL_UNIFORM_BUFFER, p_index, p_ubo_buffer);1495GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, p_ubo_buffer, p_size, p_source_data, GL_STREAM_DRAW, p_name);1496} else {1497glBindBufferBase(GL_UNIFORM_BUFFER, p_index, p_ubo_buffer);1498glBufferData(GL_UNIFORM_BUFFER, p_size, p_source_data, GL_STREAM_DRAW);1499}15001501glBindBuffer(GL_UNIFORM_BUFFER, 0);1502}15031504// Needs to be called after _setup_lights so that directional_light_count is accurate.1505void 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) {1506Projection correction;1507correction.set_depth_correction(p_flip_y, true, false);1508Projection projection = correction * p_render_data->cam_projection;1509//store camera into ubo1510GLES3::MaterialStorage::store_camera(projection, scene_state.data.projection_matrix);1511GLES3::MaterialStorage::store_camera(projection.inverse(), scene_state.data.inv_projection_matrix);1512GLES3::MaterialStorage::store_transform(p_render_data->cam_transform, scene_state.data.inv_view_matrix);1513GLES3::MaterialStorage::store_transform(p_render_data->inv_cam_transform, scene_state.data.view_matrix);1514GLES3::MaterialStorage::store_transform(p_render_data->main_cam_transform, scene_state.data.main_cam_inv_view_matrix);1515scene_state.data.camera_visible_layers = p_render_data->camera_visible_layers;15161517if (p_render_data->view_count > 1) {1518for (uint32_t v = 0; v < p_render_data->view_count; v++) {1519projection = correction * p_render_data->view_projection[v];1520GLES3::MaterialStorage::store_camera(projection, scene_state.multiview_data.projection_matrix_view[v]);1521GLES3::MaterialStorage::store_camera(projection.inverse(), scene_state.multiview_data.inv_projection_matrix_view[v]);15221523scene_state.multiview_data.eye_offset[v][0] = p_render_data->view_eye_offset[v].x;1524scene_state.multiview_data.eye_offset[v][1] = p_render_data->view_eye_offset[v].y;1525scene_state.multiview_data.eye_offset[v][2] = p_render_data->view_eye_offset[v].z;1526scene_state.multiview_data.eye_offset[v][3] = 0.0;1527}1528}15291530// Only render the lights without shadows in the base pass.1531scene_state.data.directional_light_count = p_render_data->directional_light_count - p_render_data->directional_shadow_count;15321533// Lights with shadows still need to be applied to fog sun scatter.1534scene_state.data.directional_shadow_count = p_render_data->directional_shadow_count;15351536scene_state.data.z_far = p_render_data->z_far;1537scene_state.data.z_near = p_render_data->z_near;15381539scene_state.data.viewport_size[0] = p_screen_size.x;1540scene_state.data.viewport_size[1] = p_screen_size.y;15411542Size2 screen_pixel_size = Vector2(1.0, 1.0) / Size2(p_screen_size);1543scene_state.data.screen_pixel_size[0] = screen_pixel_size.x;1544scene_state.data.screen_pixel_size[1] = screen_pixel_size.y;15451546scene_state.data.luminance_multiplier = p_render_data->luminance_multiplier;15471548scene_state.data.shadow_bias = p_shadow_bias;1549scene_state.data.pancake_shadows = p_pancake_shadows;15501551//time global variables1552scene_state.data.time = time;15531554if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {1555scene_state.data.use_ambient_light = true;1556scene_state.data.ambient_light_color_energy[0] = 1;1557scene_state.data.ambient_light_color_energy[1] = 1;1558scene_state.data.ambient_light_color_energy[2] = 1;1559scene_state.data.ambient_light_color_energy[3] = 1.0;1560scene_state.data.use_ambient_cubemap = false;1561scene_state.data.use_reflection_cubemap = false;1562} else if (is_environment(p_render_data->environment)) {1563RS::EnvironmentBG env_bg = environment_get_background(p_render_data->environment);1564RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_render_data->environment);15651566float bg_energy_multiplier = environment_get_bg_energy_multiplier(p_render_data->environment);15671568scene_state.data.ambient_light_color_energy[3] = bg_energy_multiplier;15691570scene_state.data.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_render_data->environment);15711572//ambient1573if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) {1574Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_render_data->environment);1575color = color.srgb_to_linear();15761577scene_state.data.ambient_light_color_energy[0] = color.r * bg_energy_multiplier;1578scene_state.data.ambient_light_color_energy[1] = color.g * bg_energy_multiplier;1579scene_state.data.ambient_light_color_energy[2] = color.b * bg_energy_multiplier;1580scene_state.data.use_ambient_light = true;1581scene_state.data.use_ambient_cubemap = false;1582} else {1583float energy = environment_get_ambient_light_energy(p_render_data->environment);1584Color color = environment_get_ambient_light(p_render_data->environment);1585color = color.srgb_to_linear();1586scene_state.data.ambient_light_color_energy[0] = color.r * energy;1587scene_state.data.ambient_light_color_energy[1] = color.g * energy;1588scene_state.data.ambient_light_color_energy[2] = color.b * energy;15891590Basis sky_transform = environment_get_sky_orientation(p_render_data->environment);1591sky_transform = sky_transform.inverse() * p_render_data->cam_transform.basis;1592GLES3::MaterialStorage::store_transform_3x3(sky_transform, scene_state.data.radiance_inverse_xform);1593scene_state.data.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY;1594scene_state.data.use_ambient_light = scene_state.data.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR;1595}15961597//specular1598RS::EnvironmentReflectionSource ref_src = environment_get_reflection_source(p_render_data->environment);1599if ((ref_src == RS::ENV_REFLECTION_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ref_src == RS::ENV_REFLECTION_SOURCE_SKY) {1600scene_state.data.use_reflection_cubemap = true;1601} else {1602scene_state.data.use_reflection_cubemap = false;1603}16041605scene_state.data.fog_enabled = environment_get_fog_enabled(p_render_data->environment);1606scene_state.data.fog_mode = environment_get_fog_mode(p_render_data->environment);1607scene_state.data.fog_density = environment_get_fog_density(p_render_data->environment);1608scene_state.data.fog_height = environment_get_fog_height(p_render_data->environment);1609scene_state.data.fog_depth_curve = environment_get_fog_depth_curve(p_render_data->environment);1610scene_state.data.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.data.z_far;1611scene_state.data.fog_depth_begin = MIN(environment_get_fog_depth_begin(p_render_data->environment), scene_state.data.fog_depth_end - 0.001);1612scene_state.data.fog_height_density = environment_get_fog_height_density(p_render_data->environment);1613scene_state.data.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment);16141615Color fog_color = environment_get_fog_light_color(p_render_data->environment).srgb_to_linear();1616float fog_energy = environment_get_fog_light_energy(p_render_data->environment);16171618scene_state.data.fog_light_color[0] = fog_color.r * fog_energy;1619scene_state.data.fog_light_color[1] = fog_color.g * fog_energy;1620scene_state.data.fog_light_color[2] = fog_color.b * fog_energy;16211622scene_state.data.fog_sun_scatter = environment_get_fog_sun_scatter(p_render_data->environment);16231624} else {1625}16261627if (p_render_data->camera_attributes.is_valid()) {1628scene_state.data.emissive_exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);1629scene_state.data.IBL_exposure_normalization = 1.0;1630if (is_environment(p_render_data->environment)) {1631RID sky_rid = environment_get_sky(p_render_data->environment);1632if (sky_rid.is_valid()) {1633float current_exposure = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes) * environment_get_bg_intensity(p_render_data->environment);1634scene_state.data.IBL_exposure_normalization = current_exposure / MAX(0.001, sky_get_baked_exposure(sky_rid));1635}1636}1637} else if (scene_state.data.emissive_exposure_normalization > 0.0) {1638// This branch is triggered when using render_material().1639// Emissive is set outside the function, so don't set it.1640// IBL isn't used don't set it.1641} else {1642scene_state.data.emissive_exposure_normalization = 1.0;1643scene_state.data.IBL_exposure_normalization = 1.0;1644}16451646_update_scene_ubo(scene_state.ubo_buffer, SCENE_DATA_UNIFORM_LOCATION, sizeof(SceneState::UBO), &scene_state.data, "Scene state UBO");1647if (p_render_data->view_count > 1) {1648_update_scene_ubo(scene_state.multiview_buffer, SCENE_MULTIVIEW_UNIFORM_LOCATION, sizeof(SceneState::MultiviewUBO), &scene_state.multiview_data, "Multiview UBO");1649}16501651if (scene_state.prev_data_state != 0) {1652void *source_data = scene_state.prev_data_state == 1 ? &scene_state.data : &scene_state.prev_data;1653_update_scene_ubo(scene_state.prev_ubo_buffer, SCENE_PREV_DATA_UNIFORM_LOCATION, sizeof(SceneState::UBO), source_data, "Previous scene state UBO");16541655if (p_render_data->view_count > 1) {1656source_data = scene_state.prev_data_state == 1 ? &scene_state.multiview_data : &scene_state.prev_multiview_data;1657_update_scene_ubo(scene_state.prev_multiview_buffer, SCENE_PREV_MULTIVIEW_UNIFORM_LOCATION, sizeof(SceneState::MultiviewUBO), source_data, "Previous multiview UBO");1658}1659}1660}16611662// Puts lights into Uniform Buffers. Needs to be called before _fill_list as this caches the index of each light in the Uniform Buffer1663void 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) {1664GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton();1665GLES3::Config *config = GLES3::Config::get_singleton();16661667const Transform3D inverse_transform = p_render_data->inv_cam_transform;16681669const PagedArray<RID> &lights = *p_render_data->lights;16701671r_directional_light_count = 0;1672r_omni_light_count = 0;1673r_spot_light_count = 0;1674r_directional_shadow_count = 0;16751676int num_lights = lights.size();16771678for (int i = 0; i < num_lights; i++) {1679GLES3::LightInstance *li = GLES3::LightStorage::get_singleton()->get_light_instance(lights[i]);1680if (!li) {1681continue;1682}1683RID base = li->light;16841685ERR_CONTINUE(base.is_null());16861687RS::LightType type = light_storage->light_get_type(base);1688switch (type) {1689case RS::LIGHT_DIRECTIONAL: {1690if (r_directional_light_count >= RendererSceneRender::MAX_DIRECTIONAL_LIGHTS || light_storage->light_directional_get_sky_mode(base) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) {1691continue;1692}16931694// If a DirectionalLight has shadows, we will add it to the end of the array and work in.1695bool has_shadow = light_storage->light_has_shadow(base);16961697int index = r_directional_light_count - r_directional_shadow_count;16981699if (has_shadow) {1700// Lights with shadow are incremented from the end of the array.1701index = MAX_DIRECTIONAL_LIGHTS - 1 - r_directional_shadow_count;1702}1703DirectionalLightData &light_data = scene_state.directional_lights[index];17041705Transform3D light_transform = li->transform;17061707Vector3 direction = inverse_transform.basis.xform(light_transform.basis.xform(Vector3(0, 0, 1))).normalized();17081709light_data.direction[0] = direction.x;1710light_data.direction[1] = direction.y;1711light_data.direction[2] = direction.z;17121713light_data.bake_mode = light_storage->light_get_bake_mode(base);17141715float sign = light_storage->light_is_negative(base) ? -1 : 1;17161717light_data.energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY);17181719if (is_using_physical_light_units()) {1720light_data.energy *= light_storage->light_get_param(base, RS::LIGHT_PARAM_INTENSITY);1721} else {1722light_data.energy *= Math::PI;1723}17241725if (p_render_data->camera_attributes.is_valid()) {1726light_data.energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);1727}17281729Color linear_col = light_storage->light_get_color(base).srgb_to_linear();1730light_data.color[0] = linear_col.r;1731light_data.color[1] = linear_col.g;1732light_data.color[2] = linear_col.b;17331734float size = light_storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);1735light_data.size = 1.0 - Math::cos(Math::deg_to_rad(size)); //angle to cosine offset17361737light_data.specular = light_storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR);17381739light_data.mask = light_storage->light_get_cull_mask(base);17401741light_data.shadow_opacity = (p_using_shadows && light_storage->light_has_shadow(base))1742? light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_OPACITY)1743: 0.0;17441745if (has_shadow) {1746DirectionalShadowData &shadow_data = scene_state.directional_shadows[MAX_DIRECTIONAL_LIGHTS - 1 - r_directional_shadow_count];17471748RS::LightDirectionalShadowMode shadow_mode = light_storage->light_directional_get_shadow_mode(base);17491750int limit = shadow_mode == RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL ? 0 : (shadow_mode == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS ? 1 : 3);17511752shadow_data.shadow_atlas_pixel_size = 1.0 / light_storage->directional_shadow_get_size();17531754shadow_data.blend_splits = uint32_t((shadow_mode != RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL) && light_storage->light_directional_get_blend_splits(base));1755for (int j = 0; j < 4; j++) {1756Rect2 atlas_rect = li->shadow_transform[j].atlas_rect;1757Projection correction;1758correction.set_depth_correction(false, true, false);1759Projection matrix = correction * li->shadow_transform[j].camera;1760float split = li->shadow_transform[MIN(limit, j)].split;17611762Projection bias;1763bias.set_light_bias();1764Projection rectm;1765rectm.set_light_atlas_rect(atlas_rect);17661767Transform3D modelview = (inverse_transform * li->shadow_transform[j].transform).inverse();17681769shadow_data.direction[0] = light_data.direction[0];1770shadow_data.direction[1] = light_data.direction[1];1771shadow_data.direction[2] = light_data.direction[2];17721773Projection shadow_mtx = rectm * bias * matrix * modelview;1774shadow_data.shadow_split_offsets[j] = split;1775shadow_data.shadow_normal_bias[j] = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * li->shadow_transform[j].shadow_texel_size;1776GLES3::MaterialStorage::store_camera(shadow_mtx, shadow_data.shadow_matrices[j]);1777}1778float fade_start = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_FADE_START);1779shadow_data.fade_from = -shadow_data.shadow_split_offsets[3] * MIN(fade_start, 0.999);1780shadow_data.fade_to = -shadow_data.shadow_split_offsets[3];17811782r_directional_shadow_count++;1783}17841785r_directional_light_count++;1786} break;1787case RS::LIGHT_OMNI: {1788if (r_omni_light_count >= (uint32_t)config->max_renderable_lights) {1789continue;1790}17911792const real_t distance = p_render_data->cam_transform.origin.distance_to(li->transform.origin);17931794if (light_storage->light_is_distance_fade_enabled(li->light)) {1795const float fade_begin = light_storage->light_get_distance_fade_begin(li->light);1796const float fade_length = light_storage->light_get_distance_fade_length(li->light);17971798if (distance > fade_begin) {1799if (distance > fade_begin + fade_length) {1800// Out of range, don't draw this light to improve performance.1801continue;1802}1803}1804}18051806scene_state.omni_light_sort[r_omni_light_count].instance = li;1807scene_state.omni_light_sort[r_omni_light_count].depth = distance;1808r_omni_light_count++;1809} break;1810case RS::LIGHT_SPOT: {1811if (r_spot_light_count >= (uint32_t)config->max_renderable_lights) {1812continue;1813}18141815const real_t distance = p_render_data->cam_transform.origin.distance_to(li->transform.origin);18161817if (light_storage->light_is_distance_fade_enabled(li->light)) {1818const float fade_begin = light_storage->light_get_distance_fade_begin(li->light);1819const float fade_length = light_storage->light_get_distance_fade_length(li->light);18201821if (distance > fade_begin) {1822if (distance > fade_begin + fade_length) {1823// Out of range, don't draw this light to improve performance.1824continue;1825}1826}1827}18281829scene_state.spot_light_sort[r_spot_light_count].instance = li;1830scene_state.spot_light_sort[r_spot_light_count].depth = distance;1831r_spot_light_count++;1832} break;1833}18341835li->last_pass = RSG::rasterizer->get_frame_number();1836}18371838if (r_omni_light_count) {1839SortArray<InstanceSort<GLES3::LightInstance>> sorter;1840sorter.sort(scene_state.omni_light_sort, r_omni_light_count);1841}18421843if (r_spot_light_count) {1844SortArray<InstanceSort<GLES3::LightInstance>> sorter;1845sorter.sort(scene_state.spot_light_sort, r_spot_light_count);1846}18471848int num_positional_shadows = 0;18491850for (uint32_t i = 0; i < (r_omni_light_count + r_spot_light_count); i++) {1851uint32_t index = (i < r_omni_light_count) ? i : i - (r_omni_light_count);1852LightData &light_data = (i < r_omni_light_count) ? scene_state.omni_lights[index] : scene_state.spot_lights[index];1853RS::LightType type = (i < r_omni_light_count) ? RS::LIGHT_OMNI : RS::LIGHT_SPOT;1854GLES3::LightInstance *li = (i < r_omni_light_count) ? scene_state.omni_light_sort[index].instance : scene_state.spot_light_sort[index].instance;1855real_t distance = (i < r_omni_light_count) ? scene_state.omni_light_sort[index].depth : scene_state.spot_light_sort[index].depth;1856RID base = li->light;18571858li->gl_id = index;18591860Transform3D light_transform = li->transform;1861Vector3 pos = inverse_transform.xform(light_transform.origin);18621863light_data.position[0] = pos.x;1864light_data.position[1] = pos.y;1865light_data.position[2] = pos.z;18661867light_data.bake_mode = light_storage->light_get_bake_mode(base);18681869float radius = MAX(0.001, light_storage->light_get_param(base, RS::LIGHT_PARAM_RANGE));1870light_data.inv_radius = 1.0 / radius;18711872Vector3 direction = inverse_transform.basis.xform(light_transform.basis.xform(Vector3(0, 0, -1))).normalized();18731874light_data.direction[0] = direction.x;1875light_data.direction[1] = direction.y;1876light_data.direction[2] = direction.z;18771878float size = light_storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);18791880light_data.size = size;18811882float sign = light_storage->light_is_negative(base) ? -1 : 1;1883Color linear_col = light_storage->light_get_color(base).srgb_to_linear();18841885// Reuse fade begin, fade length and distance for shadow LOD determination later.1886float fade_begin = 0.0;1887float fade_shadow = 0.0;1888float fade_length = 0.0;18891890float fade = 1.0;1891float shadow_opacity_fade = 1.0;18921893if (light_storage->light_is_distance_fade_enabled(base)) {1894fade_begin = light_storage->light_get_distance_fade_begin(base);1895fade_shadow = light_storage->light_get_distance_fade_shadow(base);1896fade_length = light_storage->light_get_distance_fade_length(base);18971898if (distance > fade_begin) {1899// Use `smoothstep()` to make opacity changes more gradual and less noticeable to the player.1900fade = Math::smoothstep(0.0f, 1.0f, 1.0f - float(distance - fade_begin) / fade_length);1901}1902if (distance > fade_shadow) {1903shadow_opacity_fade = Math::smoothstep(0.0f, 1.0f, 1.0f - float(distance - fade_shadow) / fade_length);1904}1905}19061907float energy = sign * light_storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * fade;19081909if (is_using_physical_light_units()) {1910energy *= light_storage->light_get_param(base, RS::LIGHT_PARAM_INTENSITY);19111912// Convert from Luminous Power to Luminous Intensity1913if (type == RS::LIGHT_OMNI) {1914energy *= 1.0 / (Math::PI * 4.0);1915} else {1916// Spot Lights are not physically accurate, Luminous Intensity should change in relation to the cone angle.1917// We make this assumption to keep them easy to control.1918energy *= 1.0 / Math::PI;1919}1920} else {1921energy *= Math::PI;1922}19231924if (p_render_data->camera_attributes.is_valid()) {1925energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);1926}19271928light_data.color[0] = linear_col.r * energy;1929light_data.color[1] = linear_col.g * energy;1930light_data.color[2] = linear_col.b * energy;19311932light_data.attenuation = light_storage->light_get_param(base, RS::LIGHT_PARAM_ATTENUATION);19331934light_data.inv_spot_attenuation = 1.0f / light_storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ATTENUATION);19351936float spot_angle = light_storage->light_get_param(base, RS::LIGHT_PARAM_SPOT_ANGLE);1937light_data.cos_spot_angle = Math::cos(Math::deg_to_rad(spot_angle));19381939light_data.specular_amount = light_storage->light_get_param(base, RS::LIGHT_PARAM_SPECULAR) * 2.0;19401941// Setup shadows1942const bool needs_shadow =1943p_using_shadows &&1944light_storage->owns_shadow_atlas(p_render_data->shadow_atlas) &&1945light_storage->shadow_atlas_owns_light_instance(p_render_data->shadow_atlas, li->self) &&1946light_storage->light_has_shadow(base);19471948bool in_shadow_range = true;1949if (needs_shadow && light_storage->light_is_distance_fade_enabled(base)) {1950if (distance > fade_shadow + fade_length) {1951// Out of range, don't draw shadows to improve performance.1952in_shadow_range = false;1953}1954}19551956// Fill in the shadow information.1957if (needs_shadow && in_shadow_range) {1958if (num_positional_shadows >= config->max_renderable_lights) {1959continue;1960}1961ShadowData &shadow_data = scene_state.positional_shadows[num_positional_shadows];1962li->shadow_id = num_positional_shadows;1963num_positional_shadows++;19641965light_data.shadow_opacity = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_OPACITY) * shadow_opacity_fade;19661967float shadow_texel_size = light_storage->light_instance_get_shadow_texel_size(li->self, p_render_data->shadow_atlas);1968shadow_data.shadow_atlas_pixel_size = shadow_texel_size;1969shadow_data.shadow_normal_bias = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * shadow_texel_size * 10.0;19701971shadow_data.light_position[0] = light_data.position[0];1972shadow_data.light_position[1] = light_data.position[1];1973shadow_data.light_position[2] = light_data.position[2];19741975if (type == RS::LIGHT_OMNI) {1976Transform3D proj = (inverse_transform * light_transform).inverse();19771978GLES3::MaterialStorage::store_transform(proj, shadow_data.shadow_matrix);19791980} else if (type == RS::LIGHT_SPOT) {1981Transform3D modelview = (inverse_transform * light_transform).inverse();1982Projection bias;1983bias.set_light_bias();19841985Projection correction;1986correction.set_depth_correction(false, true, false);1987Projection cm = correction * li->shadow_transform[0].camera;1988Projection shadow_mtx = bias * cm * modelview;1989GLES3::MaterialStorage::store_camera(shadow_mtx, shadow_data.shadow_matrix);1990}1991}1992}19931994// TODO, to avoid stalls, should rotate between 3 buffers based on frame index.1995// TODO, consider mapping the buffer as in 2D1996glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_OMNILIGHT_UNIFORM_LOCATION, scene_state.omni_light_buffer);1997if (r_omni_light_count) {1998glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(LightData) * r_omni_light_count, scene_state.omni_lights);1999}20002001glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_SPOTLIGHT_UNIFORM_LOCATION, scene_state.spot_light_buffer);2002if (r_spot_light_count) {2003glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(LightData) * r_spot_light_count, scene_state.spot_lights);2004}20052006glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_DIRECTIONAL_LIGHT_UNIFORM_LOCATION, scene_state.directional_light_buffer);2007if (r_directional_light_count) {2008glBufferData(GL_UNIFORM_BUFFER, sizeof(DirectionalLightData) * MAX_DIRECTIONAL_LIGHTS, scene_state.directional_lights, GL_STREAM_DRAW);2009}20102011glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_POSITIONAL_SHADOW_UNIFORM_LOCATION, scene_state.positional_shadow_buffer);2012if (num_positional_shadows) {2013glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(ShadowData) * num_positional_shadows, scene_state.positional_shadows);2014}20152016glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_DIRECTIONAL_SHADOW_UNIFORM_LOCATION, scene_state.directional_shadow_buffer);2017if (r_directional_shadow_count) {2018glBufferData(GL_UNIFORM_BUFFER, sizeof(DirectionalShadowData) * MAX_DIRECTIONAL_LIGHTS, scene_state.directional_shadows, GL_STREAM_DRAW);2019}2020glBindBuffer(GL_UNIFORM_BUFFER, 0);2021}20222023// Render shadows2024void RasterizerSceneGLES3::_render_shadows(const RenderDataGLES3 *p_render_data, const Size2i &p_viewport_size) {2025GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton();20262027LocalVector<int> cube_shadows;2028LocalVector<int> shadows;2029LocalVector<int> directional_shadows;20302031float lod_distance_multiplier = p_render_data->cam_projection.get_lod_multiplier();20322033// Put lights into buckets for omni (cube shadows), directional, and spot.2034{2035for (int i = 0; i < p_render_data->render_shadow_count; i++) {2036RID li = p_render_data->render_shadows[i].light;2037RID base = light_storage->light_instance_get_base_light(li);20382039if (light_storage->light_get_type(base) == RS::LIGHT_DIRECTIONAL) {2040directional_shadows.push_back(i);2041} else if (light_storage->light_get_type(base) == RS::LIGHT_OMNI && light_storage->light_omni_get_shadow_mode(base) == RS::LIGHT_OMNI_SHADOW_CUBE) {2042cube_shadows.push_back(i);2043} else {2044shadows.push_back(i);2045}2046}2047if (directional_shadows.size()) {2048light_storage->update_directional_shadow_atlas();2049}2050}20512052bool render_shadows = directional_shadows.size() || shadows.size() || cube_shadows.size();20532054if (render_shadows) {2055RENDER_TIMESTAMP("Render Shadows");20562057// Render cubemap shadows.2058for (const int &index : cube_shadows) {2059_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);2060}2061// Render directional shadows.2062for (uint32_t i = 0; i < directional_shadows.size(); i++) {2063_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);2064}2065// Render positional shadows (Spotlight and Omnilight with dual-paraboloid).2066for (uint32_t i = 0; i < shadows.size(); i++) {2067_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);2068}2069}2070}20712072void 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) {2073GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton();20742075ERR_FAIL_COND(!light_storage->owns_light_instance(p_light));20762077RID base = light_storage->light_instance_get_base_light(p_light);20782079float zfar = 0.0;2080bool use_pancake = false;2081float shadow_bias = 0.0;2082bool reverse_cull = false;2083bool needs_clear = false;20842085Projection light_projection;2086Transform3D light_transform;2087GLuint shadow_fb = 0;2088Rect2i atlas_rect;20892090if (light_storage->light_get_type(base) == RS::LIGHT_DIRECTIONAL) {2091// Set pssm stuff.2092uint64_t last_scene_shadow_pass = light_storage->light_instance_get_shadow_pass(p_light);2093if (last_scene_shadow_pass != get_scene_pass()) {2094light_storage->light_instance_set_directional_rect(p_light, light_storage->get_directional_shadow_rect());2095light_storage->directional_shadow_increase_current_light();2096light_storage->light_instance_set_shadow_pass(p_light, get_scene_pass());2097}20982099atlas_rect = light_storage->light_instance_get_directional_rect(p_light);21002101if (light_storage->light_directional_get_shadow_mode(base) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) {2102atlas_rect.size.width /= 2;2103atlas_rect.size.height /= 2;21042105if (p_pass == 1) {2106atlas_rect.position.x += atlas_rect.size.width;2107} else if (p_pass == 2) {2108atlas_rect.position.y += atlas_rect.size.height;2109} else if (p_pass == 3) {2110atlas_rect.position += atlas_rect.size;2111}2112} else if (light_storage->light_directional_get_shadow_mode(base) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) {2113atlas_rect.size.height /= 2;21142115if (p_pass == 0) {2116} else {2117atlas_rect.position.y += atlas_rect.size.height;2118}2119}21202121use_pancake = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE) > 0;2122light_projection = light_storage->light_instance_get_shadow_camera(p_light, p_pass);2123light_transform = light_storage->light_instance_get_shadow_transform(p_light, p_pass);21242125float directional_shadow_size = light_storage->directional_shadow_get_size();2126Rect2 atlas_rect_norm = atlas_rect;2127atlas_rect_norm.position /= directional_shadow_size;2128atlas_rect_norm.size /= directional_shadow_size;2129light_storage->light_instance_set_directional_shadow_atlas_rect(p_light, p_pass, atlas_rect_norm);21302131zfar = RSG::light_storage->light_get_param(base, RS::LIGHT_PARAM_RANGE);2132shadow_fb = light_storage->direction_shadow_get_fb();2133reverse_cull = !light_storage->light_get_reverse_cull_face_mode(base);21342135float bias_scale = light_storage->light_instance_get_shadow_bias_scale(p_light, p_pass);2136shadow_bias = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0 * bias_scale;21372138} else {2139// Set from shadow atlas.21402141ERR_FAIL_COND(!light_storage->owns_shadow_atlas(p_shadow_atlas));2142ERR_FAIL_COND(!light_storage->shadow_atlas_owns_light_instance(p_shadow_atlas, p_light));21432144uint32_t key = light_storage->shadow_atlas_get_light_instance_key(p_shadow_atlas, p_light);21452146uint32_t quadrant = (key >> GLES3::LightStorage::QUADRANT_SHIFT) & 0x3;2147uint32_t shadow = key & GLES3::LightStorage::SHADOW_INDEX_MASK;21482149ERR_FAIL_INDEX((int)shadow, light_storage->shadow_atlas_get_quadrant_shadows_length(p_shadow_atlas, quadrant));21502151int shadow_size = light_storage->shadow_atlas_get_quadrant_shadow_size(p_shadow_atlas, quadrant);21522153shadow_fb = light_storage->shadow_atlas_get_quadrant_shadow_fb(p_shadow_atlas, quadrant, shadow);21542155zfar = light_storage->light_get_param(base, RS::LIGHT_PARAM_RANGE);2156reverse_cull = !light_storage->light_get_reverse_cull_face_mode(base);21572158if (light_storage->light_get_type(base) == RS::LIGHT_OMNI) {2159if (light_storage->light_omni_get_shadow_mode(base) == RS::LIGHT_OMNI_SHADOW_CUBE) {2160GLuint shadow_texture = light_storage->shadow_atlas_get_quadrant_shadow_texture(p_shadow_atlas, quadrant, shadow);2161glBindFramebuffer(GL_FRAMEBUFFER, shadow_fb);21622163static GLenum cube_map_faces[6] = {2164GL_TEXTURE_CUBE_MAP_POSITIVE_X,2165GL_TEXTURE_CUBE_MAP_NEGATIVE_X,2166// Flipped order for Y to match what the RD renderer expects2167// (and thus what is given to us by the Rendering Server).2168GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,2169GL_TEXTURE_CUBE_MAP_POSITIVE_Y,2170GL_TEXTURE_CUBE_MAP_POSITIVE_Z,2171GL_TEXTURE_CUBE_MAP_NEGATIVE_Z2172};21732174glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, cube_map_faces[p_pass], shadow_texture, 0);21752176light_projection = light_storage->light_instance_get_shadow_camera(p_light, p_pass);2177light_transform = light_storage->light_instance_get_shadow_transform(p_light, p_pass);2178shadow_size = shadow_size / 2;2179} else {2180ERR_FAIL_MSG("Dual paraboloid shadow mode not supported in the Compatibility renderer. Please use CubeMap shadow mode instead.");2181}21822183shadow_bias = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS);21842185} else if (light_storage->light_get_type(base) == RS::LIGHT_SPOT) {2186light_projection = light_storage->light_instance_get_shadow_camera(p_light, 0);2187light_transform = light_storage->light_instance_get_shadow_transform(p_light, 0);21882189shadow_bias = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) / 10.0;2190// Prebake range into bias so we can scale based on distance easily.2191shadow_bias *= light_storage->light_get_param(base, RS::LIGHT_PARAM_RANGE);2192}2193atlas_rect.size.x = shadow_size;2194atlas_rect.size.y = shadow_size;21952196needs_clear = true;2197}21982199RenderDataGLES3 render_data;2200render_data.cam_projection = light_projection;2201render_data.cam_transform = light_transform;2202render_data.inv_cam_transform = light_transform.affine_inverse();2203render_data.z_far = zfar; // Only used by OmniLights.2204render_data.z_near = 0.0;2205render_data.lod_distance_multiplier = p_lod_distance_multiplier;2206render_data.main_cam_transform = p_main_cam_transform;22072208render_data.instances = &p_instances;2209render_data.render_info = p_render_info;22102211_setup_environment(&render_data, true, p_viewport_size, false, Color(), use_pancake, shadow_bias);22122213if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {2214render_data.screen_mesh_lod_threshold = 0.0;2215} else {2216render_data.screen_mesh_lod_threshold = p_screen_mesh_lod_threshold;2217}22182219_fill_render_list(RENDER_LIST_SECONDARY, &render_data, PASS_MODE_SHADOW);2220render_list[RENDER_LIST_SECONDARY].sort_by_key();22212222glBindFramebuffer(GL_FRAMEBUFFER, shadow_fb);2223glViewport(atlas_rect.position.x, atlas_rect.position.y, atlas_rect.size.x, atlas_rect.size.y);22242225GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_shader_parameters_get_uniform_buffer();22262227glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_GLOBALS_UNIFORM_LOCATION, global_buffer);2228glBindBuffer(GL_UNIFORM_BUFFER, 0);22292230scene_state.reset_gl_state();2231scene_state.enable_gl_depth_test(true);2232scene_state.enable_gl_depth_draw(true);2233scene_state.set_gl_depth_func(GL_GREATER);22342235glColorMask(0, 0, 0, 0);2236glDrawBuffers(0, nullptr);2237RasterizerGLES3::clear_depth(0.0);2238if (needs_clear) {2239glClear(GL_DEPTH_BUFFER_BIT);2240}22412242uint64_t spec_constant_base_flags = SceneShaderGLES3::DISABLE_LIGHTMAP |2243SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL |2244SceneShaderGLES3::DISABLE_LIGHT_OMNI |2245SceneShaderGLES3::DISABLE_LIGHT_SPOT |2246SceneShaderGLES3::DISABLE_FOG |2247SceneShaderGLES3::RENDER_SHADOWS;22482249if (light_storage->light_get_type(base) == RS::LIGHT_OMNI) {2250spec_constant_base_flags |= SceneShaderGLES3::RENDER_SHADOWS_LINEAR;2251}22522253RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), reverse_cull, spec_constant_base_flags, false);22542255_render_list_template<PASS_MODE_SHADOW>(&render_list_params, &render_data, 0, render_list[RENDER_LIST_SECONDARY].elements.size());22562257glColorMask(1, 1, 1, 1);2258scene_state.enable_gl_depth_test(false);2259scene_state.enable_gl_depth_draw(true);2260glDisable(GL_CULL_FACE);2261scene_state.cull_mode = RS::CULL_MODE_DISABLED;2262glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);2263}22642265void 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) {2266GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();2267GLES3::Config *config = GLES3::Config::get_singleton();2268RENDER_TIMESTAMP("Setup 3D Scene");22692270bool apply_color_adjustments_in_post = false;2271bool is_reflection_probe = p_reflection_probe.is_valid();22722273Ref<RenderSceneBuffersGLES3> rb = p_render_buffers;2274ERR_FAIL_COND(rb.is_null());22752276if (rb->get_scaling_3d_mode() != RS::VIEWPORT_SCALING_3D_MODE_OFF) {2277// If we're scaling, we apply tonemapping etc. in post, so disable it during rendering2278apply_color_adjustments_in_post = true;2279}22802281GLES3::RenderTarget *rt = nullptr; // No render target for reflection probe2282if (!is_reflection_probe) {2283rt = texture_storage->get_render_target(rb->render_target);2284ERR_FAIL_NULL(rt);2285}22862287bool glow_enabled = false;2288if (p_environment.is_valid()) {2289glow_enabled = environment_get_glow_enabled(p_environment);2290if (glow_enabled) {2291// If glow is enabled, we apply tonemapping etc. in post, so disable it during rendering2292apply_color_adjustments_in_post = true;2293}2294}22952296bool ssao_enabled = false;2297if (p_environment.is_valid()) {2298ssao_enabled = environment_get_ssao_enabled(p_environment);2299if (ssao_enabled) {2300// If SSAO is enabled, we apply tonemapping etc. in post, so disable it during rendering2301apply_color_adjustments_in_post = true;2302}2303}23042305// Assign render data2306// Use the format from rendererRD2307RenderDataGLES3 render_data;2308{2309render_data.render_buffers = rb;23102311if (rt) {2312render_data.transparent_bg = rt->is_transparent;2313render_data.render_region = rt->render_region;2314}23152316// Our first camera is used by default2317render_data.cam_transform = p_camera_data->main_transform;2318render_data.inv_cam_transform = render_data.cam_transform.affine_inverse();2319render_data.cam_projection = p_camera_data->main_projection;2320render_data.cam_orthogonal = p_camera_data->is_orthogonal;2321render_data.cam_frustum = p_camera_data->is_frustum;2322render_data.camera_visible_layers = p_camera_data->visible_layers;2323render_data.main_cam_transform = p_camera_data->main_transform;23242325render_data.view_count = p_camera_data->view_count;2326for (uint32_t v = 0; v < p_camera_data->view_count; v++) {2327render_data.view_eye_offset[v] = p_camera_data->view_offset[v].origin;2328render_data.view_projection[v] = p_camera_data->view_projection[v];2329}23302331render_data.z_near = p_camera_data->main_projection.get_z_near();2332render_data.z_far = p_camera_data->main_projection.get_z_far();23332334render_data.instances = &p_instances;2335render_data.lights = &p_lights;2336render_data.reflection_probes = &p_reflection_probes;2337render_data.environment = p_environment;2338render_data.camera_attributes = p_camera_attributes;2339render_data.shadow_atlas = p_shadow_atlas;2340render_data.reflection_probe = p_reflection_probe;2341render_data.reflection_probe_pass = p_reflection_probe_pass;23422343// this should be the same for all cameras..2344render_data.lod_distance_multiplier = p_camera_data->main_projection.get_lod_multiplier();23452346if (rt != nullptr && rt->color_type == GL_UNSIGNED_INT_2_10_10_10_REV && glow_enabled) {2347// As our output is in sRGB and we're using 10bit color space, we can fake a little HDR to do glow...2348render_data.luminance_multiplier = 0.25;2349} else {2350render_data.luminance_multiplier = 1.0;2351}23522353if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {2354render_data.screen_mesh_lod_threshold = 0.0;2355} else {2356render_data.screen_mesh_lod_threshold = p_screen_mesh_lod_threshold;2357}2358render_data.render_info = r_render_info;2359render_data.render_shadows = p_render_shadows;2360render_data.render_shadow_count = p_render_shadow_count;2361}23622363PagedArray<RID> empty;23642365if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {2366render_data.lights = ∅2367render_data.reflection_probes = ∅2368}23692370bool reverse_cull = render_data.cam_transform.basis.determinant() < 0;23712372///////////2373// Fill Light lists here2374//////////23752376GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_shader_parameters_get_uniform_buffer();2377glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_GLOBALS_UNIFORM_LOCATION, global_buffer);23782379Color clear_color;2380if (!is_reflection_probe && rb->render_target.is_valid()) {2381clear_color = texture_storage->render_target_get_clear_request_color(rb->render_target);2382} else {2383clear_color = texture_storage->get_default_clear_color();2384}23852386bool fb_cleared = false;23872388Size2i screen_size = rb->internal_size;23892390bool use_wireframe = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME;23912392SceneState::TonemapUBO tonemap_ubo;2393if (render_data.environment.is_valid()) {2394bool use_bcs = environment_get_adjustments_enabled(render_data.environment);2395if (use_bcs) {2396apply_color_adjustments_in_post = true;2397}23982399tonemap_ubo.exposure = environment_get_exposure(render_data.environment);2400tonemap_ubo.tonemapper = int32_t(environment_get_tone_mapper(render_data.environment));2401RendererEnvironmentStorage::TonemapParameters params = environment_get_tonemap_parameters(render_data.environment, false);2402tonemap_ubo.tonemapper_params[0] = params.tonemapper_params[0];2403tonemap_ubo.tonemapper_params[1] = params.tonemapper_params[1];2404tonemap_ubo.tonemapper_params[2] = params.tonemapper_params[2];2405tonemap_ubo.tonemapper_params[3] = params.tonemapper_params[3];2406tonemap_ubo.brightness = environment_get_adjustments_brightness(render_data.environment);2407tonemap_ubo.contrast = environment_get_adjustments_contrast(render_data.environment);2408tonemap_ubo.saturation = environment_get_adjustments_saturation(render_data.environment);2409}24102411if (scene_state.tonemap_buffer == 0) {2412// Only create if using 3D2413glGenBuffers(1, &scene_state.tonemap_buffer);2414glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_TONEMAP_UNIFORM_LOCATION, scene_state.tonemap_buffer);2415GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.tonemap_buffer, sizeof(SceneState::TonemapUBO), &tonemap_ubo, GL_STREAM_DRAW, "Tonemap UBO");2416} else {2417glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_TONEMAP_UNIFORM_LOCATION, scene_state.tonemap_buffer);2418glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::TonemapUBO), &tonemap_ubo, GL_STREAM_DRAW);2419}24202421glBindBuffer(GL_UNIFORM_BUFFER, 0);24222423scene_state.data.emissive_exposure_normalization = -1.0; // Use default exposure normalization.24242425bool enough_vertex_attribs_for_motion_vectors = GLES3::Config::get_singleton()->max_vertex_attribs >= 22;2426if (rt && rt->overridden.velocity_fbo != 0 && enough_vertex_attribs_for_motion_vectors) {2427// First frame we render motion vectors? Use our current data!2428if (scene_state.prev_data_state == 0) {2429scene_state.prev_data_state = 1;2430}2431} else {2432// Not using motion vectors? We don't need to load our data.2433scene_state.prev_data_state = 0;2434}24352436bool flip_y = !is_reflection_probe;24372438if (rt && rt->overridden.color.is_valid()) {2439// If we've overridden the render target's color texture, then don't render upside down.2440// We're probably rendering directly to an XR device.2441flip_y = false;2442}2443if (!flip_y) {2444// If we're rendering right-side up, then we need to change the winding order.2445glFrontFace(GL_CW);2446}2447_render_shadows(&render_data, screen_size);24482449_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);2450_setup_environment(&render_data, is_reflection_probe, screen_size, flip_y, clear_color, false);24512452_fill_render_list(RENDER_LIST_OPAQUE, &render_data, PASS_MODE_COLOR);2453render_list[RENDER_LIST_OPAQUE].sort_by_key();2454render_list[RENDER_LIST_ALPHA].sort_by_reverse_depth_and_priority();24552456bool draw_sky = false;2457bool draw_sky_fog_only = false;2458bool keep_color = false;2459bool draw_canvas = false;2460bool draw_feed = false;2461float sky_energy_multiplier = 1.0;2462int camera_feed_id = -1;24632464if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW)) {2465clear_color = Color(0, 0, 0, 1); //in overdraw mode, BG should always be black2466} else if (render_data.environment.is_valid()) {2467RS::EnvironmentBG bg_mode = environment_get_background(render_data.environment);2468float bg_energy_multiplier = environment_get_bg_energy_multiplier(render_data.environment);2469bg_energy_multiplier *= environment_get_bg_intensity(render_data.environment);2470RS::EnvironmentReflectionSource reflection_source = environment_get_reflection_source(render_data.environment);2471RS::EnvironmentAmbientSource ambient_source = environment_get_ambient_source(render_data.environment);24722473if (render_data.camera_attributes.is_valid()) {2474bg_energy_multiplier *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(render_data.camera_attributes);2475}24762477switch (bg_mode) {2478case RS::ENV_BG_CLEAR_COLOR: {2479clear_color.r *= bg_energy_multiplier;2480clear_color.g *= bg_energy_multiplier;2481clear_color.b *= bg_energy_multiplier;2482if (!render_data.transparent_bg && environment_get_fog_enabled(render_data.environment)) {2483draw_sky_fog_only = true;2484GLES3::MaterialStorage::get_singleton()->material_set_param(sky_globals.fog_material, "clear_color", Variant(clear_color));2485}2486} break;2487case RS::ENV_BG_COLOR: {2488clear_color = environment_get_bg_color(render_data.environment);2489clear_color.r *= bg_energy_multiplier;2490clear_color.g *= bg_energy_multiplier;2491clear_color.b *= bg_energy_multiplier;2492if (!render_data.transparent_bg && environment_get_fog_enabled(render_data.environment)) {2493draw_sky_fog_only = true;2494GLES3::MaterialStorage::get_singleton()->material_set_param(sky_globals.fog_material, "clear_color", Variant(clear_color));2495}2496} break;2497case RS::ENV_BG_SKY: {2498draw_sky = !render_data.transparent_bg;2499} break;2500case RS::ENV_BG_CANVAS: {2501draw_canvas = true;2502} break;2503case RS::ENV_BG_KEEP: {2504keep_color = true;2505} break;2506case RS::ENV_BG_CAMERA_FEED: {2507camera_feed_id = environment_get_camera_feed_id(render_data.environment);2508draw_feed = true;2509keep_color = true;2510} break;2511default: {2512}2513}25142515bool sky_reflections = reflection_source == RS::ENV_REFLECTION_SOURCE_SKY;2516sky_reflections |= reflection_source == RS::ENV_REFLECTION_SOURCE_BG && bg_mode == RS::ENV_BG_SKY;2517bool sky_ambient = ambient_source == RS::ENV_AMBIENT_SOURCE_SKY;2518sky_ambient |= ambient_source == RS::ENV_AMBIENT_SOURCE_BG && bg_mode == RS::ENV_BG_SKY;25192520// setup sky if used for ambient, reflections, or background2521if (draw_sky || draw_sky_fog_only || sky_reflections || sky_ambient) {2522RENDER_TIMESTAMP("Setup Sky");2523Projection projection = render_data.cam_projection;2524if (is_reflection_probe) {2525Projection correction;2526correction.set_depth_correction(true, true, false);2527projection = correction * render_data.cam_projection;2528}25292530sky_energy_multiplier *= bg_energy_multiplier;25312532_setup_sky(&render_data, *render_data.lights, projection, render_data.cam_transform, screen_size);25332534if (environment_get_sky(render_data.environment).is_valid()) {2535if (sky_reflections || sky_ambient) {2536_update_sky_radiance(render_data.environment, projection, render_data.cam_transform, sky_energy_multiplier);2537}2538} else {2539// do not try to draw sky if invalid2540draw_sky = false;2541}2542}2543}25442545scene_state.reset_gl_state();25462547GLuint motion_vectors_fbo = rt ? rt->overridden.velocity_fbo : 0;2548if (motion_vectors_fbo != 0 && enough_vertex_attribs_for_motion_vectors) {2549RENDER_TIMESTAMP("Motion Vectors Pass");2550glBindFramebuffer(GL_FRAMEBUFFER, motion_vectors_fbo);25512552Size2i motion_vectors_target_size = rt->velocity_target_size;2553glViewport(0, 0, motion_vectors_target_size.x, motion_vectors_target_size.y);25542555scene_state.enable_gl_depth_test(true);2556scene_state.enable_gl_depth_draw(true);2557scene_state.enable_gl_blend(false);2558glDepthFunc(GL_GEQUAL);2559scene_state.enable_gl_scissor_test(false);25602561glColorMask(1, 1, 1, 1);2562RasterizerGLES3::clear_depth(0.0);2563glClearColor(0.0, 0.0, 0.0, 0.0);2564glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);2565GLuint db = GL_COLOR_ATTACHMENT0;2566glDrawBuffers(1, &db);25672568uint64_t spec_constant = SceneShaderGLES3::DISABLE_FOG | SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL |2569SceneShaderGLES3::DISABLE_LIGHTMAP | SceneShaderGLES3::DISABLE_LIGHT_OMNI |2570SceneShaderGLES3::DISABLE_LIGHT_SPOT;25712572RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, spec_constant, use_wireframe);2573_render_list_template<PASS_MODE_MOTION_VECTORS>(&render_list_params, &render_data, 0, render_list[RENDER_LIST_OPAQUE].elements.size());25742575// Copy our current scene data to our previous scene data for use in the next frame.2576scene_state.prev_data = scene_state.data;2577scene_state.prev_multiview_data = scene_state.multiview_data;2578scene_state.prev_data_state = 2;2579}25802581GLuint fbo = 0;2582if (is_reflection_probe && GLES3::LightStorage::get_singleton()->reflection_probe_has_atlas_index(render_data.reflection_probe)) {2583fbo = GLES3::LightStorage::get_singleton()->reflection_probe_instance_get_framebuffer(render_data.reflection_probe, render_data.reflection_probe_pass);2584} else {2585rb->set_apply_color_adjustments_in_post(apply_color_adjustments_in_post);2586fbo = rb->get_render_fbo();2587}25882589glBindFramebuffer(GL_FRAMEBUFFER, fbo);2590glViewport(0, 0, rb->internal_size.x, rb->internal_size.y);25912592// If SSAO is enabled, we definitely need the depth buffer.2593if (ssao_enabled) {2594scene_state.used_depth_texture = true;2595}25962597// Do depth prepass if it's explicitly enabled2598bool use_depth_prepass = config->use_depth_prepass;25992600// Forcibly enable depth prepass if opaque stencil writes are used.2601use_depth_prepass = use_depth_prepass || scene_state.used_opaque_stencil;26022603// Don't do depth prepass we are rendering overdraw2604use_depth_prepass = use_depth_prepass && get_debug_draw_mode() != RS::VIEWPORT_DEBUG_DRAW_OVERDRAW;26052606if (use_depth_prepass) {2607RENDER_TIMESTAMP("Depth Prepass");2608//pre z pass26092610if (render_data.render_region != Rect2i()) {2611glViewport(render_data.render_region.position.x, render_data.render_region.position.y, render_data.render_region.size.width, render_data.render_region.size.height);2612}26132614scene_state.enable_gl_depth_test(true);2615scene_state.enable_gl_depth_draw(true);2616scene_state.enable_gl_blend(false);2617scene_state.set_gl_depth_func(GL_GEQUAL);2618scene_state.enable_gl_scissor_test(false);2619scene_state.enable_gl_stencil_test(false);26202621glColorMask(0, 0, 0, 0);2622RasterizerGLES3::clear_depth(0.0);2623RasterizerGLES3::clear_stencil(0);2624glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);2625// Some desktop GL implementations fall apart when using Multiview with GL_NONE.2626GLuint db = p_camera_data->view_count > 1 ? GL_COLOR_ATTACHMENT0 : GL_NONE;2627glDrawBuffers(1, &db);26282629uint64_t spec_constant = SceneShaderGLES3::DISABLE_FOG | SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL |2630SceneShaderGLES3::DISABLE_LIGHTMAP | SceneShaderGLES3::DISABLE_LIGHT_OMNI |2631SceneShaderGLES3::DISABLE_LIGHT_SPOT;26322633RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, spec_constant, use_wireframe);2634_render_list_template<PASS_MODE_DEPTH>(&render_list_params, &render_data, 0, render_list[RENDER_LIST_OPAQUE].elements.size());26352636glColorMask(1, 1, 1, 1);26372638fb_cleared = true;2639scene_state.used_depth_prepass = true;2640} else {2641scene_state.used_depth_prepass = false;2642}26432644glBlendEquation(GL_FUNC_ADD);2645if (render_data.transparent_bg) {2646glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);2647scene_state.enable_gl_blend(true);2648} else {2649glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);2650scene_state.enable_gl_blend(false);2651}2652scene_state.current_blend_mode = GLES3::SceneShaderData::BLEND_MODE_MIX;26532654scene_state.enable_gl_scissor_test(false);2655scene_state.enable_gl_depth_test(true);2656scene_state.enable_gl_depth_draw(true);2657scene_state.set_gl_depth_func(GL_GEQUAL);26582659{2660GLuint db = GL_COLOR_ATTACHMENT0;2661glDrawBuffers(1, &db);2662}26632664scene_state.enable_gl_stencil_test(false);26652666if (!fb_cleared) {2667RasterizerGLES3::clear_depth(0.0);2668RasterizerGLES3::clear_stencil(0);2669glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);2670}26712672// Need to clear framebuffer unless:2673// a) We explicitly request not to (i.e. ENV_BG_KEEP).2674// b) We are rendering to a non-intermediate framebuffer with ENV_BG_CANVAS (shared between 2D and 3D).2675if (!keep_color && (!draw_canvas || fbo != rt->fbo)) {2676clear_color.a = render_data.transparent_bg ? 0.0f : 1.0f;2677glClearBufferfv(GL_COLOR, 0, clear_color.components);2678}2679if ((keep_color || draw_canvas) && fbo != rt->fbo) {2680// Need to copy our current contents to our intermediate/MSAA buffer2681GLES3::CopyEffects *copy_effects = GLES3::CopyEffects::get_singleton();26822683scene_state.enable_gl_depth_test(false);2684scene_state.enable_gl_depth_draw(false);26852686glActiveTexture(GL_TEXTURE0);2687glBindTexture(rt->view_count > 1 ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D, rt->color);26882689copy_effects->copy_screen(render_data.luminance_multiplier);26902691scene_state.enable_gl_depth_test(true);2692scene_state.enable_gl_depth_draw(true);2693}26942695RENDER_TIMESTAMP("Render Opaque Pass");2696uint64_t spec_constant_base_flags = 0;26972698if (render_data.render_region != Rect2i()) {2699glViewport(render_data.render_region.position.x, render_data.render_region.position.y, render_data.render_region.size.width, render_data.render_region.size.height);2700}27012702{2703// Specialization Constants that apply for entire rendering pass.2704if (render_data.directional_light_count == 0) {2705spec_constant_base_flags |= SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL;2706}27072708if (render_data.environment.is_null() || (render_data.environment.is_valid() && !environment_get_fog_enabled(render_data.environment))) {2709spec_constant_base_flags |= SceneShaderGLES3::DISABLE_FOG;2710}27112712if (render_data.environment.is_valid() && environment_get_fog_mode(render_data.environment) == RS::EnvironmentFogMode::ENV_FOG_MODE_DEPTH) {2713spec_constant_base_flags |= SceneShaderGLES3::USE_DEPTH_FOG;2714}27152716if (!apply_color_adjustments_in_post) {2717spec_constant_base_flags |= SceneShaderGLES3::APPLY_TONEMAPPING;2718}2719}27202721if (draw_feed && camera_feed_id > -1) {2722RENDER_TIMESTAMP("Render Camera feed");27232724scene_state.enable_gl_depth_draw(false);2725scene_state.enable_gl_depth_test(false);2726scene_state.enable_gl_blend(false);2727scene_state.set_gl_cull_mode(RS::CULL_MODE_BACK);27282729Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);27302731if (feed.is_valid()) {2732RID camera_YCBCR = feed->get_texture(CameraServer::FEED_YCBCR_IMAGE);2733GLES3::TextureStorage::get_singleton()->texture_bind(camera_YCBCR, 0);27342735GLES3::FeedEffects *feed_effects = GLES3::FeedEffects::get_singleton();2736feed_effects->draw();2737}2738scene_state.enable_gl_depth_draw(true);2739scene_state.enable_gl_depth_test(true);2740scene_state.enable_gl_blend(true);2741}27422743// Render Opaque Objects.2744RenderListParameters 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);27452746_render_list_template<PASS_MODE_COLOR>(&render_list_params, &render_data, 0, render_list[RENDER_LIST_OPAQUE].elements.size());27472748scene_state.enable_gl_depth_draw(false);2749scene_state.enable_gl_stencil_test(false);27502751if (draw_sky || draw_sky_fog_only) {2752RENDER_TIMESTAMP("Render Sky");27532754scene_state.enable_gl_depth_test(true);2755scene_state.set_gl_depth_func(GL_GEQUAL);2756scene_state.enable_gl_blend(false);2757scene_state.set_gl_cull_mode(RS::CULL_MODE_BACK);27582759Transform3D transform = render_data.cam_transform;2760Projection projection = render_data.cam_projection;2761if (is_reflection_probe) {2762Projection correction;2763correction.columns[1][1] = -1.0;2764projection = correction * render_data.cam_projection;2765} else if (render_data.cam_frustum) {2766// Sky is drawn upside down, the frustum offset doesn't know the image is upside down so needs a flip.2767projection[2].y = -projection[2].y;2768}27692770_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);2771}27722773if (scene_state.used_screen_texture || scene_state.used_depth_texture) {2774rb->check_backbuffer(scene_state.used_screen_texture, scene_state.used_depth_texture);2775Size2i size = rb->get_internal_size();2776GLuint backbuffer_fbo = rb->get_backbuffer_fbo();2777GLuint backbuffer = rb->get_backbuffer();2778GLuint backbuffer_depth = rb->get_backbuffer_depth();27792780if (backbuffer_fbo != 0) {2781glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);2782glReadBuffer(GL_COLOR_ATTACHMENT0);2783glBindFramebuffer(GL_DRAW_FRAMEBUFFER, backbuffer_fbo);2784if (scene_state.used_screen_texture) {2785glBlitFramebuffer(0, 0, size.x, size.y,27860, 0, size.x, size.y,2787GL_COLOR_BUFFER_BIT, GL_NEAREST);2788glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 6);2789glBindTexture(GL_TEXTURE_2D, backbuffer);2790}2791if (scene_state.used_depth_texture) {2792glBlitFramebuffer(0, 0, size.x, size.y,27930, 0, size.x, size.y,2794GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);2795glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 7);2796glBindTexture(GL_TEXTURE_2D, backbuffer_depth);2797}2798}27992800// Bound framebuffer may have changed, so change it back2801glBindFramebuffer(GL_FRAMEBUFFER, fbo);2802}28032804RENDER_TIMESTAMP("Render 3D Transparent Pass");2805scene_state.enable_gl_blend(true);28062807//Render transparent pass2808RenderListParameters 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);28092810_render_list_template<PASS_MODE_COLOR_TRANSPARENT>(&render_list_params_alpha, &render_data, 0, render_list[RENDER_LIST_ALPHA].elements.size(), true);28112812scene_state.enable_gl_stencil_test(false);28132814if (!flip_y) {2815// Restore the default winding order.2816glFrontFace(GL_CCW);2817}28182819if (!is_reflection_probe && rb.is_valid()) {2820_render_buffers_debug_draw(rb, p_shadow_atlas, fbo);2821}28222823// Reset stuff that may trip up the next process.2824scene_state.reset_gl_state();2825glUseProgram(0);28262827if (!is_reflection_probe) {2828_render_post_processing(&render_data);28292830texture_storage->render_target_disable_clear_request(rb->render_target);2831}28322833glActiveTexture(GL_TEXTURE0);2834}28352836void RasterizerSceneGLES3::_render_post_processing(const RenderDataGLES3 *p_render_data) {2837GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();2838GLES3::Glow *glow = GLES3::Glow::get_singleton();2839GLES3::PostEffects *post_effects = GLES3::PostEffects::get_singleton();28402841Ref<RenderSceneBuffersGLES3> rb = p_render_data->render_buffers;2842ERR_FAIL_COND(rb.is_null());28432844RID render_target = rb->get_render_target();2845Size2i internal_size = rb->get_internal_size();2846Size2i target_size = rb->get_target_size();2847uint32_t view_count = rb->get_view_count();28482849// bool msaa2d_needs_resolve = texture_storage->render_target_get_msaa(render_target) != RS::VIEWPORT_MSAA_DISABLED && !GLES3::Config::get_singleton()->rt_msaa_supported;2850bool msaa3d_needs_resolve = rb->get_msaa_needs_resolve();2851GLuint fbo_msaa_3d = rb->get_msaa3d_fbo();2852GLuint fbo_int = rb->get_internal_fbo();2853GLuint 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.28542855// Check if we have glow enabled and if so, check if our buffers were allocated2856bool glow_enabled = false;2857float glow_intensity = 1.0;2858float glow_bloom = 0.0;2859float glow_hdr_bleed_threshold = 1.0;2860float glow_hdr_bleed_scale = 2.0;2861float glow_hdr_luminance_cap = 12.0;2862float srgb_white = 1.0;2863if (p_render_data->environment.is_valid()) {2864glow_enabled = environment_get_glow_enabled(p_render_data->environment);2865glow_intensity = environment_get_glow_intensity(p_render_data->environment);2866glow_bloom = environment_get_glow_bloom(p_render_data->environment);2867glow_hdr_bleed_threshold = environment_get_glow_hdr_bleed_threshold(p_render_data->environment);2868glow_hdr_bleed_scale = environment_get_glow_hdr_bleed_scale(p_render_data->environment);2869glow_hdr_luminance_cap = environment_get_glow_hdr_luminance_cap(p_render_data->environment);2870srgb_white = environment_get_white(p_render_data->environment, false);2871}28722873if (glow_enabled) {2874// Only glow requires srgb_white to be calculated.2875srgb_white = 1.055 * Math::pow(srgb_white, 1.0f / 2.4f) - 0.055;28762877rb->check_glow_buffers();2878}28792880// Check if we want and can have SSAO.2881bool ssao_enabled = false;2882float ssao_strength = 4.0;2883float ssao_radius = 0.5;2884if (p_render_data->environment.is_valid()) {2885ssao_enabled = environment_get_ssao_enabled(p_render_data->environment);2886// This SSAO is not implemented the same way, but uses the intensity and radius2887// in a similar way. The parameters are scaled so the SSAO defaults look ok.2888ssao_strength = environment_get_ssao_intensity(p_render_data->environment) * 2.0;2889ssao_radius = environment_get_ssao_radius(p_render_data->environment) * 0.5;2890}28912892uint64_t bcs_spec_constants = 0;2893if (p_render_data->environment.is_valid()) {2894bool use_bcs = environment_get_adjustments_enabled(p_render_data->environment);2895RID color_correction_texture = environment_get_color_correction(p_render_data->environment);2896if (use_bcs) {2897bcs_spec_constants |= PostShaderGLES3::USE_BCS;28982899if (color_correction_texture.is_valid()) {2900bcs_spec_constants |= PostShaderGLES3::USE_COLOR_CORRECTION;29012902bool use_1d_lut = environment_get_use_1d_color_correction(p_render_data->environment);2903GLenum texture_target = GL_TEXTURE_3D;2904if (use_1d_lut) {2905bcs_spec_constants |= PostShaderGLES3::USE_1D_LUT;2906texture_target = GL_TEXTURE_2D;2907}29082909glActiveTexture(GL_TEXTURE2);2910glBindTexture(texture_target, texture_storage->texture_get_texid(color_correction_texture));2911glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);2912glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);2913glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);2914glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);2915glTexParameteri(texture_target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);2916}2917}2918}29192920if (view_count == 1) {2921// Resolve if needed.2922if (fbo_msaa_3d != 0 && msaa3d_needs_resolve) {2923// We can use blit to copy things over2924glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_msaa_3d);29252926if (fbo_int != 0) {2927// We can't combine resolve and scaling, so resolve into our internal buffer2928glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_int);2929} else {2930glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_rt);2931}2932glBlitFramebuffer(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);2933}29342935// Rendered to intermediate buffer, must copy to our render target2936if (fbo_int != 0) {2937// Apply glow/bloom if requested? then populate our glow buffers2938GLuint color = fbo_int != 0 ? rb->get_internal_color() : texture_storage->render_target_get_color(render_target);29392940// We need to pass this in for SSAO.2941GLuint depth_buffer = fbo_int != 0 ? rb->get_internal_depth() : texture_storage->render_target_get_depth(render_target);29422943const GLES3::Glow::GLOWLEVEL *glow_buffers = nullptr;2944if (glow_enabled) {2945glow_buffers = rb->get_glow_buffers();29462947glow->set_luminance_multiplier(p_render_data->luminance_multiplier);29482949glow->set_intensity(glow_intensity);2950glow->set_glow_bloom(glow_bloom);2951glow->set_glow_hdr_bleed_threshold(glow_hdr_bleed_threshold);2952glow->set_glow_hdr_bleed_scale(glow_hdr_bleed_scale);2953glow->set_glow_hdr_luminance_cap(glow_hdr_luminance_cap);29542955glow->process_glow(color, internal_size, glow_buffers);2956}29572958// Copy color buffer2959post_effects->post_copy(fbo_rt, target_size, color,2960depth_buffer, ssao_enabled, ssao_quality, ssao_strength, ssao_radius,2961internal_size, p_render_data->luminance_multiplier, glow_buffers, glow_intensity,2962srgb_white, 0, false, bcs_spec_constants);29632964// Copy depth buffer2965glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_int);2966glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_rt);2967glBlitFramebuffer(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);2968}29692970glBindFramebuffer(GL_FRAMEBUFFER, fbo_rt);2971} else if ((fbo_msaa_3d != 0 && msaa3d_needs_resolve) || (fbo_int != 0)) {2972// TODO investigate if it's smarter to cache these FBOs2973GLuint fbos[3]; // read, write and post2974glGenFramebuffers(3, fbos);29752976// Resolve if needed.2977if (fbo_msaa_3d != 0 && msaa3d_needs_resolve) {2978GLuint read_color = rb->get_msaa3d_color();2979GLuint read_depth = rb->get_msaa3d_depth();2980GLuint write_color = 0;2981GLuint write_depth = 0;29822983if (fbo_int != 0) {2984write_color = rb->get_internal_color();2985write_depth = rb->get_internal_depth();2986} else {2987write_color = texture_storage->render_target_get_color(render_target);2988write_depth = texture_storage->render_target_get_depth(render_target);2989}29902991glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[0]);2992glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]);29932994for (uint32_t v = 0; v < view_count; v++) {2995glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, read_color, 0, v);2996glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, read_depth, 0, v);2997glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, write_color, 0, v);2998glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, write_depth, 0, v);2999glBlitFramebuffer(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);3000}3001}30023003// Rendered to intermediate buffer, must copy to our render target3004if (fbo_int != 0) {3005// Apply glow/bloom if requested? then populate our glow buffers3006const GLES3::Glow::GLOWLEVEL *glow_buffers = nullptr;3007GLuint source_color = fbo_int != 0 ? rb->get_internal_color() : texture_storage->render_target_get_color(render_target);30083009// Moved this up so SSAO could use it too.3010GLuint read_depth = rb->get_internal_depth();30113012if (glow_enabled) {3013glow_buffers = rb->get_glow_buffers();30143015glow->set_luminance_multiplier(p_render_data->luminance_multiplier);30163017glow->set_intensity(glow_intensity);3018glow->set_glow_bloom(glow_bloom);3019glow->set_glow_hdr_bleed_threshold(glow_hdr_bleed_threshold);3020glow->set_glow_hdr_bleed_scale(glow_hdr_bleed_scale);3021glow->set_glow_hdr_luminance_cap(glow_hdr_luminance_cap);3022}30233024GLuint write_color = texture_storage->render_target_get_color(render_target);30253026for (uint32_t v = 0; v < view_count; v++) {3027if (glow_enabled) {3028glow->process_glow(source_color, internal_size, glow_buffers, v, true);3029}30303031glBindFramebuffer(GL_FRAMEBUFFER, fbos[2]);3032glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, write_color, 0, v);3033post_effects->post_copy(fbos[2], target_size, source_color,3034read_depth, ssao_enabled, ssao_quality, ssao_strength, ssao_radius,3035internal_size, p_render_data->luminance_multiplier, glow_buffers, glow_intensity,3036srgb_white, v, true, bcs_spec_constants);3037}30383039// Copy depth3040GLuint write_depth = texture_storage->render_target_get_depth(render_target);30413042glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[0]);3043glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]);30443045for (uint32_t v = 0; v < view_count; v++) {3046glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, read_depth, 0, v);3047glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, write_depth, 0, v);30483049glBlitFramebuffer(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);3050}3051}30523053glBindFramebuffer(GL_FRAMEBUFFER, fbo_rt);3054glDeleteFramebuffers(3, fbos);3055}30563057glActiveTexture(GL_TEXTURE2);3058glBindTexture(GL_TEXTURE_2D, 0);3059}30603061template <PassMode p_pass_mode>3062void 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) {3063GLES3::MeshStorage *mesh_storage = GLES3::MeshStorage::get_singleton();3064GLES3::ParticlesStorage *particles_storage = GLES3::ParticlesStorage::get_singleton();3065GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();30663067GLuint prev_vertex_array_gl = 0;3068GLuint prev_index_array_gl = 0;30693070GLES3::SceneMaterialData *prev_material_data = nullptr;3071GLES3::SceneShaderData *prev_shader = nullptr;3072GeometryInstanceGLES3 *prev_inst = nullptr;3073SceneShaderGLES3::ShaderVariant prev_variant = SceneShaderGLES3::ShaderVariant::MODE_COLOR;3074SceneShaderGLES3::ShaderVariant shader_variant = SceneShaderGLES3::MODE_COLOR; // Assigned to silence wrong -Wmaybe-initialized3075uint64_t prev_spec_constants = 0;30763077// Specializations constants used by all instances in the scene.3078uint64_t base_spec_constants = p_params->spec_constant_base_flags;30793080if constexpr (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) {3081GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();3082GLES3::Config *config = GLES3::Config::get_singleton();3083glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 2);3084GLuint texture_to_bind = texture_storage->get_texture(texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_CUBEMAP_BLACK))->tex_id;3085if (p_render_data->environment.is_valid()) {3086Sky *sky = sky_owner.get_or_null(environment_get_sky(p_render_data->environment));3087if (sky && sky->radiance != 0) {3088texture_to_bind = sky->radiance;3089base_spec_constants |= SceneShaderGLES3::USE_RADIANCE_MAP;3090}3091glBindTexture(GL_TEXTURE_CUBE_MAP, texture_to_bind);3092}30933094} else if constexpr (p_pass_mode == PASS_MODE_DEPTH || p_pass_mode == PASS_MODE_SHADOW) {3095shader_variant = SceneShaderGLES3::MODE_DEPTH;3096} else if constexpr (p_pass_mode == PASS_MODE_MOTION_VECTORS) {3097base_spec_constants |= SceneShaderGLES3::RENDER_MOTION_VECTORS;3098}30993100if (p_render_data->view_count > 1) {3101base_spec_constants |= SceneShaderGLES3::USE_MULTIVIEW;3102}31033104bool should_request_redraw = false;3105if constexpr (p_pass_mode != PASS_MODE_DEPTH && p_pass_mode != PASS_MODE_MOTION_VECTORS) {3106// Don't count elements during depth pre-pass or motion vector pass to match the RD renderers.3107if (p_render_data->render_info) {3108p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] += p_to_element - p_from_element;3109}3110}31113112for (uint32_t i = p_from_element; i < p_to_element; i++) {3113GeometryInstanceSurface *surf = p_params->elements[i];3114GeometryInstanceGLES3 *inst = surf->owner;31153116if (p_pass_mode == PASS_MODE_COLOR && !(surf->flags & GeometryInstanceSurface::FLAG_PASS_OPAQUE)) {3117continue; // Objects with "Depth-prepass" transparency are included in both render lists, but should only be rendered in the transparent pass3118}31193120if (inst->instance_count == 0) {3121continue;3122}31233124GLES3::SceneShaderData *shader;3125GLES3::SceneMaterialData *material_data;3126void *mesh_surface;31273128if constexpr (p_pass_mode == PASS_MODE_SHADOW) {3129shader = surf->shader_shadow;3130material_data = surf->material_shadow;3131mesh_surface = surf->surface_shadow;3132} else {3133if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW)) {3134material_data = overdraw_material_data_ptr;3135shader = material_data->shader_data;3136} else if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING)) {3137material_data = default_material_data_ptr;3138shader = material_data->shader_data;3139} else {3140shader = surf->shader;3141material_data = surf->material;3142}3143mesh_surface = surf->surface;3144}31453146if (!mesh_surface) {3147continue;3148}31493150//request a redraw if one of the shaders uses TIME3151if (shader->uses_time) {3152should_request_redraw = true;3153}31543155if constexpr (p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) {3156scene_state.enable_gl_depth_test(shader->depth_test != GLES3::SceneShaderData::DEPTH_TEST_DISABLED);3157}31583159if (shader->depth_test == GLES3::SceneShaderData::DEPTH_TEST_ENABLED_INVERTED) {3160scene_state.set_gl_depth_func(GL_LESS);3161} else {3162scene_state.set_gl_depth_func(GL_GEQUAL);3163}31643165if constexpr (p_pass_mode != PASS_MODE_SHADOW) {3166if (shader->depth_draw == GLES3::SceneShaderData::DEPTH_DRAW_OPAQUE) {3167scene_state.enable_gl_depth_draw((p_pass_mode == PASS_MODE_COLOR && !GLES3::Config::get_singleton()->use_depth_prepass) || p_pass_mode == PASS_MODE_DEPTH || p_pass_mode == PASS_MODE_MOTION_VECTORS);3168} else {3169scene_state.enable_gl_depth_draw(shader->depth_draw == GLES3::SceneShaderData::DEPTH_DRAW_ALWAYS);3170}3171}31723173bool uses_additive_lighting = (inst->light_passes.size() + p_render_data->directional_shadow_count) > 0;3174uses_additive_lighting = uses_additive_lighting && !shader->unshaded;31753176// TODOS3177/*3178* 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 enough3179* Disable depth draw3180*/31813182for (int32_t pass = 0; pass < MAX(1, int32_t(inst->light_passes.size() + p_render_data->directional_shadow_count)); pass++) {3183if constexpr (p_pass_mode == PASS_MODE_DEPTH || p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_MOTION_VECTORS) {3184if (pass > 0) {3185// Don't render shadow passes when doing depth, shadow, or motion vector pass.3186break;3187}3188}31893190// Stencil.3191if (p_pass_mode != PASS_MODE_DEPTH && shader->stencil_enabled) {3192static const GLenum stencil_compare_table[GLES3::SceneShaderData::STENCIL_COMPARE_MAX] = {3193GL_LESS,3194GL_EQUAL,3195GL_LEQUAL,3196GL_GREATER,3197GL_NOTEQUAL,3198GL_GEQUAL,3199GL_ALWAYS,3200};32013202GLenum stencil_compare = stencil_compare_table[shader->stencil_compare];3203GLuint stencil_compare_mask = 0;3204GLuint stencil_write_mask = 0;3205GLenum stencil_op_dpfail = GL_KEEP;3206GLenum stencil_op_dppass = GL_KEEP;32073208if (shader->stencil_flags & GLES3::SceneShaderData::STENCIL_FLAG_READ) {3209stencil_compare_mask = 255;3210}32113212if (shader->stencil_flags & GLES3::SceneShaderData::STENCIL_FLAG_WRITE) {3213stencil_op_dppass = GL_REPLACE;3214stencil_write_mask = 255;3215}32163217if (shader->stencil_flags & GLES3::SceneShaderData::STENCIL_FLAG_WRITE_DEPTH_FAIL) {3218stencil_op_dpfail = GL_REPLACE;3219stencil_write_mask = 255;3220}32213222scene_state.enable_gl_stencil_test(true);3223scene_state.set_gl_stencil_func(stencil_compare, shader->stencil_reference, stencil_compare_mask);3224scene_state.set_gl_stencil_write_mask(stencil_write_mask);3225scene_state.set_gl_stencil_op(GL_KEEP, stencil_op_dpfail, stencil_op_dppass);3226} else {3227scene_state.enable_gl_stencil_test(false);3228}32293230if constexpr (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) {3231if (!uses_additive_lighting && pass == 1) {3232// Don't render additive passes if not using additive lighting.3233break;3234}3235if (uses_additive_lighting && pass == 1 && !p_render_data->transparent_bg) {3236// Enable blending if in opaque pass and not already enabled.3237scene_state.enable_gl_blend(true);3238}3239if (pass < int32_t(inst->light_passes.size())) {3240RID light_instance_rid = inst->light_passes[pass].light_instance_rid;3241if (!GLES3::LightStorage::get_singleton()->light_instance_has_shadow_atlas(light_instance_rid, p_render_data->shadow_atlas)) {3242// Shadow wasn't able to get a spot on the atlas. So skip it.3243continue;3244}3245} else if (pass > 0) {3246uint32_t shadow_id = MAX_DIRECTIONAL_LIGHTS - 1 - (pass - int32_t(inst->light_passes.size()));3247if (inst->lightmap_instance.is_valid() && scene_state.directional_lights[shadow_id].bake_mode == RenderingServer::LIGHT_BAKE_STATIC) {3248// Skip shadows for static lights on meshes with a lightmap.3249continue;3250}3251}3252}32533254if constexpr (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) {3255GLES3::SceneShaderData::BlendMode desired_blend_mode;3256if (pass > 0) {3257desired_blend_mode = GLES3::SceneShaderData::BLEND_MODE_ADD;3258} else {3259desired_blend_mode = shader->blend_mode;3260}32613262if (desired_blend_mode != scene_state.current_blend_mode) {3263switch (desired_blend_mode) {3264case GLES3::SceneShaderData::BLEND_MODE_MIX: {3265glBlendEquation(GL_FUNC_ADD);3266if (p_render_data->transparent_bg) {3267glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);3268} else {3269glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);3270}32713272} break;3273case GLES3::SceneShaderData::BLEND_MODE_ADD: {3274glBlendEquation(GL_FUNC_ADD);3275glBlendFunc(p_pass_mode == PASS_MODE_COLOR_TRANSPARENT ? GL_SRC_ALPHA : GL_ONE, GL_ONE);32763277} break;3278case GLES3::SceneShaderData::BLEND_MODE_SUB: {3279glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);3280glBlendFunc(GL_SRC_ALPHA, GL_ONE);32813282} break;3283case GLES3::SceneShaderData::BLEND_MODE_MUL: {3284glBlendEquation(GL_FUNC_ADD);3285if (p_render_data->transparent_bg) {3286glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_DST_ALPHA, GL_ZERO);3287} else {3288glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_ZERO, GL_ONE);3289}32903291} break;3292case GLES3::SceneShaderData::BLEND_MODE_PREMULT_ALPHA: {3293glBlendEquation(GL_FUNC_ADD);3294glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);32953296} break;3297case GLES3::SceneShaderData::BLEND_MODE_ALPHA_TO_COVERAGE: {3298// Do nothing for now.3299} break;3300}3301scene_state.current_blend_mode = desired_blend_mode;3302}3303}33043305// Find cull variant.3306RS::CullMode cull_mode = shader->cull_mode;33073308if (p_pass_mode == PASS_MODE_MATERIAL || (p_pass_mode == PASS_MODE_SHADOW && (surf->flags & GeometryInstanceSurface::FLAG_USES_DOUBLE_SIDED_SHADOWS))) {3309cull_mode = RS::CULL_MODE_DISABLED;3310} else {3311bool mirror = inst->mirror;3312if (p_params->reverse_cull) {3313mirror = !mirror;3314}3315if (cull_mode == RS::CULL_MODE_FRONT && mirror) {3316cull_mode = RS::CULL_MODE_BACK;3317} else if (cull_mode == RS::CULL_MODE_BACK && mirror) {3318cull_mode = RS::CULL_MODE_FRONT;3319}3320}33213322scene_state.set_gl_cull_mode(cull_mode);33233324RS::PrimitiveType primitive = surf->primitive;3325if (shader->uses_point_size) {3326primitive = RS::PRIMITIVE_POINTS;3327}3328static const GLenum prim[5] = { GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP };3329GLenum primitive_gl = prim[int(primitive)];33303331GLuint vertex_array_gl = 0;3332GLuint index_array_gl = 0;3333uint64_t vertex_input_mask = shader->vertex_input_mask;3334if (inst->lightmap_instance.is_valid() || p_pass_mode == PASS_MODE_MATERIAL) {3335vertex_input_mask |= 1 << RS::ARRAY_TEX_UV2;3336}33373338// Skeleton and blend shapes.3339if (surf->owner->mesh_instance.is_valid()) {3340mesh_storage->mesh_instance_surface_get_vertex_arrays_and_format(surf->owner->mesh_instance, surf->surface_index, vertex_input_mask, p_pass_mode == PASS_MODE_MOTION_VECTORS, vertex_array_gl);3341} else {3342mesh_storage->mesh_surface_get_vertex_arrays_and_format(mesh_surface, vertex_input_mask, p_pass_mode == PASS_MODE_MOTION_VECTORS, vertex_array_gl);3343}33443345index_array_gl = mesh_storage->mesh_surface_get_index_buffer(mesh_surface, surf->lod_index);33463347if (prev_vertex_array_gl != vertex_array_gl) {3348if (vertex_array_gl != 0) {3349glBindVertexArray(vertex_array_gl);3350}3351prev_vertex_array_gl = vertex_array_gl;33523353// Invalidate the previous index array3354prev_index_array_gl = 0;3355}33563357bool use_wireframe = false;3358if (p_params->force_wireframe || shader->wireframe) {3359GLuint wireframe_index_array_gl = mesh_storage->mesh_surface_get_index_buffer_wireframe(mesh_surface);3360if (wireframe_index_array_gl) {3361index_array_gl = wireframe_index_array_gl;3362use_wireframe = true;3363}3364}33653366bool use_index_buffer = index_array_gl != 0;3367if (prev_index_array_gl != index_array_gl) {3368if (index_array_gl != 0) {3369// Bind index each time so we can use LODs3370glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_gl);3371}3372prev_index_array_gl = index_array_gl;3373}33743375Transform3D world_transform;3376if (inst->store_transform_cache) {3377world_transform = inst->transform;3378}33793380if (prev_material_data != material_data) {3381material_data->bind_uniforms();3382prev_material_data = material_data;3383}33843385SceneShaderGLES3::ShaderVariant instance_variant = shader_variant;33863387if (inst->instance_count > 0) {3388// Will need to use instancing to draw (either MultiMesh or Particles).3389instance_variant = SceneShaderGLES3::ShaderVariant(1 + int(instance_variant));3390}33913392uint64_t spec_constants = base_spec_constants;33933394// Set up spec constants for lighting.3395if constexpr (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) {3396// Only check during color passes as light shader code is compiled out during depth-only pass anyway.33973398if (pass == 0) {3399spec_constants |= SceneShaderGLES3::BASE_PASS;34003401if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {3402spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_OMNI;3403spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_SPOT;3404spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL;3405spec_constants |= SceneShaderGLES3::DISABLE_LIGHTMAP;3406} else {3407if (inst->omni_light_gl_cache.is_empty()) {3408spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_OMNI;3409}34103411if (inst->spot_light_gl_cache.is_empty()) {3412spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_SPOT;3413}34143415if (p_render_data->directional_light_count == p_render_data->directional_shadow_count) {3416spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL;3417}34183419if (inst->reflection_probe_rid_cache.is_empty()) {3420// We don't have any probes.3421spec_constants |= SceneShaderGLES3::DISABLE_REFLECTION_PROBE;3422} else if (inst->reflection_probe_rid_cache.size() > 1) {3423// We have a second probe.3424spec_constants |= SceneShaderGLES3::SECOND_REFLECTION_PROBE;3425}34263427if (inst->lightmap_instance.is_valid()) {3428spec_constants |= SceneShaderGLES3::USE_LIGHTMAP;34293430GLES3::LightmapInstance *li = GLES3::LightStorage::get_singleton()->get_lightmap_instance(inst->lightmap_instance);3431GLES3::Lightmap *lm = GLES3::LightStorage::get_singleton()->get_lightmap(li->lightmap);34323433if (lm->uses_spherical_harmonics) {3434spec_constants |= SceneShaderGLES3::USE_SH_LIGHTMAP;3435}34363437if (lightmap_bicubic_upscale) {3438spec_constants |= SceneShaderGLES3::LIGHTMAP_BICUBIC_FILTER;3439}3440} else if (inst->lightmap_sh) {3441spec_constants |= SceneShaderGLES3::USE_LIGHTMAP_CAPTURE;3442} else {3443spec_constants |= SceneShaderGLES3::DISABLE_LIGHTMAP;3444}34453446if (p_render_data->directional_light_count > 0 && is_environment(p_render_data->environment) && environment_get_fog_sun_scatter(p_render_data->environment) > 0.001) {3447spec_constants |= SceneShaderGLES3::USE_SUN_SCATTER;3448}3449}3450} else {3451// Only base pass uses the radiance map.3452spec_constants &= ~SceneShaderGLES3::USE_RADIANCE_MAP;3453spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_OMNI;3454spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_SPOT;3455spec_constants |= SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL;3456spec_constants |= SceneShaderGLES3::DISABLE_REFLECTION_PROBE;34573458bool disable_lightmaps = true;34593460// Additive directional passes may use shadowmasks, so enable lightmaps for them.3461if (pass >= int32_t(inst->light_passes.size()) && inst->lightmap_instance.is_valid()) {3462GLES3::LightmapInstance *li = GLES3::LightStorage::get_singleton()->get_lightmap_instance(inst->lightmap_instance);3463GLES3::Lightmap *lm = GLES3::LightStorage::get_singleton()->get_lightmap(li->lightmap);34643465if (lm->shadowmask_mode != RS::SHADOWMASK_MODE_NONE) {3466spec_constants |= SceneShaderGLES3::USE_LIGHTMAP;3467disable_lightmaps = false;34683469if (lightmap_bicubic_upscale) {3470spec_constants |= SceneShaderGLES3::LIGHTMAP_BICUBIC_FILTER;3471}3472}3473}34743475if (disable_lightmaps) {3476spec_constants |= SceneShaderGLES3::DISABLE_LIGHTMAP;3477}3478}34793480if (uses_additive_lighting) {3481spec_constants |= SceneShaderGLES3::USE_ADDITIVE_LIGHTING;34823483if (pass < int32_t(inst->light_passes.size())) {3484// Rendering positional lights.3485if (inst->light_passes[pass].is_omni) {3486spec_constants |= SceneShaderGLES3::ADDITIVE_OMNI;3487} else {3488spec_constants |= SceneShaderGLES3::ADDITIVE_SPOT;3489}34903491if (scene_state.positional_shadow_quality >= RS::SHADOW_QUALITY_SOFT_HIGH) {3492spec_constants |= SceneShaderGLES3::SHADOW_MODE_PCF_13;3493} else if (scene_state.positional_shadow_quality >= RS::SHADOW_QUALITY_SOFT_LOW) {3494spec_constants |= SceneShaderGLES3::SHADOW_MODE_PCF_5;3495}3496} else {3497// Render directional lights.34983499uint32_t shadow_id = MAX_DIRECTIONAL_LIGHTS - 1 - (pass - int32_t(inst->light_passes.size()));3500if (!(scene_state.directional_lights[shadow_id].mask & inst->layer_mask)) {3501// Disable additive lighting when masks are not overlapping.3502spec_constants &= ~SceneShaderGLES3::USE_ADDITIVE_LIGHTING;3503}3504if (pass == 0 && inst->lightmap_instance.is_valid() && scene_state.directional_lights[shadow_id].bake_mode == RenderingServer::LIGHT_BAKE_STATIC) {3505// Disable additive lighting with a static light and a lightmap.3506spec_constants &= ~SceneShaderGLES3::USE_ADDITIVE_LIGHTING;3507}3508if (scene_state.directional_shadows[shadow_id].shadow_split_offsets[0] == scene_state.directional_shadows[shadow_id].shadow_split_offsets[1]) {3509// Orthogonal, do nothing.3510} else if (scene_state.directional_shadows[shadow_id].shadow_split_offsets[1] == scene_state.directional_shadows[shadow_id].shadow_split_offsets[2]) {3511spec_constants |= SceneShaderGLES3::LIGHT_USE_PSSM2;3512} else {3513spec_constants |= SceneShaderGLES3::LIGHT_USE_PSSM4;3514}35153516if (scene_state.directional_shadows[shadow_id].blend_splits) {3517spec_constants |= SceneShaderGLES3::LIGHT_USE_PSSM_BLEND;3518}35193520if (scene_state.directional_shadow_quality >= RS::SHADOW_QUALITY_SOFT_HIGH) {3521spec_constants |= SceneShaderGLES3::SHADOW_MODE_PCF_13;3522} else if (scene_state.directional_shadow_quality >= RS::SHADOW_QUALITY_SOFT_LOW) {3523spec_constants |= SceneShaderGLES3::SHADOW_MODE_PCF_5;3524}3525}3526}3527}35283529if (prev_shader != shader || prev_variant != instance_variant || spec_constants != prev_spec_constants) {3530bool success = material_storage->shaders.scene_shader.version_bind_shader(shader->version, instance_variant, spec_constants);3531if (!success) {3532break;3533}35343535float opaque_prepass_threshold = 0.0;3536if constexpr (p_pass_mode == PASS_MODE_DEPTH || p_pass_mode == PASS_MODE_MOTION_VECTORS) {3537opaque_prepass_threshold = 0.99;3538} else if constexpr (p_pass_mode == PASS_MODE_SHADOW) {3539opaque_prepass_threshold = 0.1;3540}35413542material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::OPAQUE_PREPASS_THRESHOLD, opaque_prepass_threshold, shader->version, instance_variant, spec_constants);3543}35443545// Pass in lighting uniforms.3546if constexpr (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) {3547GLES3::Config *config = GLES3::Config::get_singleton();3548// Pass light and shadow index and bind shadow texture.3549if (uses_additive_lighting) {3550if (pass < int32_t(inst->light_passes.size())) {3551int32_t shadow_id = inst->light_passes[pass].shadow_id;3552if (shadow_id >= 0) {3553uint32_t light_id = inst->light_passes[pass].light_id;3554bool is_omni = inst->light_passes[pass].is_omni;3555SceneShaderGLES3::Uniforms uniform_name = is_omni ? SceneShaderGLES3::OMNI_LIGHT_INDEX : SceneShaderGLES3::SPOT_LIGHT_INDEX;3556material_storage->shaders.scene_shader.version_set_uniform(uniform_name, uint32_t(light_id), shader->version, instance_variant, spec_constants);3557material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::POSITIONAL_SHADOW_INDEX, uint32_t(shadow_id), shader->version, instance_variant, spec_constants);35583559glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 3);3560RID light_instance_rid = inst->light_passes[pass].light_instance_rid;35613562GLuint tex = GLES3::LightStorage::get_singleton()->light_instance_get_shadow_texture(light_instance_rid, p_render_data->shadow_atlas);3563if (is_omni) {3564glBindTexture(GL_TEXTURE_CUBE_MAP, tex);3565} else {3566glBindTexture(GL_TEXTURE_2D, tex);3567}3568}3569} else {3570uint32_t shadow_id = MAX_DIRECTIONAL_LIGHTS - 1 - (pass - int32_t(inst->light_passes.size()));3571material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::DIRECTIONAL_SHADOW_INDEX, shadow_id, shader->version, instance_variant, spec_constants);35723573GLuint tex = GLES3::LightStorage::get_singleton()->directional_shadow_get_texture();3574glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 3);3575glBindTexture(GL_TEXTURE_2D, tex);35763577if (inst->lightmap_instance.is_valid()) {3578// Use shadowmasks for directional light passes.3579GLES3::LightmapInstance *li = GLES3::LightStorage::get_singleton()->get_lightmap_instance(inst->lightmap_instance);3580GLES3::Lightmap *lm = GLES3::LightStorage::get_singleton()->get_lightmap(li->lightmap);35813582material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::LIGHTMAP_SLICE, inst->lightmap_slice_index, shader->version, instance_variant, spec_constants);35833584Vector4 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);3585material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::LIGHTMAP_UV_SCALE, uv_scale, shader->version, instance_variant, spec_constants);35863587if (lightmap_bicubic_upscale) {3588Vector2 light_texture_size(lm->light_texture_size.x, lm->light_texture_size.y);3589material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::LIGHTMAP_TEXTURE_SIZE, light_texture_size, shader->version, instance_variant, spec_constants);3590}35913592material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::LIGHTMAP_SHADOWMASK_MODE, (uint32_t)lm->shadowmask_mode, shader->version, instance_variant, spec_constants);35933594if (lm->shadow_texture.is_valid()) {3595tex = GLES3::TextureStorage::get_singleton()->texture_get_texid(lm->shadow_texture);3596} else {3597tex = GLES3::TextureStorage::get_singleton()->texture_get_texid(GLES3::TextureStorage::get_singleton()->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_2D_ARRAY_WHITE));3598}35993600glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 5);3601glBindTexture(GL_TEXTURE_2D_ARRAY, tex);3602}3603}3604}36053606// Pass light count and array of light indices for base pass.3607if ((prev_inst != inst || prev_shader != shader || prev_variant != instance_variant || prev_spec_constants != spec_constants) && pass == 0) {3608// Rebind the light indices.3609material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::OMNI_LIGHT_COUNT, inst->omni_light_gl_cache.size(), shader->version, instance_variant, spec_constants);3610material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::SPOT_LIGHT_COUNT, inst->spot_light_gl_cache.size(), shader->version, instance_variant, spec_constants);36113612if (inst->omni_light_gl_cache.size()) {3613glUniform1uiv(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());3614}36153616if (inst->spot_light_gl_cache.size()) {3617glUniform1uiv(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());3618}36193620if (inst->lightmap_instance.is_valid()) {3621GLES3::LightmapInstance *li = GLES3::LightStorage::get_singleton()->get_lightmap_instance(inst->lightmap_instance);3622GLES3::Lightmap *lm = GLES3::LightStorage::get_singleton()->get_lightmap(li->lightmap);36233624GLuint tex = GLES3::TextureStorage::get_singleton()->texture_get_texid(lm->light_texture);3625glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 4);3626glBindTexture(GL_TEXTURE_2D_ARRAY, tex);36273628material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::LIGHTMAP_SLICE, inst->lightmap_slice_index, shader->version, instance_variant, spec_constants);36293630Vector4 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);3631material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::LIGHTMAP_UV_SCALE, uv_scale, shader->version, instance_variant, spec_constants);36323633if (lightmap_bicubic_upscale) {3634Vector2 light_texture_size(lm->light_texture_size.x, lm->light_texture_size.y);3635material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::LIGHTMAP_TEXTURE_SIZE, light_texture_size, shader->version, instance_variant, spec_constants);3636}36373638float exposure_normalization = 1.0;3639if (p_render_data->camera_attributes.is_valid()) {3640float enf = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);3641exposure_normalization = enf / lm->baked_exposure;3642}3643material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::LIGHTMAP_EXPOSURE_NORMALIZATION, exposure_normalization, shader->version, instance_variant, spec_constants);36443645if (lm->uses_spherical_harmonics) {3646Basis to_lm = li->transform.basis.inverse() * p_render_data->cam_transform.basis;3647to_lm = to_lm.inverse().transposed();3648GLfloat matrix[9] = {3649(GLfloat)to_lm.rows[0][0],3650(GLfloat)to_lm.rows[1][0],3651(GLfloat)to_lm.rows[2][0],3652(GLfloat)to_lm.rows[0][1],3653(GLfloat)to_lm.rows[1][1],3654(GLfloat)to_lm.rows[2][1],3655(GLfloat)to_lm.rows[0][2],3656(GLfloat)to_lm.rows[1][2],3657(GLfloat)to_lm.rows[2][2],3658};3659glUniformMatrix3fv(material_storage->shaders.scene_shader.version_get_uniform(SceneShaderGLES3::LIGHTMAP_NORMAL_XFORM, shader->version, instance_variant, spec_constants), 1, GL_FALSE, matrix);3660}36613662} else if (inst->lightmap_sh) {3663glUniform4fv(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));3664}3665prev_inst = inst;3666}3667}36683669prev_shader = shader;3670prev_variant = instance_variant;3671prev_spec_constants = spec_constants;36723673// Pass in reflection probe data3674if constexpr (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) {3675if (pass == 0 && inst->reflection_probe_rid_cache.size() > 0) {3676GLES3::Config *config = GLES3::Config::get_singleton();3677GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton();36783679// Setup first probe.3680{3681RID probe_rid = light_storage->reflection_probe_instance_get_probe(inst->reflection_probe_rid_cache[0]);3682GLES3::ReflectionProbe *probe = light_storage->get_reflection_probe(probe_rid);36833684material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE1_USE_BOX_PROJECT, probe->box_projection, shader->version, instance_variant, spec_constants);3685material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE1_BOX_EXTENTS, probe->size * 0.5, shader->version, instance_variant, spec_constants);3686material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE1_BOX_OFFSET, probe->origin_offset, shader->version, instance_variant, spec_constants);3687material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE1_EXTERIOR, !probe->interior, shader->version, instance_variant, spec_constants);3688material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE1_INTENSITY, probe->intensity, shader->version, instance_variant, spec_constants);3689material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE1_AMBIENT_MODE, int(probe->ambient_mode), shader->version, instance_variant, spec_constants);3690material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE1_AMBIENT_COLOR, probe->ambient_color * probe->ambient_color_energy, shader->version, instance_variant, spec_constants);3691material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE1_LOCAL_MATRIX, inst->reflection_probes_local_transform_cache[0], shader->version, instance_variant, spec_constants);3692material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE1_BLEND_DISTANCE, probe->blend_distance, shader->version, instance_variant, spec_constants);36933694glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 8);3695glBindTexture(GL_TEXTURE_CUBE_MAP, light_storage->reflection_probe_instance_get_texture(inst->reflection_probe_rid_cache[0]));3696}36973698if (inst->reflection_probe_rid_cache.size() > 1) {3699// Setup second probe.3700RID probe_rid = light_storage->reflection_probe_instance_get_probe(inst->reflection_probe_rid_cache[1]);3701GLES3::ReflectionProbe *probe = light_storage->get_reflection_probe(probe_rid);37023703material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE2_USE_BOX_PROJECT, probe->box_projection, shader->version, instance_variant, spec_constants);3704material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE2_BOX_EXTENTS, probe->size * 0.5, shader->version, instance_variant, spec_constants);3705material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE2_BOX_OFFSET, probe->origin_offset, shader->version, instance_variant, spec_constants);3706material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE2_EXTERIOR, !probe->interior, shader->version, instance_variant, spec_constants);3707material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE2_INTENSITY, probe->intensity, shader->version, instance_variant, spec_constants);3708material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE2_AMBIENT_MODE, int(probe->ambient_mode), shader->version, instance_variant, spec_constants);3709material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE2_AMBIENT_COLOR, probe->ambient_color * probe->ambient_color_energy, shader->version, instance_variant, spec_constants);3710material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE2_LOCAL_MATRIX, inst->reflection_probes_local_transform_cache[1], shader->version, instance_variant, spec_constants);3711material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::REFPROBE2_BLEND_DISTANCE, probe->blend_distance, shader->version, instance_variant, spec_constants);37123713glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 9);3714glBindTexture(GL_TEXTURE_CUBE_MAP, light_storage->reflection_probe_instance_get_texture(inst->reflection_probe_rid_cache[1]));37153716spec_constants |= SceneShaderGLES3::SECOND_REFLECTION_PROBE;3717}3718}3719}37203721if constexpr (p_pass_mode == PASS_MODE_MOTION_VECTORS) {3722if (unlikely(!inst->is_prev_transform_stored)) {3723inst->prev_transform = world_transform;3724inst->is_prev_transform_stored = true;3725}37263727material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::PREV_WORLD_TRANSFORM, inst->prev_transform, shader->version, instance_variant, spec_constants);3728inst->prev_transform = world_transform;3729}37303731material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, world_transform, shader->version, instance_variant, spec_constants);3732{3733GLES3::Mesh::Surface *s = reinterpret_cast<GLES3::Mesh::Surface *>(surf->surface);3734if (s->format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) {3735material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::COMPRESSED_AABB_POSITION, s->aabb.position, shader->version, instance_variant, spec_constants);3736material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::COMPRESSED_AABB_SIZE, s->aabb.size, shader->version, instance_variant, spec_constants);3737material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::UV_SCALE, s->uv_scale, shader->version, instance_variant, spec_constants);3738} else {3739material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::COMPRESSED_AABB_POSITION, Vector3(0.0, 0.0, 0.0), shader->version, instance_variant, spec_constants);3740material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::COMPRESSED_AABB_SIZE, Vector3(1.0, 1.0, 1.0), shader->version, instance_variant, spec_constants);3741material_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);3742}3743}37443745material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::MODEL_FLAGS, inst->flags_cache, shader->version, instance_variant, spec_constants);3746material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::INSTANCE_OFFSET, uint32_t(inst->shader_uniforms_offset), shader->version, instance_variant, spec_constants);37473748if (p_pass_mode == PASS_MODE_MATERIAL) {3749material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::UV_OFFSET, p_params->uv_offset, shader->version, instance_variant, spec_constants);3750} else if (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) {3751material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::LAYER_MASK, inst->layer_mask, shader->version, instance_variant, spec_constants);3752}37533754// Can be index count or vertex count3755uint32_t count = 0;3756if (surf->lod_index > 0) {3757count = surf->index_count;3758} else {3759count = mesh_storage->mesh_surface_get_vertices_drawn_count(mesh_surface);3760}37613762if (use_wireframe) {3763// In this case we are using index count, and we need double the indices for the wireframe mesh.3764count = count * 2;3765}37663767if constexpr (p_pass_mode != PASS_MODE_DEPTH && p_pass_mode != PASS_MODE_MOTION_VECTORS) {3768// Don't count draw calls during depth pre-pass or motion vector pass to match the RD renderers.3769if (p_render_data->render_info) {3770p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME]++;3771}3772}37733774if (inst->instance_count > 0) {3775// Using MultiMesh or Particles.3776// Bind instance buffers.37773778GLuint instance_buffer = 0;3779uint32_t stride = 0;3780if (inst->flags_cache & INSTANCE_DATA_FLAG_PARTICLES) {3781instance_buffer = particles_storage->particles_get_gl_buffer(inst->data->base);3782stride = 16; // 12 bytes for instance transform and 4 bytes for packed color and custom.3783} else {3784instance_buffer = mesh_storage->multimesh_get_gl_buffer(inst->data->base);3785stride = mesh_storage->multimesh_get_stride(inst->data->base);3786}37873788if (instance_buffer == 0) {3789// Instance buffer not initialized yet. Skip rendering for now.3790break;3791}37923793bool uses_format_2d = inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D;3794bool has_color_or_custom_data = (inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR) || (inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA);3795// Current data multimesh vertex attrib data begins at index 12.3796mesh_storage->multimesh_vertex_attrib_setup(instance_buffer, stride, uses_format_2d, has_color_or_custom_data, 12);37973798if (p_pass_mode == PASS_MODE_MOTION_VECTORS) {3799GLuint prev_instance_buffer = 0;3800if (inst->flags_cache & INSTANCE_DATA_FLAG_PARTICLES) {3801prev_instance_buffer = particles_storage->particles_get_prev_gl_buffer(inst->data->base);3802} else {3803prev_instance_buffer = mesh_storage->multimesh_get_prev_gl_buffer(inst->data->base);3804}38053806if (prev_instance_buffer == 0) {3807break;3808}38093810GLuint secondary_instance_buffer = 0;3811if (inst->flags_cache & INSTANCE_DATA_FLAG_PARTICLES) {3812if (particles_storage->particles_get_last_change(inst->data->base) == RSG::rasterizer->get_frame_number()) {3813secondary_instance_buffer = prev_instance_buffer;3814} else {3815secondary_instance_buffer = instance_buffer;3816}3817} else {3818if (mesh_storage->multimesh_get_last_change(inst->data->base) == RSG::rasterizer->get_frame_number()) {3819secondary_instance_buffer = prev_instance_buffer;3820} else {3821secondary_instance_buffer = instance_buffer;3822}3823}38243825// Previous data multimesh vertex attrib data begins at index 18.3826mesh_storage->multimesh_vertex_attrib_setup(secondary_instance_buffer, stride, uses_format_2d, has_color_or_custom_data, 18);3827}38283829if (use_wireframe) {3830glDrawElementsInstanced(GL_LINES, count, GL_UNSIGNED_INT, nullptr, inst->instance_count);3831} else {3832if (use_index_buffer) {3833glDrawElementsInstanced(primitive_gl, count, mesh_storage->mesh_surface_get_index_type(mesh_surface), nullptr, inst->instance_count);3834} else {3835glDrawArraysInstanced(primitive_gl, 0, count, inst->instance_count);3836}3837}3838} else {3839// Using regular Mesh.3840if (use_wireframe) {3841glDrawElements(GL_LINES, count, GL_UNSIGNED_INT, nullptr);3842} else {3843if (use_index_buffer) {3844glDrawElements(primitive_gl, count, mesh_storage->mesh_surface_get_index_type(mesh_surface), nullptr);3845} else {3846glDrawArrays(primitive_gl, 0, count);3847}3848}3849}38503851if (inst->instance_count > 0) {3852glDisableVertexAttribArray(12);3853glDisableVertexAttribArray(13);3854glDisableVertexAttribArray(14);3855glDisableVertexAttribArray(15);3856}3857}3858if constexpr (p_pass_mode == PASS_MODE_COLOR) {3859if (uses_additive_lighting && !p_render_data->transparent_bg) {3860// Disable additive blending if enabled for additive lights.3861scene_state.enable_gl_blend(false);3862}3863}3864}38653866// Make the actual redraw request3867if (should_request_redraw) {3868RenderingServerDefault::redraw_request();3869}3870}38713872void 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) {3873}38743875void RasterizerSceneGLES3::render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) {3876GLES3::ParticlesStorage *particles_storage = GLES3::ParticlesStorage::get_singleton();38773878ERR_FAIL_COND(!particles_storage->particles_collision_is_heightfield(p_collider));3879Vector3 extents = particles_storage->particles_collision_get_extents(p_collider) * p_transform.basis.get_scale();3880Projection cm;3881cm.set_orthogonal(-extents.x, extents.x, -extents.z, extents.z, 0, extents.y * 2.0);38823883Vector3 cam_pos = p_transform.origin;3884cam_pos.y += extents.y;38853886Transform3D cam_xform;3887cam_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());38883889GLuint fb = particles_storage->particles_collision_get_heightfield_framebuffer(p_collider);3890Size2i fb_size = particles_storage->particles_collision_get_heightfield_size(p_collider);38913892RENDER_TIMESTAMP("Setup GPUParticlesCollisionHeightField3D");38933894RenderDataGLES3 render_data;38953896render_data.cam_projection = cm;3897render_data.cam_transform = cam_xform;3898render_data.view_projection[0] = cm;3899render_data.inv_cam_transform = render_data.cam_transform.affine_inverse();3900render_data.cam_orthogonal = true;3901render_data.z_near = 0.0;3902render_data.z_far = cm.get_z_far();3903render_data.main_cam_transform = cam_xform;39043905render_data.instances = &p_instances;39063907_setup_environment(&render_data, true, Vector2(fb_size), true, Color(), false);39083909PassMode pass_mode = PASS_MODE_SHADOW;39103911_fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode);3912render_list[RENDER_LIST_SECONDARY].sort_by_key();39133914RENDER_TIMESTAMP("Render Collider Heightfield");39153916glBindFramebuffer(GL_FRAMEBUFFER, fb);3917glViewport(0, 0, fb_size.width, fb_size.height);39183919GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_shader_parameters_get_uniform_buffer();39203921glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_GLOBALS_UNIFORM_LOCATION, global_buffer);3922glBindBuffer(GL_UNIFORM_BUFFER, 0);39233924scene_state.reset_gl_state();3925scene_state.enable_gl_depth_test(true);3926scene_state.enable_gl_depth_draw(true);3927scene_state.set_gl_depth_func(GL_GREATER);39283929glDrawBuffers(0, nullptr);39303931glColorMask(0, 0, 0, 0);3932RasterizerGLES3::clear_depth(0.0);39333934glClear(GL_DEPTH_BUFFER_BIT);39353936RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), false, 31, false);39373938_render_list_template<PASS_MODE_SHADOW>(&render_list_params, &render_data, 0, render_list[RENDER_LIST_SECONDARY].elements.size());39393940glColorMask(1, 1, 1, 1);3941glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);3942}39433944void RasterizerSceneGLES3::_render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, GLuint p_framebuffer, const Rect2i &p_region) {3945RENDER_TIMESTAMP("Setup Rendering UV2");39463947RenderDataGLES3 render_data;3948render_data.instances = &p_instances;39493950scene_state.data.emissive_exposure_normalization = -1.0; // Use default exposure normalization.39513952_setup_environment(&render_data, true, Vector2(1, 1), true, Color(), false);39533954PassMode pass_mode = PASS_MODE_MATERIAL;39553956_fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode);3957render_list[RENDER_LIST_SECONDARY].sort_by_key();39583959RENDER_TIMESTAMP("Render 3D Material");39603961{3962glBindFramebuffer(GL_FRAMEBUFFER, p_framebuffer);3963glViewport(p_region.position.x, p_region.position.y, p_region.size.x, p_region.size.y);39643965GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_shader_parameters_get_uniform_buffer();39663967glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_GLOBALS_UNIFORM_LOCATION, global_buffer);3968glBindBuffer(GL_UNIFORM_BUFFER, 0);39693970scene_state.reset_gl_state();3971scene_state.enable_gl_depth_test(true);3972scene_state.enable_gl_depth_draw(true);3973scene_state.set_gl_depth_func(GL_GREATER);39743975constexpr GLenum draw_buffers[]{3976GL_COLOR_ATTACHMENT0,3977GL_COLOR_ATTACHMENT1,3978GL_COLOR_ATTACHMENT2,3979GL_COLOR_ATTACHMENT33980};3981glDrawBuffers(std_size(draw_buffers), draw_buffers);39823983glClearColor(0.0, 0.0, 0.0, 0.0);3984RasterizerGLES3::clear_depth(0.0);3985glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);39863987uint64_t base_spec_constant = 0;3988base_spec_constant |= SceneShaderGLES3::RENDER_MATERIAL;3989base_spec_constant |= SceneShaderGLES3::DISABLE_FOG;3990base_spec_constant |= SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL;3991base_spec_constant |= SceneShaderGLES3::DISABLE_LIGHT_OMNI;3992base_spec_constant |= SceneShaderGLES3::DISABLE_LIGHT_SPOT;3993base_spec_constant |= SceneShaderGLES3::DISABLE_LIGHTMAP;39943995RenderListParameters 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));39963997const int uv_offset_count = 9;3998static const Vector2 uv_offsets[uv_offset_count] = {3999Vector2(-1, 1),4000Vector2(1, 1),4001Vector2(1, -1),4002Vector2(-1, -1),4003Vector2(-1, 0),4004Vector2(1, 0),4005Vector2(0, -1),4006Vector2(0, 1),4007Vector2(0, 0),4008};40094010for (int i = 0; i < uv_offset_count; i++) {4011Vector2 ofs = uv_offsets[i];4012ofs.x /= p_region.size.width;4013ofs.y /= p_region.size.height;4014render_list_params.uv_offset = ofs;4015_render_list_template<PASS_MODE_MATERIAL>(&render_list_params, &render_data, 0, render_list[RENDER_LIST_SECONDARY].elements.size());4016}40174018render_list_params.uv_offset = Vector2(0, 0);4019render_list_params.force_wireframe = false;4020_render_list_template<PASS_MODE_MATERIAL>(&render_list_params, &render_data, 0, render_list[RENDER_LIST_SECONDARY].elements.size());40214022GLuint db = GL_COLOR_ATTACHMENT0;4023glDrawBuffers(1, &db);4024glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);4025}4026}40274028void RasterizerSceneGLES3::set_time(double p_time, double p_step) {4029time = p_time;4030time_step = p_step;4031}40324033void RasterizerSceneGLES3::set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) {4034debug_draw = p_debug_draw;4035}40364037Ref<RenderSceneBuffers> RasterizerSceneGLES3::render_buffers_create() {4038Ref<RenderSceneBuffersGLES3> rb;4039rb.instantiate();4040return rb;4041}40424043void RasterizerSceneGLES3::_render_buffers_debug_draw(Ref<RenderSceneBuffersGLES3> p_render_buffers, RID p_shadow_atlas, GLuint p_fbo) {4044GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();4045GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton();4046GLES3::CopyEffects *copy_effects = GLES3::CopyEffects::get_singleton();40474048ERR_FAIL_COND(p_render_buffers.is_null());40494050RID render_target = p_render_buffers->render_target;4051GLES3::RenderTarget *rt = texture_storage->get_render_target(render_target);4052ERR_FAIL_NULL(rt);40534054if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SHADOW_ATLAS) {4055if (p_shadow_atlas.is_valid()) {4056// Get or create debug textures to display shadow maps as an atlas.4057GLuint shadow_atlas_texture = light_storage->shadow_atlas_get_debug_texture(p_shadow_atlas);4058GLuint shadow_atlas_fb = light_storage->shadow_atlas_get_debug_fb(p_shadow_atlas);40594060uint32_t shadow_atlas_size = light_storage->shadow_atlas_get_size(p_shadow_atlas);4061uint32_t quadrant_size = shadow_atlas_size >> 1;40624063glBindFramebuffer(GL_FRAMEBUFFER, shadow_atlas_fb);4064glViewport(0, 0, shadow_atlas_size, shadow_atlas_size);4065glActiveTexture(GL_TEXTURE0);4066scene_state.enable_gl_depth_draw(true);4067scene_state.set_gl_depth_func(GL_ALWAYS);4068scene_state.set_gl_cull_mode(RS::CULL_MODE_DISABLED);40694070// Loop through quadrants and copy shadows over.4071for (int quadrant = 0; quadrant < 4; quadrant++) {4072uint32_t subdivision = light_storage->shadow_atlas_get_quadrant_subdivision(p_shadow_atlas, quadrant);4073if (subdivision == 0) {4074continue;4075}40764077Rect2i atlas_rect;4078Rect2 atlas_uv_rect;40794080uint32_t shadow_size = (quadrant_size / subdivision);4081float size = float(shadow_size) / float(shadow_atlas_size);40824083uint32_t length = light_storage->shadow_atlas_get_quadrant_shadows_allocated(p_shadow_atlas, quadrant);4084for (uint32_t shadow_idx = 0; shadow_idx < length; shadow_idx++) {4085bool is_omni = light_storage->shadow_atlas_get_quadrant_shadow_is_omni(p_shadow_atlas, quadrant, shadow_idx);40864087// Calculate shadow's position in the debug atlas.4088atlas_rect.position.x = (quadrant & 1) * quadrant_size;4089atlas_rect.position.y = (quadrant >> 1) * quadrant_size;40904091atlas_rect.position.x += (shadow_idx % subdivision) * shadow_size;4092atlas_rect.position.y += (shadow_idx / subdivision) * shadow_size;40934094atlas_uv_rect.position = Vector2(atlas_rect.position) / float(shadow_atlas_size);40954096atlas_uv_rect.size = Vector2(size, size);40974098GLuint shadow_tex = light_storage->shadow_atlas_get_quadrant_shadow_texture(p_shadow_atlas, quadrant, shadow_idx);4099// Copy from shadowmap to debug atlas.4100if (is_omni) {4101glBindTexture(GL_TEXTURE_CUBE_MAP, shadow_tex);4102glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_NONE);41034104copy_effects->copy_cube_to_rect(atlas_uv_rect);41054106glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);4107glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);4108} else {4109glBindTexture(GL_TEXTURE_2D, shadow_tex);4110glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);41114112copy_effects->copy_to_rect(atlas_uv_rect);41134114glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);4115glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);4116}4117}4118}41194120// Set back to FBO4121glBindFramebuffer(GL_FRAMEBUFFER, p_fbo);4122Size2i size = p_render_buffers->get_internal_size();4123glViewport(0, 0, size.width, size.height);4124glBindTexture(GL_TEXTURE_2D, shadow_atlas_texture);41254126copy_effects->copy_to_rect(Rect2(Vector2(), Vector2(0.5, 0.5)));4127glBindTexture(GL_TEXTURE_2D, 0);4128glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);4129}4130}4131if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS) {4132if (light_storage->directional_shadow_get_texture() != 0) {4133GLuint shadow_atlas_texture = light_storage->directional_shadow_get_texture();4134glActiveTexture(GL_TEXTURE0);4135glBindTexture(GL_TEXTURE_2D, shadow_atlas_texture);4136glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);4137glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);4138glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED);4139glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);4140glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE);41414142scene_state.enable_gl_depth_test(false);4143scene_state.enable_gl_depth_draw(false);41444145copy_effects->copy_to_rect(Rect2(Vector2(), Vector2(0.5, 0.5)));4146glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);4147glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN);4148glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE);4149glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);4150glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);4151glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);4152glBindTexture(GL_TEXTURE_2D, 0);4153}4154}4155}41564157void RasterizerSceneGLES3::gi_set_use_half_resolution(bool p_enable) {4158}41594160void RasterizerSceneGLES3::screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_curve) {4161}41624163bool RasterizerSceneGLES3::screen_space_roughness_limiter_is_active() const {4164return false;4165}41664167void RasterizerSceneGLES3::sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) {4168}41694170void RasterizerSceneGLES3::sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) {4171}41724173TypedArray<Image> RasterizerSceneGLES3::bake_render_uv2(RID p_base, const TypedArray<RID> &p_material_overrides, const Size2i &p_image_size) {4174GLES3::Config *config = GLES3::Config::get_singleton();4175ERR_FAIL_COND_V_MSG(p_image_size.width <= 0, TypedArray<Image>(), "Image width must be greater than 0.");4176ERR_FAIL_COND_V_MSG(p_image_size.height <= 0, TypedArray<Image>(), "Image height must be greater than 0.");41774178GLuint albedo_alpha_tex = 0;4179GLuint normal_tex = 0;4180GLuint orm_tex = 0;4181GLuint emission_tex = 0;4182GLuint depth_tex = 0;4183glGenTextures(1, &albedo_alpha_tex);4184glGenTextures(1, &normal_tex);4185glGenTextures(1, &orm_tex);4186glGenTextures(1, &emission_tex);4187glGenTextures(1, &depth_tex);41884189glBindTexture(GL_TEXTURE_2D, albedo_alpha_tex);4190glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, p_image_size.width, p_image_size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);4191GLES3::Utilities::get_singleton()->texture_allocated_data(albedo_alpha_tex, p_image_size.width * p_image_size.height * 4, "Lightmap albedo texture");41924193glBindTexture(GL_TEXTURE_2D, normal_tex);4194glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, p_image_size.width, p_image_size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);4195GLES3::Utilities::get_singleton()->texture_allocated_data(normal_tex, p_image_size.width * p_image_size.height * 4, "Lightmap normal texture");41964197glBindTexture(GL_TEXTURE_2D, orm_tex);4198glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, p_image_size.width, p_image_size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);4199GLES3::Utilities::get_singleton()->texture_allocated_data(orm_tex, p_image_size.width * p_image_size.height * 4, "Lightmap ORM texture");42004201// Consider rendering to RGBA8 encoded as RGBE, then manually convert to RGBAH on CPU.4202glBindTexture(GL_TEXTURE_2D, emission_tex);4203if (config->float_texture_supported) {4204glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, p_image_size.width, p_image_size.height, 0, GL_RGBA, GL_FLOAT, nullptr);4205GLES3::Utilities::get_singleton()->texture_allocated_data(emission_tex, p_image_size.width * p_image_size.height * 16, "Lightmap emission texture");4206} else {4207// Fallback to RGBA8 on devices that don't support rendering to floating point textures. This will look bad, but we have no choice.4208glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, p_image_size.width, p_image_size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);4209GLES3::Utilities::get_singleton()->texture_allocated_data(emission_tex, p_image_size.width * p_image_size.height * 4, "Lightmap emission texture");4210}42114212glBindTexture(GL_TEXTURE_2D, depth_tex);4213glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, p_image_size.width, p_image_size.height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);4214GLES3::Utilities::get_singleton()->texture_allocated_data(depth_tex, p_image_size.width * p_image_size.height * 3, "Lightmap depth texture");42154216GLuint fbo = 0;4217glGenFramebuffers(1, &fbo);4218glBindFramebuffer(GL_FRAMEBUFFER, fbo);42194220glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, albedo_alpha_tex, 0);4221glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, normal_tex, 0);4222glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, orm_tex, 0);4223glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, emission_tex, 0);4224glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_tex, 0);42254226GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);4227if (status != GL_FRAMEBUFFER_COMPLETE) {4228glDeleteFramebuffers(1, &fbo);4229GLES3::Utilities::get_singleton()->texture_free_data(albedo_alpha_tex);4230GLES3::Utilities::get_singleton()->texture_free_data(normal_tex);4231GLES3::Utilities::get_singleton()->texture_free_data(orm_tex);4232GLES3::Utilities::get_singleton()->texture_free_data(emission_tex);4233GLES3::Utilities::get_singleton()->texture_free_data(depth_tex);42344235WARN_PRINT("Could not create render target, status: " + GLES3::TextureStorage::get_singleton()->get_framebuffer_error(status));4236return TypedArray<Image>();4237}42384239RenderGeometryInstance *gi_inst = geometry_instance_create(p_base);4240ERR_FAIL_NULL_V(gi_inst, TypedArray<Image>());42414242uint32_t sc = RSG::mesh_storage->mesh_get_surface_count(p_base);4243Vector<RID> materials;4244materials.resize(sc);42454246for (uint32_t i = 0; i < sc; i++) {4247if (i < (uint32_t)p_material_overrides.size()) {4248materials.write[i] = p_material_overrides[i];4249}4250}42514252gi_inst->set_surface_materials(materials);42534254if (cull_argument.size() == 0) {4255cull_argument.push_back(nullptr);4256}4257cull_argument[0] = gi_inst;4258_render_uv2(cull_argument, fbo, Rect2i(0, 0, p_image_size.width, p_image_size.height));42594260geometry_instance_free(gi_inst);42614262TypedArray<Image> ret;42634264// Create a dummy texture so we can use texture_2d_get.4265RID tex_rid = GLES3::TextureStorage::get_singleton()->texture_allocate();4266GLES3::Texture texture;4267texture.width = p_image_size.width;4268texture.height = p_image_size.height;4269texture.alloc_width = p_image_size.width;4270texture.alloc_height = p_image_size.height;4271texture.format = Image::FORMAT_RGBA8;4272texture.real_format = Image::FORMAT_RGBA8;4273texture.gl_format_cache = GL_RGBA;4274texture.gl_type_cache = GL_UNSIGNED_BYTE;4275texture.type = GLES3::Texture::TYPE_2D;4276texture.target = GL_TEXTURE_2D;4277texture.active = true;4278texture.is_render_target = true; // Enable this so the texture isn't cached in the editor.42794280GLES3::TextureStorage::get_singleton()->texture_2d_initialize_from_texture(tex_rid, texture);4281GLES3::Texture *tex = GLES3::TextureStorage::get_singleton()->get_texture(tex_rid);42824283{4284tex->tex_id = albedo_alpha_tex;4285Ref<Image> img = GLES3::TextureStorage::get_singleton()->texture_2d_get(tex_rid);4286GLES3::Utilities::get_singleton()->texture_free_data(albedo_alpha_tex);4287ret.push_back(img);4288}42894290{4291tex->tex_id = normal_tex;4292Ref<Image> img = GLES3::TextureStorage::get_singleton()->texture_2d_get(tex_rid);4293GLES3::Utilities::get_singleton()->texture_free_data(normal_tex);4294ret.push_back(img);4295}42964297{4298tex->tex_id = orm_tex;4299Ref<Image> img = GLES3::TextureStorage::get_singleton()->texture_2d_get(tex_rid);4300GLES3::Utilities::get_singleton()->texture_free_data(orm_tex);4301ret.push_back(img);4302}43034304{4305tex->tex_id = emission_tex;4306if (config->float_texture_supported) {4307tex->format = Image::FORMAT_RGBAH;4308tex->real_format = Image::FORMAT_RGBAH;4309tex->gl_type_cache = GL_HALF_FLOAT;4310}4311Ref<Image> img = GLES3::TextureStorage::get_singleton()->texture_2d_get(tex_rid);4312GLES3::Utilities::get_singleton()->texture_free_data(emission_tex);4313ret.push_back(img);4314}43154316tex->is_render_target = false;4317tex->tex_id = 0;4318GLES3::TextureStorage::get_singleton()->texture_free(tex_rid);43194320GLES3::Utilities::get_singleton()->texture_free_data(depth_tex);4321glDeleteFramebuffers(1, &fbo);4322return ret;4323}43244325bool RasterizerSceneGLES3::free(RID p_rid) {4326if (is_environment(p_rid)) {4327environment_free(p_rid);4328} else if (sky_owner.owns(p_rid)) {4329Sky *sky = sky_owner.get_or_null(p_rid);4330ERR_FAIL_NULL_V(sky, false);4331_free_sky_data(sky);4332sky_owner.free(p_rid);4333} else if (GLES3::LightStorage::get_singleton()->owns_light_instance(p_rid)) {4334GLES3::LightStorage::get_singleton()->light_instance_free(p_rid);4335} else if (RSG::camera_attributes->owns_camera_attributes(p_rid)) {4336//not much to delete, just free it4337RSG::camera_attributes->camera_attributes_free(p_rid);4338} else if (is_compositor(p_rid)) {4339compositor_free(p_rid);4340} else if (is_compositor_effect(p_rid)) {4341compositor_effect_free(p_rid);4342} else {4343return false;4344}4345return true;4346}43474348void RasterizerSceneGLES3::update() {4349_update_dirty_skys();4350}43514352void RasterizerSceneGLES3::sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) {4353}43544355void RasterizerSceneGLES3::decals_set_filter(RS::DecalFilter p_filter) {4356}43574358void RasterizerSceneGLES3::light_projectors_set_filter(RS::LightProjectorFilter p_filter) {4359}43604361void RasterizerSceneGLES3::lightmaps_set_bicubic_filter(bool p_enable) {4362lightmap_bicubic_upscale = p_enable;4363}43644365void RasterizerSceneGLES3::material_set_use_debanding(bool p_enable) {4366// Material debanding not yet implemented.4367}43684369RasterizerSceneGLES3::RasterizerSceneGLES3() {4370singleton = this;43714372GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();4373GLES3::Config *config = GLES3::Config::get_singleton();43744375cull_argument.set_page_pool(&cull_argument_pool);43764377// Quality settings.4378use_physical_light_units = GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units");43794380positional_soft_shadow_filter_set_quality((RS::ShadowQuality)(int)GLOBAL_GET("rendering/lights_and_shadows/positional_shadow/soft_shadow_filter_quality"));4381directional_soft_shadow_filter_set_quality((RS::ShadowQuality)(int)GLOBAL_GET("rendering/lights_and_shadows/directional_shadow/soft_shadow_filter_quality"));4382lightmaps_set_bicubic_filter(GLOBAL_GET("rendering/lightmapping/lightmap_gi/use_bicubic_filter"));43834384{4385// Setup Lights43864387config->max_renderable_lights = MIN(config->max_renderable_lights, config->max_uniform_buffer_size / (int)sizeof(RasterizerSceneGLES3::LightData));4388config->max_lights_per_object = MIN(config->max_lights_per_object, config->max_renderable_lights);43894390uint32_t light_buffer_size = config->max_renderable_lights * sizeof(LightData);4391scene_state.omni_lights = memnew_arr(LightData, config->max_renderable_lights);4392scene_state.omni_light_sort = memnew_arr(InstanceSort<GLES3::LightInstance>, config->max_renderable_lights);4393glGenBuffers(1, &scene_state.omni_light_buffer);4394glBindBuffer(GL_UNIFORM_BUFFER, scene_state.omni_light_buffer);4395GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.omni_light_buffer, light_buffer_size, nullptr, GL_STREAM_DRAW, "OmniLight UBO");43964397scene_state.spot_lights = memnew_arr(LightData, config->max_renderable_lights);4398scene_state.spot_light_sort = memnew_arr(InstanceSort<GLES3::LightInstance>, config->max_renderable_lights);4399glGenBuffers(1, &scene_state.spot_light_buffer);4400glBindBuffer(GL_UNIFORM_BUFFER, scene_state.spot_light_buffer);4401GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.spot_light_buffer, light_buffer_size, nullptr, GL_STREAM_DRAW, "SpotLight UBO");44024403uint32_t directional_light_buffer_size = MAX_DIRECTIONAL_LIGHTS * sizeof(DirectionalLightData);4404scene_state.directional_lights = memnew_arr(DirectionalLightData, MAX_DIRECTIONAL_LIGHTS);4405glGenBuffers(1, &scene_state.directional_light_buffer);4406glBindBuffer(GL_UNIFORM_BUFFER, scene_state.directional_light_buffer);4407GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.directional_light_buffer, directional_light_buffer_size, nullptr, GL_STREAM_DRAW, "DirectionalLight UBO");44084409uint32_t shadow_buffer_size = config->max_renderable_lights * sizeof(ShadowData) * 2;4410scene_state.positional_shadows = memnew_arr(ShadowData, config->max_renderable_lights * 2);4411glGenBuffers(1, &scene_state.positional_shadow_buffer);4412glBindBuffer(GL_UNIFORM_BUFFER, scene_state.positional_shadow_buffer);4413GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.positional_shadow_buffer, shadow_buffer_size, nullptr, GL_STREAM_DRAW, "Positional Shadow UBO");44144415uint32_t directional_shadow_buffer_size = MAX_DIRECTIONAL_LIGHTS * sizeof(DirectionalShadowData);4416scene_state.directional_shadows = memnew_arr(DirectionalShadowData, MAX_DIRECTIONAL_LIGHTS);4417glGenBuffers(1, &scene_state.directional_shadow_buffer);4418glBindBuffer(GL_UNIFORM_BUFFER, scene_state.directional_shadow_buffer);4419GLES3::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");44204421glBindBuffer(GL_UNIFORM_BUFFER, 0);4422}44234424{4425sky_globals.max_directional_lights = 4;4426uint32_t directional_light_buffer_size = sky_globals.max_directional_lights * sizeof(DirectionalLightData);4427sky_globals.directional_lights = memnew_arr(DirectionalLightData, sky_globals.max_directional_lights);4428sky_globals.last_frame_directional_lights = memnew_arr(DirectionalLightData, sky_globals.max_directional_lights);4429sky_globals.last_frame_directional_light_count = sky_globals.max_directional_lights + 1;4430glGenBuffers(1, &sky_globals.directional_light_buffer);4431glBindBuffer(GL_UNIFORM_BUFFER, sky_globals.directional_light_buffer);4432GLES3::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");44334434glBindBuffer(GL_UNIFORM_BUFFER, 0);4435}44364437{4438String global_defines;4439global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now4440global_defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(config->max_renderable_lights) + "\n";4441global_defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(MAX_DIRECTIONAL_LIGHTS) + "\n";4442global_defines += "\n#define MAX_FORWARD_LIGHTS " + itos(config->max_lights_per_object) + "u\n";4443global_defines += "\n#define MAX_ROUGHNESS_LOD " + itos(sky_globals.roughness_layers - 1) + ".0\n";4444if (config->force_vertex_shading) {4445global_defines += "\n#define USE_VERTEX_LIGHTING\n";4446}4447if (!config->specular_occlusion) {4448global_defines += "\n#define SPECULAR_OCCLUSION_DISABLED\n";4449}4450material_storage->shaders.scene_shader.initialize(global_defines);4451scene_globals.shader_default_version = material_storage->shaders.scene_shader.version_create();4452material_storage->shaders.scene_shader.version_bind_shader(scene_globals.shader_default_version, SceneShaderGLES3::MODE_COLOR);4453}44544455{4456//default material and shader4457scene_globals.default_shader = material_storage->shader_allocate();4458material_storage->shader_initialize(scene_globals.default_shader);4459material_storage->shader_set_code(scene_globals.default_shader, R"(4460// Default 3D material shader (Compatibility).44614462shader_type spatial;44634464void vertex() {4465ROUGHNESS = 0.8;4466}44674468void fragment() {4469ALBEDO = vec3(0.6);4470ROUGHNESS = 0.8;4471METALLIC = 0.2;4472}4473)");4474scene_globals.default_material = material_storage->material_allocate();4475material_storage->material_initialize(scene_globals.default_material);4476material_storage->material_set_shader(scene_globals.default_material, scene_globals.default_shader);4477default_material_data_ptr = static_cast<GLES3::SceneMaterialData *>(GLES3::MaterialStorage::get_singleton()->material_get_data(scene_globals.default_material, RS::SHADER_SPATIAL));4478}44794480{4481// Overdraw material and shader.4482scene_globals.overdraw_shader = material_storage->shader_allocate();4483material_storage->shader_initialize(scene_globals.overdraw_shader);4484material_storage->shader_set_code(scene_globals.overdraw_shader, R"(4485// 3D editor Overdraw debug draw mode shader (Compatibility).44864487shader_type spatial;44884489render_mode blend_add, unshaded, fog_disabled;44904491void fragment() {4492ALBEDO = vec3(0.4, 0.8, 0.8);4493ALPHA = 0.2;4494}4495)");4496scene_globals.overdraw_material = material_storage->material_allocate();4497material_storage->material_initialize(scene_globals.overdraw_material);4498material_storage->material_set_shader(scene_globals.overdraw_material, scene_globals.overdraw_shader);4499overdraw_material_data_ptr = static_cast<GLES3::SceneMaterialData *>(GLES3::MaterialStorage::get_singleton()->material_get_data(scene_globals.overdraw_material, RS::SHADER_SPATIAL));4500}45014502{4503// Initialize Sky stuff4504sky_globals.roughness_layers = GLOBAL_GET("rendering/reflections/sky_reflections/roughness_layers");45054506String global_defines;4507global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now4508global_defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(sky_globals.max_directional_lights) + "\n";4509material_storage->shaders.sky_shader.initialize(global_defines);4510sky_globals.shader_default_version = material_storage->shaders.sky_shader.version_create();4511}45124513{4514sky_globals.default_shader = material_storage->shader_allocate();45154516material_storage->shader_initialize(sky_globals.default_shader);45174518material_storage->shader_set_code(sky_globals.default_shader, R"(4519// Default sky shader.45204521shader_type sky;45224523void sky() {4524COLOR = vec3(0.0);4525}4526)");4527sky_globals.default_material = material_storage->material_allocate();4528material_storage->material_initialize(sky_globals.default_material);45294530material_storage->material_set_shader(sky_globals.default_material, sky_globals.default_shader);4531}4532{4533sky_globals.fog_shader = material_storage->shader_allocate();4534material_storage->shader_initialize(sky_globals.fog_shader);45354536material_storage->shader_set_code(sky_globals.fog_shader, R"(4537// Default clear color sky shader.45384539shader_type sky;45404541uniform vec4 clear_color;45424543void sky() {4544COLOR = clear_color.rgb;4545}4546)");4547sky_globals.fog_material = material_storage->material_allocate();4548material_storage->material_initialize(sky_globals.fog_material);45494550material_storage->material_set_shader(sky_globals.fog_material, sky_globals.fog_shader);4551}45524553{4554glGenVertexArrays(1, &sky_globals.screen_triangle_array);4555glBindVertexArray(sky_globals.screen_triangle_array);4556glGenBuffers(1, &sky_globals.screen_triangle);4557glBindBuffer(GL_ARRAY_BUFFER, sky_globals.screen_triangle);45584559const float qv[6] = {4560-1.0f,4561-1.0f,45623.0f,4563-1.0f,4564-1.0f,45653.0f,4566};45674568GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, sky_globals.screen_triangle, sizeof(float) * 6, qv, GL_STATIC_DRAW, "Screen triangle vertex buffer");45694570glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, nullptr);4571glEnableVertexAttribArray(RS::ARRAY_VERTEX);4572glBindVertexArray(0);4573glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind4574}45754576#ifdef GL_API_ENABLED4577if (RasterizerGLES3::is_gles_over_gl()) {4578glEnable(_EXT_TEXTURE_CUBE_MAP_SEAMLESS);4579}4580#endif // GL_API_ENABLED45814582// MultiMesh may read from color when color is disabled, so make sure that the color defaults to white instead of black;4583glVertexAttrib4f(RS::ARRAY_COLOR, 1.0, 1.0, 1.0, 1.0);4584}45854586RasterizerSceneGLES3::~RasterizerSceneGLES3() {4587GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.directional_light_buffer);4588GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.omni_light_buffer);4589GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.spot_light_buffer);4590GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.positional_shadow_buffer);4591GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.directional_shadow_buffer);4592memdelete_arr(scene_state.directional_lights);4593memdelete_arr(scene_state.omni_lights);4594memdelete_arr(scene_state.spot_lights);4595memdelete_arr(scene_state.omni_light_sort);4596memdelete_arr(scene_state.spot_light_sort);4597memdelete_arr(scene_state.positional_shadows);4598memdelete_arr(scene_state.directional_shadows);45994600// Scene Shader4601GLES3::MaterialStorage::get_singleton()->shaders.scene_shader.version_free(scene_globals.shader_default_version);4602RSG::material_storage->material_free(scene_globals.default_material);4603RSG::material_storage->shader_free(scene_globals.default_shader);46044605// Overdraw Shader4606RSG::material_storage->material_free(scene_globals.overdraw_material);4607RSG::material_storage->shader_free(scene_globals.overdraw_shader);46084609// Sky Shader4610GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_free(sky_globals.shader_default_version);4611RSG::material_storage->material_free(sky_globals.default_material);4612RSG::material_storage->shader_free(sky_globals.default_shader);4613RSG::material_storage->material_free(sky_globals.fog_material);4614RSG::material_storage->shader_free(sky_globals.fog_shader);4615GLES3::Utilities::get_singleton()->buffer_free_data(sky_globals.screen_triangle);4616glDeleteVertexArrays(1, &sky_globals.screen_triangle_array);4617GLES3::Utilities::get_singleton()->buffer_free_data(sky_globals.directional_light_buffer);4618memdelete_arr(sky_globals.directional_lights);4619memdelete_arr(sky_globals.last_frame_directional_lights);46204621// UBOs4622if (scene_state.ubo_buffer != 0) {4623GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.ubo_buffer);4624}46254626if (scene_state.prev_ubo_buffer != 0) {4627GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.prev_ubo_buffer);4628}46294630if (scene_state.multiview_buffer != 0) {4631GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.multiview_buffer);4632}46334634if (scene_state.prev_multiview_buffer != 0) {4635GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.prev_multiview_buffer);4636}46374638if (scene_state.tonemap_buffer != 0) {4639GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.tonemap_buffer);4640}46414642singleton = nullptr;4643}46444645#endif // GLES3_ENABLED464646474648