diff options
Diffstat (limited to 'drivers/gles3/rasterizer_scene_gles3.cpp')
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 462 |
1 files changed, 270 insertions, 192 deletions
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 1952efff0e..026ec85e6b 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -34,8 +34,8 @@ #include "servers/rendering/rendering_server_default.h" #include "servers/rendering/rendering_server_globals.h" #include "storage/config.h" -#include "storage/light_storage.h" #include "storage/mesh_storage.h" +#include "storage/particles_storage.h" #include "storage/texture_storage.h" #ifdef GLES3_ENABLED @@ -51,6 +51,9 @@ RenderGeometryInstance *RasterizerSceneGLES3::geometry_instance_create(RID p_bas ginstance->data->base = p_base; ginstance->data->base_type = type; + ginstance->data->dependency_tracker.userdata = ginstance; + ginstance->data->dependency_tracker.changed_callback = _geometry_instance_dependency_changed; + ginstance->data->dependency_tracker.deleted_callback = _geometry_instance_dependency_deleted; ginstance->_mark_dirty(); @@ -70,7 +73,7 @@ void RasterizerSceneGLES3::GeometryInstanceGLES3::pair_light_instances(const RID spot_lights.clear(); for (uint32_t i = 0; i < p_light_instance_count; i++) { - RS::LightType type = RasterizerSceneGLES3::get_singleton()->light_instance_get_type(p_light_instances[i]); + RS::LightType type = GLES3::LightStorage::get_singleton()->light_instance_get_type(p_light_instances[i]); switch (type) { case RS::LIGHT_OMNI: { if (omni_light_count < (uint32_t)config->max_lights_per_object) { @@ -315,6 +318,8 @@ void RasterizerSceneGLES3::_geometry_instance_add_surface(GeometryInstanceGLES3 void RasterizerSceneGLES3::_geometry_instance_update(RenderGeometryInstance *p_geometry_instance) { GLES3::MeshStorage *mesh_storage = GLES3::MeshStorage::get_singleton(); + GLES3::ParticlesStorage *particles_storage = GLES3::ParticlesStorage::get_singleton(); + GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_geometry_instance); if (ginstance->data->dirty_dependencies) { @@ -362,6 +367,26 @@ void RasterizerSceneGLES3::_geometry_instance_update(RenderGeometryInstance *p_g } break; case RS::INSTANCE_PARTICLES: { + int draw_passes = particles_storage->particles_get_draw_passes(ginstance->data->base); + + for (int j = 0; j < draw_passes; j++) { + RID mesh = particles_storage->particles_get_draw_pass_mesh(ginstance->data->base, j); + if (!mesh.is_valid()) { + continue; + } + + const RID *materials = nullptr; + uint32_t surface_count; + + materials = mesh_storage->mesh_get_surface_count_and_materials(mesh, surface_count); + if (materials) { + for (uint32_t k = 0; k < surface_count; k++) { + _geometry_instance_add_surface(ginstance, k, materials[k], mesh); + } + } + } + + ginstance->instance_count = particles_storage->particles_get_amount(ginstance->data->base); } break; default: { @@ -383,9 +408,17 @@ void RasterizerSceneGLES3::_geometry_instance_update(RenderGeometryInstance *p_g ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA; } - //ginstance->transforms_uniform_set = mesh_storage->multimesh_get_3d_uniform_set(ginstance->data->base, scene_globals.default_shader_rd, TRANSFORMS_UNIFORM_SET); - } else if (ginstance->data->base_type == RS::INSTANCE_PARTICLES) { + ginstance->base_flags |= INSTANCE_DATA_FLAG_PARTICLES; + ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH; + + ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR; + ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA; + + if (!particles_storage->particles_is_using_local_coords(ginstance->data->base)) { + store_transform = false; + } + } else if (ginstance->data->base_type == RS::INSTANCE_MESH) { } @@ -399,32 +432,6 @@ void RasterizerSceneGLES3::_geometry_instance_update(RenderGeometryInstance *p_g ginstance->dirty_list_element.remove_from_list(); } -/* SHADOW ATLAS API */ - -RID RasterizerSceneGLES3::shadow_atlas_create() { - return RID(); -} - -void RasterizerSceneGLES3::shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits) { -} - -void RasterizerSceneGLES3::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) { -} - -bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) { - return false; -} - -void RasterizerSceneGLES3::directional_shadow_atlas_set_size(int p_size, bool p_16_bits) { -} - -int RasterizerSceneGLES3::get_directional_light_shadow_size(RID p_light_intance) { - return 0; -} - -void RasterizerSceneGLES3::set_directional_shadow_count(int p_count) { -} - /* SKY API */ void RasterizerSceneGLES3::_free_sky_data(Sky *p_sky) { @@ -622,10 +629,11 @@ void RasterizerSceneGLES3::_setup_sky(const RenderDataGLES3 *p_render_data, cons sky->reflection_dirty = true; } + glBindBufferBase(GL_UNIFORM_BUFFER, SKY_DIRECTIONAL_LIGHT_UNIFORM_LOCATION, sky_globals.directional_light_buffer); if (shader_data->uses_light) { sky_globals.directional_light_count = 0; for (int i = 0; i < (int)p_lights.size(); i++) { - LightInstance *li = light_instance_owner.get_or_null(p_lights[i]); + GLES3::LightInstance *li = GLES3::LightStorage::get_singleton()->get_light_instance(p_lights[i]); if (!li) { continue; } @@ -705,7 +713,6 @@ void RasterizerSceneGLES3::_setup_sky(const RenderDataGLES3 *p_render_data, cons } if (light_data_dirty) { - glBindBufferBase(GL_UNIFORM_BUFFER, SKY_DIRECTIONAL_LIGHT_UNIFORM_LOCATION, sky_globals.directional_light_buffer); glBufferData(GL_UNIFORM_BUFFER, sizeof(DirectionalLightData) * sky_globals.max_directional_lights, sky_globals.directional_lights, GL_STREAM_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); @@ -737,7 +744,6 @@ void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection, RS::EnvironmentBG background = environment_get_background(p_env); if (sky) { - ERR_FAIL_COND(!sky); sky_material = sky->material; if (sky_material.is_valid()) { @@ -779,12 +785,16 @@ void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection, sky_transform.invert(); sky_transform = p_transform.basis * sky_transform; - GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_bind_shader(shader_data->version, SkyShaderGLES3::MODE_BACKGROUND); - GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::ORIENTATION, sky_transform, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND); - GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::PROJECTION, camera.matrix[2][0], camera.matrix[0][0], camera.matrix[2][1], camera.matrix[1][1], shader_data->version, SkyShaderGLES3::MODE_BACKGROUND); - GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::POSITION, p_transform.origin, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND); - GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::TIME, time, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND); - GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, p_luminance_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND); + bool success = material_storage->shaders.sky_shader.version_bind_shader(shader_data->version, SkyShaderGLES3::MODE_BACKGROUND); + if (!success) { + return; + } + + material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::ORIENTATION, sky_transform, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND); + material_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); + material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::POSITION, p_transform.origin, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND); + material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::TIME, time, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND); + material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, p_luminance_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND); glBindVertexArray(sky_globals.screen_triangle_array); glDrawArrays(GL_TRIANGLES, 0, 3); @@ -875,15 +885,18 @@ void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_p Projection cm; cm.set_perspective(90, 1, 0.01, 10.0); Projection correction; - correction.set_depth_correction(true); + correction.columns[1][1] = -1.0; cm = correction * cm; - GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_bind_shader(shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); + bool success = material_storage->shaders.sky_shader.version_bind_shader(shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); + if (!success) { + return; + } - GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::POSITION, p_transform.origin, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); - GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::TIME, time, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); - GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::PROJECTION, cm.matrix[2][0], cm.matrix[0][0], cm.matrix[2][1], cm.matrix[1][1], shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); - GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, p_luminance_multiplier, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); + material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::POSITION, p_transform.origin, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); + material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::TIME, time, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); + material_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); + material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, p_luminance_multiplier, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); glBindVertexArray(sky_globals.screen_triangle_array); @@ -892,7 +905,7 @@ void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_p for (int i = 0; i < 6; i++) { Basis local_view = Basis::looking_at(view_normals[i], view_up[i]); - GLES3::MaterialStorage::get_singleton()->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::ORIENTATION, local_view, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); + material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::ORIENTATION, local_view, shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, sky->raw_radiance, 0); glDrawArrays(GL_TRIANGLES, 0, 3); } @@ -973,7 +986,10 @@ void RasterizerSceneGLES3::_filter_sky_radiance(Sky *p_sky, int p_base_layer) { glViewport(0, 0, size, size); glBindVertexArray(sky_globals.screen_triangle_array); - material_storage->shaders.cubemap_filter_shader.version_bind_shader(scene_globals.cubemap_filter_shader_version, mode); + bool success = material_storage->shaders.cubemap_filter_shader.version_bind_shader(scene_globals.cubemap_filter_shader_version, mode); + if (!success) { + return; + } if (p_base_layer > 0) { const uint32_t sample_counts[4] = { 1, sky_globals.ggx_samples / 4, sky_globals.ggx_samples / 2, sky_globals.ggx_samples }; @@ -1085,38 +1101,6 @@ void RasterizerSceneGLES3::positional_soft_shadow_filter_set_quality(RS::ShadowQ void RasterizerSceneGLES3::directional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) { } -RID RasterizerSceneGLES3::light_instance_create(RID p_light) { - RID li = light_instance_owner.make_rid(LightInstance()); - - LightInstance *light_instance = light_instance_owner.get_or_null(li); - - light_instance->self = li; - light_instance->light = p_light; - light_instance->light_type = RSG::light_storage->light_get_type(p_light); - - return li; -} - -void RasterizerSceneGLES3::light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) { - LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance); - ERR_FAIL_COND(!light_instance); - - light_instance->transform = p_transform; -} - -void RasterizerSceneGLES3::light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) { - LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance); - ERR_FAIL_COND(!light_instance); - - light_instance->aabb = p_aabb; -} - -void RasterizerSceneGLES3::light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) { -} - -void RasterizerSceneGLES3::light_instance_mark_visible(RID p_light_instance) { -} - RID RasterizerSceneGLES3::fog_volume_instance_create(RID p_fog_volume) { return RID(); } @@ -1135,57 +1119,6 @@ Vector3 RasterizerSceneGLES3::fog_volume_instance_get_position(RID p_fog_volume_ return Vector3(); } -RID RasterizerSceneGLES3::reflection_atlas_create() { - return RID(); -} - -int RasterizerSceneGLES3::reflection_atlas_get_size(RID p_ref_atlas) const { - return 0; -} - -void RasterizerSceneGLES3::reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) { -} - -RID RasterizerSceneGLES3::reflection_probe_instance_create(RID p_probe) { - return RID(); -} - -void RasterizerSceneGLES3::reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) { -} - -void RasterizerSceneGLES3::reflection_probe_release_atlas_index(RID p_instance) { -} - -bool RasterizerSceneGLES3::reflection_probe_instance_needs_redraw(RID p_instance) { - return false; -} - -bool RasterizerSceneGLES3::reflection_probe_instance_has_reflection(RID p_instance) { - return false; -} - -bool RasterizerSceneGLES3::reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) { - return false; -} - -bool RasterizerSceneGLES3::reflection_probe_instance_postprocess_step(RID p_instance) { - return true; -} - -RID RasterizerSceneGLES3::decal_instance_create(RID p_decal) { - return RID(); -} - -void RasterizerSceneGLES3::decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) { -} - -RID RasterizerSceneGLES3::lightmap_instance_create(RID p_lightmap) { - return RID(); -} - -void RasterizerSceneGLES3::lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) { -} - RID RasterizerSceneGLES3::voxel_gi_instance_create(RID p_voxel_gi) { return RID(); } @@ -1258,13 +1191,13 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const if (inst->omni_light_count) { inst->omni_light_gl_cache.resize(inst->omni_light_count); for (uint32_t j = 0; j < inst->omni_light_count; j++) { - inst->omni_light_gl_cache[j] = light_instance_get_gl_id(inst->omni_lights[j]); + inst->omni_light_gl_cache[j] = GLES3::LightStorage::get_singleton()->light_instance_get_gl_id(inst->omni_lights[j]); } } if (inst->spot_light_count) { inst->spot_light_gl_cache.resize(inst->spot_light_count); for (uint32_t j = 0; j < inst->spot_light_count; j++) { - inst->spot_light_gl_cache[j] = light_instance_get_gl_id(inst->spot_lights[j]); + inst->spot_light_gl_cache[j] = GLES3::LightStorage::get_singleton()->light_instance_get_gl_id(inst->spot_lights[j]); } } } @@ -1277,12 +1210,13 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const // LOD if (p_render_data->screen_mesh_lod_threshold > 0.0 && mesh_storage->mesh_surface_has_lod(surf->surface)) { - //lod - Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_render_data->lod_camera_plane.normal); - Vector3 lod_support_max = inst->transformed_aabb.get_support(p_render_data->lod_camera_plane.normal); + // Get the LOD support points on the mesh AABB. + Vector3 lod_support_min = inst->transformed_aabb.get_support(p_render_data->cam_transform.basis.get_column(Vector3::AXIS_Z)); + Vector3 lod_support_max = inst->transformed_aabb.get_support(-p_render_data->cam_transform.basis.get_column(Vector3::AXIS_Z)); - float distance_min = p_render_data->lod_camera_plane.distance_to(lod_support_min); - float distance_max = p_render_data->lod_camera_plane.distance_to(lod_support_max); + // Get the distances to those points on the AABB from the camera origin. + float distance_min = (float)p_render_data->cam_transform.origin.distance_to(lod_support_min); + float distance_max = (float)p_render_data->cam_transform.origin.distance_to(lod_support_max); float distance = 0.0; @@ -1299,8 +1233,8 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const distance = 1.0; } - uint32_t indices; - surf->lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, &indices); + uint32_t indices = 0; + surf->lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, indices); /* if (p_render_data->render_info) { indices = _indices_to_primitives(surf->primitive, indices); @@ -1375,7 +1309,7 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const // Needs to be called after _setup_lights so that directional_light_count is accurate. void 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) { Projection correction; - correction.set_depth_correction(p_flip_y); + correction.columns[1][1] = p_flip_y ? -1.0 : 1.0; Projection projection = correction * p_render_data->cam_projection; //store camera into ubo GLES3::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix); @@ -1383,6 +1317,19 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da GLES3::MaterialStorage::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix); GLES3::MaterialStorage::store_transform(p_render_data->inv_cam_transform, scene_state.ubo.view_matrix); + if (p_render_data->view_count > 1) { + for (uint32_t v = 0; v < p_render_data->view_count; v++) { + projection = correction * p_render_data->view_projection[v]; + GLES3::MaterialStorage::store_camera(projection, scene_state.multiview_ubo.projection_matrix_view[v]); + GLES3::MaterialStorage::store_camera(projection.inverse(), scene_state.multiview_ubo.inv_projection_matrix_view[v]); + + scene_state.multiview_ubo.eye_offset[v][0] = p_render_data->view_eye_offset[v].x; + scene_state.multiview_ubo.eye_offset[v][1] = p_render_data->view_eye_offset[v].y; + scene_state.multiview_ubo.eye_offset[v][2] = p_render_data->view_eye_offset[v].z; + scene_state.multiview_ubo.eye_offset[v][3] = 0.0; + } + } + scene_state.ubo.directional_light_count = p_render_data->directional_light_count; scene_state.ubo.z_far = p_render_data->z_far; @@ -1484,6 +1431,15 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_DATA_UNIFORM_LOCATION, scene_state.ubo_buffer); glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::UBO), &scene_state.ubo, GL_STREAM_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); + + if (p_render_data->view_count > 1) { + if (scene_state.multiview_buffer == 0) { + glGenBuffers(1, &scene_state.multiview_buffer); + } + glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer); + glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::MultiviewUBO), &scene_state.multiview_ubo, GL_STREAM_DRAW); + glBindBuffer(GL_UNIFORM_BUFFER, 0); + } } // Puts lights into Uniform Buffers. Needs to be called before _fill_list as this caches the index of each light in the Uniform Buffer @@ -1502,7 +1458,7 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b int num_lights = lights.size(); for (int i = 0; i < num_lights; i++) { - LightInstance *li = light_instance_owner.get_or_null(lights[i]); + GLES3::LightInstance *li = GLES3::LightStorage::get_singleton()->get_light_instance(lights[i]); if (!li) { continue; } @@ -1607,12 +1563,12 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b } if (r_omni_light_count) { - SortArray<InstanceSort<LightInstance>> sorter; + SortArray<InstanceSort<GLES3::LightInstance>> sorter; sorter.sort(scene_state.omni_light_sort, r_omni_light_count); } if (r_spot_light_count) { - SortArray<InstanceSort<LightInstance>> sorter; + SortArray<InstanceSort<GLES3::LightInstance>> sorter; sorter.sort(scene_state.spot_light_sort, r_spot_light_count); } @@ -1620,7 +1576,7 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b uint32_t index = (i < r_omni_light_count) ? i : i - (r_omni_light_count); LightData &light_data = (i < r_omni_light_count) ? scene_state.omni_lights[index] : scene_state.spot_lights[index]; RS::LightType type = (i < r_omni_light_count) ? RS::LIGHT_OMNI : RS::LIGHT_SPOT; - LightInstance *li = (i < r_omni_light_count) ? scene_state.omni_light_sort[index].instance : scene_state.spot_light_sort[index].instance; + GLES3::LightInstance *li = (i < r_omni_light_count) ? scene_state.omni_light_sort[index].instance : scene_state.spot_light_sort[index].instance; RID base = li->light; Transform3D light_transform = li->transform; @@ -1719,7 +1675,7 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b glBindBuffer(GL_UNIFORM_BUFFER, 0); } -void 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_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, RendererScene::RenderInfo *r_render_info) { +void 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_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) { GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); GLES3::Config *config = GLES3::Config::get_singleton(); RENDER_TIMESTAMP("Setup 3D Scene"); @@ -1730,6 +1686,9 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ ERR_FAIL_COND(rb.is_null()); } + GLES3::RenderTarget *rt = texture_storage->get_render_target(rb->render_target); + ERR_FAIL_COND(!rt); + // Assign render data // Use the format from rendererRD RenderDataGLES3 render_data; @@ -1761,7 +1720,6 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ // this should be the same for all cameras.. render_data.lod_distance_multiplier = p_camera_data->main_projection.get_lod_multiplier(); - render_data.lod_camera_plane = Plane(-p_camera_data->main_transform.basis.get_column(Vector3::AXIS_Z), p_camera_data->main_transform.get_origin()); if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) { render_data.screen_mesh_lod_threshold = 0.0; @@ -1818,8 +1776,20 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ scene_state.ubo.emissive_exposure_normalization = -1.0; // Use default exposure normalization. + bool flip_y = !render_data.reflection_probe.is_valid(); + + if (rt->overridden.color.is_valid()) { + // If we've overridden the render target's color texture, then don't render upside down. + // We're probably rendering directly to an XR device. + flip_y = false; + } + if (!flip_y) { + // If we're rendering right-side up, then we need to change the winding order. + glFrontFace(GL_CW); + } + _setup_lights(&render_data, false, render_data.directional_light_count, render_data.omni_light_count, render_data.spot_light_count); - _setup_environment(&render_data, render_data.reflection_probe.is_valid(), screen_size, !render_data.reflection_probe.is_valid(), clear_color, false); + _setup_environment(&render_data, render_data.reflection_probe.is_valid(), screen_size, flip_y, clear_color, false); _fill_render_list(RENDER_LIST_OPAQUE, &render_data, PASS_MODE_COLOR); render_list[RENDER_LIST_OPAQUE].sort_by_key(); @@ -1881,7 +1851,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ Projection projection = render_data.cam_projection; if (render_data.reflection_probe.is_valid()) { Projection correction; - correction.set_depth_correction(true); + correction.columns[1][1] = -1.0; projection = correction * render_data.cam_projection; } @@ -1900,7 +1870,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ } } - glBindFramebuffer(GL_FRAMEBUFFER, rb->framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo); glViewport(0, 0, rb->width, rb->height); // Do depth prepass if it's explicitly enabled @@ -1925,8 +1895,11 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ glColorMask(0, 0, 0, 0); glClearDepth(1.0f); glClear(GL_DEPTH_BUFFER_BIT); + uint32_t spec_constant = SceneShaderGLES3::DISABLE_FOG | SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL | + SceneShaderGLES3::DISABLE_LIGHTMAP | SceneShaderGLES3::DISABLE_LIGHT_OMNI | + SceneShaderGLES3::DISABLE_LIGHT_SPOT; - RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, 0, use_wireframe); + RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, spec_constant, use_wireframe); _render_list_template<PASS_MODE_DEPTH>(&render_list_params, &render_data, 0, render_list[RENDER_LIST_OPAQUE].elements.size()); glColorMask(1, 1, 1, 1); @@ -1968,11 +1941,11 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ { // Specialization Constants that apply for entire rendering pass. if (render_data.directional_light_count == 0) { - spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_DIRECTIONAL_LIGHTS; + spec_constant_base_flags |= SceneShaderGLES3::DISABLE_LIGHT_DIRECTIONAL; } if (render_data.environment.is_null() || (render_data.environment.is_valid() && !environment_get_fog_enabled(render_data.environment))) { - spec_constant_base_flags |= 1 << SPEC_CONSTANT_DISABLE_FOG; + spec_constant_base_flags |= SceneShaderGLES3::DISABLE_FOG; } } // Render Opaque Objects. @@ -2006,6 +1979,11 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ _render_list_template<PASS_MODE_COLOR_TRANSPARENT>(&render_list_params_alpha, &render_data, 0, render_list[RENDER_LIST_ALPHA].elements.size(), true); + if (!flip_y) { + // Restore the default winding order. + glFrontFace(GL_CCW); + } + if (rb.is_valid()) { _render_buffers_debug_draw(rb, p_shadow_atlas, p_occluder_debug_tex); } @@ -2016,6 +1994,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ template <PassMode p_pass_mode> void 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) { GLES3::MeshStorage *mesh_storage = GLES3::MeshStorage::get_singleton(); + GLES3::ParticlesStorage *particles_storage = GLES3::ParticlesStorage::get_singleton(); GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); GLES3::Config *config = GLES3::Config::get_singleton(); @@ -2027,8 +2006,13 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, GLES3::SceneShaderData *prev_shader = nullptr; GeometryInstanceGLES3 *prev_inst = nullptr; SceneShaderGLES3::ShaderVariant prev_variant = SceneShaderGLES3::ShaderVariant::MODE_COLOR; + SceneShaderGLES3::ShaderVariant shader_variant = SceneShaderGLES3::MODE_COLOR; // Assigned to silence wrong -Wmaybe-initialized + + uint32_t base_spec_constants = p_params->spec_constant_base_flags; - SceneShaderGLES3::ShaderVariant shader_variant = SceneShaderGLES3::MODE_COLOR; // Assigned to silence wrong -Wmaybe-initialized. + if (p_render_data->view_count > 1) { + base_spec_constants |= SceneShaderGLES3::USE_MULTIVIEW; + } switch (p_pass_mode) { case PASS_MODE_COLOR: @@ -2043,19 +2027,21 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, } break; } - if (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) { + if constexpr (p_pass_mode == PASS_MODE_COLOR || p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) { glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 2); GLuint texture_to_bind = texture_storage->get_texture(texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_CUBEMAP_BLACK))->tex_id; if (p_render_data->environment.is_valid()) { Sky *sky = sky_owner.get_or_null(environment_get_sky(p_render_data->environment)); if (sky && sky->radiance != 0) { texture_to_bind = sky->radiance; - // base_spec_constant |= USE_RADIANCE_MAP; + base_spec_constants |= SceneShaderGLES3::USE_RADIANCE_MAP; } glBindTexture(GL_TEXTURE_CUBE_MAP, texture_to_bind); } } + bool should_request_redraw = false; + for (uint32_t i = p_from_element; i < p_to_element; i++) { const GeometryInstanceSurface *surf = p_params->elements[i]; GeometryInstanceGLES3 *inst = surf->owner; @@ -2068,13 +2054,11 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, continue; } - //uint32_t base_spec_constants = p_params->spec_constant_base_flags; - GLES3::SceneShaderData *shader; GLES3::SceneMaterialData *material_data; void *mesh_surface; - if (p_pass_mode == PASS_MODE_SHADOW) { + if constexpr (p_pass_mode == PASS_MODE_SHADOW) { shader = surf->shader_shadow; material_data = surf->material_shadow; mesh_surface = surf->surface_shadow; @@ -2088,7 +2072,12 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, continue; } - if (p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) { + //request a redraw if one of the shaders uses TIME + if (shader->uses_time) { + should_request_redraw = true; + } + + if constexpr (p_pass_mode == PASS_MODE_COLOR_TRANSPARENT) { if (scene_state.current_depth_test != shader->depth_test) { if (shader->depth_test == GLES3::SceneShaderData::DEPTH_TEST_DISABLED) { glDisable(GL_DEPTH_TEST); @@ -2115,9 +2104,9 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, scene_state.current_depth_draw = shader->depth_draw; } - if (p_pass_mode == PASS_MODE_COLOR_TRANSPARENT || p_pass_mode == PASS_MODE_COLOR_ADDITIVE) { + if constexpr (p_pass_mode == PASS_MODE_COLOR_TRANSPARENT || p_pass_mode == PASS_MODE_COLOR_ADDITIVE) { GLES3::SceneShaderData::BlendMode desired_blend_mode; - if (p_pass_mode == PASS_MODE_COLOR_ADDITIVE) { + if constexpr (p_pass_mode == PASS_MODE_COLOR_ADDITIVE) { desired_blend_mode = GLES3::SceneShaderData::BLEND_MODE_ADD; } else { desired_blend_mode = shader->blend_mode; @@ -2215,7 +2204,7 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, } bool use_index_buffer = index_array_gl != 0; - if (prev_index_array_gl != index_array_gl) { + if (prev_index_array_gl != index_array_gl || prev_vertex_array_gl != vertex_array_gl) { if (index_array_gl != 0) { // Bind index each time so we can use LODs glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_gl); @@ -2235,19 +2224,24 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, SceneShaderGLES3::ShaderVariant instance_variant = shader_variant; if (inst->instance_count > 0) { + // Will need to use instancing to draw (either MultiMesh or Particles). instance_variant = SceneShaderGLES3::ShaderVariant(1 + int(shader_variant)); } if (prev_shader != shader || prev_variant != instance_variant) { - material_storage->shaders.scene_shader.version_bind_shader(shader->version, instance_variant); + bool success = material_storage->shaders.scene_shader.version_bind_shader(shader->version, instance_variant, base_spec_constants); + if (!success) { + continue; + } + float opaque_prepass_threshold = 0.0; - if (p_pass_mode == PASS_MODE_DEPTH) { + if constexpr (p_pass_mode == PASS_MODE_DEPTH) { opaque_prepass_threshold = 0.99; - } else if (p_pass_mode == PASS_MODE_SHADOW) { + } else if constexpr (p_pass_mode == PASS_MODE_SHADOW) { opaque_prepass_threshold = 0.1; } - material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::OPAQUE_PREPASS_THRESHOLD, opaque_prepass_threshold, shader->version, instance_variant); + material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::OPAQUE_PREPASS_THRESHOLD, opaque_prepass_threshold, shader->version, instance_variant, base_spec_constants); prev_shader = shader; prev_variant = instance_variant; @@ -2255,41 +2249,58 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, if (prev_inst != inst || prev_shader != shader || prev_variant != instance_variant) { // Rebind the light indices. - material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::OMNI_LIGHT_COUNT, inst->omni_light_count, shader->version, instance_variant); - material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::SPOT_LIGHT_COUNT, inst->spot_light_count, shader->version, instance_variant); + material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::OMNI_LIGHT_COUNT, inst->omni_light_count, shader->version, instance_variant, base_spec_constants); + material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::SPOT_LIGHT_COUNT, inst->spot_light_count, shader->version, instance_variant, base_spec_constants); if (inst->omni_light_count) { - glUniform1uiv(material_storage->shaders.scene_shader.version_get_uniform(SceneShaderGLES3::OMNI_LIGHT_INDICES, shader->version, instance_variant), inst->omni_light_count, inst->omni_light_gl_cache.ptr()); + glUniform1uiv(material_storage->shaders.scene_shader.version_get_uniform(SceneShaderGLES3::OMNI_LIGHT_INDICES, shader->version, instance_variant, base_spec_constants), inst->omni_light_count, inst->omni_light_gl_cache.ptr()); } if (inst->spot_light_count) { - glUniform1uiv(material_storage->shaders.scene_shader.version_get_uniform(SceneShaderGLES3::SPOT_LIGHT_INDICES, shader->version, instance_variant), inst->spot_light_count, inst->spot_light_gl_cache.ptr()); + glUniform1uiv(material_storage->shaders.scene_shader.version_get_uniform(SceneShaderGLES3::SPOT_LIGHT_INDICES, shader->version, instance_variant, base_spec_constants), inst->spot_light_count, inst->spot_light_gl_cache.ptr()); } prev_inst = inst; } - material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, world_transform, shader->version, instance_variant); + material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, world_transform, shader->version, instance_variant, base_spec_constants); if (inst->instance_count > 0) { - // Using MultiMesh. + // Using MultiMesh or Particles. // Bind instance buffers. - GLuint multimesh_buffer = mesh_storage->multimesh_get_gl_buffer(inst->data->base); - glBindBuffer(GL_ARRAY_BUFFER, multimesh_buffer); - uint32_t multimesh_stride = mesh_storage->multimesh_get_stride(inst->data->base); + GLuint instance_buffer = 0; + uint32_t stride = 0; + if (inst->flags_cache & INSTANCE_DATA_FLAG_PARTICLES) { + instance_buffer = particles_storage->particles_get_gl_buffer(inst->data->base); + stride = 16; // 12 bytes for instance transform and 4 bytes for packed color and custom. + } else { + instance_buffer = mesh_storage->multimesh_get_gl_buffer(inst->data->base); + stride = mesh_storage->multimesh_get_stride(inst->data->base); + } + + if (instance_buffer == 0) { + // Instance buffer not initialized yet. Skip rendering for now. + continue; + } + + glBindBuffer(GL_ARRAY_BUFFER, instance_buffer); + glEnableVertexAttribArray(12); - glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, multimesh_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(0)); + glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(0)); glVertexAttribDivisor(12, 1); glEnableVertexAttribArray(13); - glVertexAttribPointer(13, 4, GL_FLOAT, GL_FALSE, multimesh_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(4 * 4)); + glVertexAttribPointer(13, 4, GL_FLOAT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4)); glVertexAttribDivisor(13, 1); - glEnableVertexAttribArray(14); - glVertexAttribPointer(14, 4, GL_FLOAT, GL_FALSE, multimesh_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(4 * 8)); - glVertexAttribDivisor(14, 1); + if (!(inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D)) { + glEnableVertexAttribArray(14); + glVertexAttribPointer(14, 4, GL_FLOAT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(sizeof(float) * 8)); + glVertexAttribDivisor(14, 1); + } - if (mesh_storage->multimesh_uses_colors(inst->data->base) || mesh_storage->multimesh_uses_custom_data(inst->data->base)) { + if ((inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR) || (inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA)) { + uint32_t color_custom_offset = inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D ? 8 : 12; glEnableVertexAttribArray(15); - glVertexAttribIPointer(15, 4, GL_UNSIGNED_INT, multimesh_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(mesh_storage->multimesh_get_color_offset(inst->data->base) * sizeof(float))); + glVertexAttribIPointer(15, 4, GL_UNSIGNED_INT, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(color_custom_offset * sizeof(float))); glVertexAttribDivisor(15, 1); } if (use_index_buffer) { @@ -2312,12 +2323,83 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, glDisableVertexAttribArray(15); } } + + // Make the actual redraw request + if (should_request_redraw) { + RenderingServerDefault::redraw_request(); + } } void 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) { } void RasterizerSceneGLES3::render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) { + GLES3::ParticlesStorage *particles_storage = GLES3::ParticlesStorage::get_singleton(); + + ERR_FAIL_COND(!particles_storage->particles_collision_is_heightfield(p_collider)); + Vector3 extents = particles_storage->particles_collision_get_extents(p_collider) * p_transform.basis.get_scale(); + Projection cm; + cm.set_orthogonal(-extents.x, extents.x, -extents.z, extents.z, 0, extents.y * 2.0); + + Vector3 cam_pos = p_transform.origin; + cam_pos.y += extents.y; + + Transform3D cam_xform; + cam_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()); + + GLuint fb = particles_storage->particles_collision_get_heightfield_framebuffer(p_collider); + Size2i fb_size = particles_storage->particles_collision_get_heightfield_size(p_collider); + + RENDER_TIMESTAMP("Setup GPUParticlesCollisionHeightField3D"); + + RenderDataGLES3 render_data; + + render_data.cam_projection = cm; + render_data.cam_transform = cam_xform; + render_data.view_projection[0] = cm; + render_data.inv_cam_transform = render_data.cam_transform.affine_inverse(); + render_data.cam_orthogonal = true; + render_data.z_near = 0.0; + render_data.z_far = cm.get_z_far(); + + render_data.instances = &p_instances; + + _setup_environment(&render_data, true, Vector2(fb_size), true, Color(), false); + + PassMode pass_mode = PASS_MODE_SHADOW; + + _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode); + render_list[RENDER_LIST_SECONDARY].sort_by_key(); + + RENDER_TIMESTAMP("Render Collider Heightfield"); + + glBindFramebuffer(GL_FRAMEBUFFER, fb); + glViewport(0, 0, fb_size.width, fb_size.height); + + GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_shader_parameters_get_uniform_buffer(); + + glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_GLOBALS_UNIFORM_LOCATION, global_buffer); + glBindBuffer(GL_UNIFORM_BUFFER, 0); + + glDisable(GL_BLEND); + glDepthMask(GL_TRUE); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + glDisable(GL_SCISSOR_TEST); + glCullFace(GL_BACK); + glEnable(GL_CULL_FACE); + scene_state.cull_mode = GLES3::SceneShaderData::CULL_BACK; + + glColorMask(0, 0, 0, 0); + glClearDepth(1.0f); + glClear(GL_DEPTH_BUFFER_BIT); + + RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), false, 31, false); + + _render_list_template<PASS_MODE_SHADOW>(&render_list_params, &render_data, 0, render_list[RENDER_LIST_SECONDARY].elements.size()); + + glColorMask(1, 1, 1, 1); + glBindFramebuffer(GL_FRAMEBUFFER, 0); } void RasterizerSceneGLES3::set_time(double p_time, double p_step) { @@ -2391,10 +2473,8 @@ bool RasterizerSceneGLES3::free(RID p_rid) { ERR_FAIL_COND_V(!sky, false); _free_sky_data(sky); sky_owner.free(p_rid); - } else if (light_instance_owner.owns(p_rid)) { - LightInstance *light_instance = light_instance_owner.get_or_null(p_rid); - ERR_FAIL_COND_V(!light_instance, false); - light_instance_owner.free(p_rid); + } else if (GLES3::LightStorage::get_singleton()->owns_light_instance(p_rid)) { + GLES3::LightStorage::get_singleton()->light_instance_free(p_rid); } else if (RSG::camera_attributes->owns_camera_attributes(p_rid)) { //not much to delete, just free it RSG::camera_attributes->camera_attributes_free(p_rid); @@ -2434,13 +2514,13 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() { uint32_t light_buffer_size = config->max_renderable_lights * sizeof(LightData); scene_state.omni_lights = memnew_arr(LightData, config->max_renderable_lights); - scene_state.omni_light_sort = memnew_arr(InstanceSort<LightInstance>, config->max_renderable_lights); + scene_state.omni_light_sort = memnew_arr(InstanceSort<GLES3::LightInstance>, config->max_renderable_lights); glGenBuffers(1, &scene_state.omni_light_buffer); glBindBuffer(GL_UNIFORM_BUFFER, scene_state.omni_light_buffer); glBufferData(GL_UNIFORM_BUFFER, light_buffer_size, nullptr, GL_STREAM_DRAW); scene_state.spot_lights = memnew_arr(LightData, config->max_renderable_lights); - scene_state.spot_light_sort = memnew_arr(InstanceSort<LightInstance>, config->max_renderable_lights); + scene_state.spot_light_sort = memnew_arr(InstanceSort<GLES3::LightInstance>, config->max_renderable_lights); glGenBuffers(1, &scene_state.spot_light_buffer); glBindBuffer(GL_UNIFORM_BUFFER, scene_state.spot_light_buffer); glBufferData(GL_UNIFORM_BUFFER, light_buffer_size, nullptr, GL_STREAM_DRAW); @@ -2470,7 +2550,7 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() { global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now global_defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(config->max_renderable_lights) + "\n"; global_defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(MAX_DIRECTIONAL_LIGHTS) + "\n"; - global_defines += "\n#define MAX_FORWARD_LIGHTS " + itos(config->max_lights_per_object) + "\n"; + global_defines += "\n#define MAX_FORWARD_LIGHTS uint(" + itos(config->max_lights_per_object) + ")\n"; material_storage->shaders.scene_shader.initialize(global_defines); scene_globals.shader_default_version = material_storage->shaders.scene_shader.version_create(); material_storage->shaders.scene_shader.version_bind_shader(scene_globals.shader_default_version, SceneShaderGLES3::MODE_COLOR); @@ -2481,7 +2561,7 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() { scene_globals.default_shader = material_storage->shader_allocate(); material_storage->shader_initialize(scene_globals.default_shader); material_storage->shader_set_code(scene_globals.default_shader, R"( -// Default 3D material shader (clustered). +// Default 3D material shader. shader_type spatial; @@ -2510,7 +2590,6 @@ void fragment() { global_defines += "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(sky_globals.max_directional_lights) + "\n"; material_storage->shaders.sky_shader.initialize(global_defines); sky_globals.shader_default_version = material_storage->shaders.sky_shader.version_create(); - material_storage->shaders.sky_shader.version_bind_shader(sky_globals.shader_default_version, SkyShaderGLES3::MODE_BACKGROUND); } { @@ -2518,7 +2597,6 @@ void fragment() { global_defines += "\n#define MAX_SAMPLE_COUNT " + itos(sky_globals.ggx_samples) + "\n"; material_storage->shaders.cubemap_filter_shader.initialize(global_defines); scene_globals.cubemap_filter_shader_version = material_storage->shaders.cubemap_filter_shader.version_create(); - material_storage->shaders.cubemap_filter_shader.version_bind_shader(scene_globals.cubemap_filter_shader_version, CubemapFilterShaderGLES3::MODE_DEFAULT); } { |