From 2c49923c3935d45c43a974aef903a466898b664a Mon Sep 17 00:00:00 2001 From: Bastiaan Olij Date: Wed, 25 Feb 2026 21:02:25 +1100 Subject: [PATCH] Cleanup projection code so we don't need our frustum override in the renderer --- drivers/gles3/rasterizer_scene_gles3.cpp | 18 ++---------------- drivers/gles3/rasterizer_scene_gles3.h | 1 - drivers/gles3/shaders/sky.glsl | 2 +- .../rendering/renderer_rd/environment/sky.cpp | 4 ---- .../renderer_rd/renderer_scene_render_rd.cpp | 1 - .../renderer_rd/shaders/environment/sky.glsl | 4 ++-- .../storage_rd/render_scene_data_rd.h | 1 - servers/rendering/renderer_scene_cull.cpp | 12 +++++------- servers/rendering/renderer_scene_render.cpp | 6 ++---- servers/rendering/renderer_scene_render.h | 5 ++--- 10 files changed, 14 insertions(+), 40 deletions(-) diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 94b8a1c002..aea2f232c5 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -860,7 +860,7 @@ void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection, } Projection correction; - correction.set_depth_correction(false, true, false); + correction.set_depth_correction(p_flip_y, true, false); camera = correction * camera; Basis sky_transform = environment_get_sky_orientation(p_env); @@ -985,7 +985,7 @@ 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, true, false); + correction.set_depth_correction(false, true, false); cm = correction * cm; bool success = material_storage->shaders.sky_shader.version_bind_shader(shader_data->version, SkyShaderGLES3::MODE_CUBEMAP); @@ -2321,7 +2321,6 @@ void RasterizerSceneGLES3::render_scene(const Ref &p_render_ render_data.inv_cam_transform = render_data.cam_transform.affine_inverse(); render_data.cam_projection = p_camera_data->main_projection; render_data.cam_orthogonal = p_camera_data->is_orthogonal; - render_data.cam_frustum = p_camera_data->is_frustum; render_data.camera_visible_layers = p_camera_data->visible_layers; render_data.main_cam_transform = p_camera_data->main_transform; @@ -2524,11 +2523,6 @@ void RasterizerSceneGLES3::render_scene(const Ref &p_render_ if (draw_sky || draw_sky_fog_only || sky_reflections || sky_ambient) { RENDER_TIMESTAMP("Setup Sky"); Projection projection = render_data.cam_projection; - if (is_reflection_probe) { - Projection correction; - correction.set_depth_correction(true, true, false); - projection = correction * render_data.cam_projection; - } sky_energy_multiplier *= bg_energy_multiplier; @@ -2761,14 +2755,6 @@ void RasterizerSceneGLES3::render_scene(const Ref &p_render_ Transform3D transform = render_data.cam_transform; Projection projection = render_data.cam_projection; - if (is_reflection_probe) { - Projection correction; - correction.columns[1][1] = -1.0; - projection = correction * render_data.cam_projection; - } else if (render_data.cam_frustum) { - // Sky is drawn upside down, the frustum offset doesn't know the image is upside down so needs a flip. - projection[2].y = -projection[2].y; - } _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); } diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 06daba39ac..1066c8f194 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -103,7 +103,6 @@ struct RenderDataGLES3 { Transform3D inv_cam_transform; Projection cam_projection; bool cam_orthogonal = false; - bool cam_frustum = false; uint32_t camera_visible_layers = 0xFFFFFFFF; // For billboards to cast correct shadows. diff --git a/drivers/gles3/shaders/sky.glsl b/drivers/gles3/shaders/sky.glsl index a68b7b1edd..7aab3caab7 100644 --- a/drivers/gles3/shaders/sky.glsl +++ b/drivers/gles3/shaders/sky.glsl @@ -195,7 +195,7 @@ void main() { #else cube_normal.z = -1.0; cube_normal.x = (uv_interp.x + projection.x) / projection.y; - cube_normal.y = (-uv_interp.y - projection.z) / projection.w; + cube_normal.y = (uv_interp.y + projection.z) / projection.w; #endif cube_normal = mat3(orientation) * cube_normal; cube_normal = normalize(cube_normal); diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp index d5bd402b20..1bee903c12 100644 --- a/servers/rendering/renderer_rd/environment/sky.cpp +++ b/servers/rendering/renderer_rd/environment/sky.cpp @@ -1149,10 +1149,6 @@ void SkyRD::setup_sky(const RenderDataRD *p_render_data, const Size2i p_screen_s correction.add_jitter_offset(p_render_data->scene_data->taa_jitter); Projection projection = p_render_data->scene_data->cam_projection; - if (p_render_data->scene_data->cam_frustum) { - // We don't use a full projection matrix for the sky, this is enough to make up for it. - projection[2].y = -projection[2].y; - } float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_render_data->environment); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index fc3c52bd84..09f8c8009e 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -1345,7 +1345,6 @@ void RendererSceneRenderRD::render_scene(const Ref &p_render scene_data.cam_transform = p_camera_data->main_transform; scene_data.cam_projection = p_camera_data->main_projection; scene_data.cam_orthogonal = p_camera_data->is_orthogonal; - scene_data.cam_frustum = p_camera_data->is_frustum; scene_data.camera_visible_layers = p_camera_data->visible_layers; scene_data.taa_jitter = p_camera_data->taa_jitter; scene_data.taa_frame_count = p_camera_data->taa_frame_count; diff --git a/servers/rendering/renderer_rd/shaders/environment/sky.glsl b/servers/rendering/renderer_rd/shaders/environment/sky.glsl index a34ead0191..1662007b6e 100644 --- a/servers/rendering/renderer_rd/shaders/environment/sky.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/sky.glsl @@ -216,8 +216,8 @@ void main() { cube_normal += sky_scene_data.view_eye_offsets[ViewIndex].xyz; #else cube_normal.z = -1.0; - cube_normal.x = (cube_normal.z * (-uv_interp.x - params.projection.x)) / params.projection.y; - cube_normal.y = -(cube_normal.z * (uv_interp.y - params.projection.z)) / params.projection.w; + cube_normal.x = (uv_interp.x + params.projection.x) / params.projection.y; + cube_normal.y = (uv_interp.y + params.projection.z) / params.projection.w; #endif cube_normal = mat3(params.orientation) * cube_normal; cube_normal = normalize(cube_normal); diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h index fdb71afbf5..811fdc861c 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h @@ -48,7 +48,6 @@ public: float taa_frame_count = 0.0f; uint32_t camera_visible_layers; bool cam_orthogonal = false; - bool cam_frustum = false; bool flip_y = false; // For billboards to cast correct shadows. diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index f27d7240d1..71517bc304 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -2623,7 +2623,6 @@ void RendererSceneCull::render_camera(const Ref &p_render_bu Projection projection; bool vaspect = camera->vaspect; bool is_orthogonal = false; - bool is_frustum = false; switch (camera->type) { case Camera::ORTHOGONAL: { @@ -2652,11 +2651,10 @@ void RendererSceneCull::render_camera(const Ref &p_render_bu camera->znear, camera->zfar, camera->vaspect); - is_frustum = true; } break; } - camera_data.set_camera(transform, projection, is_orthogonal, is_frustum, vaspect, jitter, taa_frame_count, camera->visible_layers); + camera_data.set_camera(transform, projection, is_orthogonal, vaspect, jitter, taa_frame_count, camera->visible_layers); #ifndef XR_DISABLED } else { XRServer *xr_server = XRServer::get_singleton(); @@ -2689,9 +2687,9 @@ void RendererSceneCull::render_camera(const Ref &p_render_bu } if (view_count == 1) { - camera_data.set_camera(transforms[0], projections[0], false, false, camera->vaspect, jitter, p_jitter_phase_count, camera->visible_layers); + camera_data.set_camera(transforms[0], projections[0], false, camera->vaspect, jitter, p_jitter_phase_count, camera->visible_layers); } else if (view_count == 2) { - camera_data.set_multiview_camera(view_count, transforms, projections, false, false, camera->vaspect, camera->visible_layers); + camera_data.set_multiview_camera(view_count, transforms, projections, false, camera->vaspect, camera->visible_layers); } else { // this won't be called (see fail check above) but keeping this comment to indicate we may support more then 2 views in the future... } @@ -3641,7 +3639,7 @@ void RendererSceneCull::render_empty_scene(const Ref &p_rend RENDER_TIMESTAMP("Render Empty 3D Scene"); RendererSceneRender::CameraData camera_data; - camera_data.set_camera(Transform3D(), Projection(), true, false, false); + camera_data.set_camera(Transform3D(), Projection(), true, false); scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray(), PagedArray(), PagedArray(), PagedArray(), PagedArray(), PagedArray(), PagedArray(), environment, RID(), compositor, p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, p_window_output_max_value, nullptr); #endif @@ -3707,7 +3705,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int RendererSceneRender::CameraData camera_data; Transform3D xform = p_instance->transform * local_view; - camera_data.set_camera(xform, cm, false, false, false); + camera_data.set_camera(xform, cm, false, false); RENDER_TIMESTAMP("Render ReflectionProbe, Face " + itos(face)); _render_scene(&camera_data, render_buffers, environment, RID(), RID(), RSG::light_storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, RID(), shadow_atlas, reflection_probe->instance, face, mesh_lod_threshold, use_shadows); diff --git a/servers/rendering/renderer_scene_render.cpp b/servers/rendering/renderer_scene_render.cpp index 7909d07e91..e50f0cc8f7 100644 --- a/servers/rendering/renderer_scene_render.cpp +++ b/servers/rendering/renderer_scene_render.cpp @@ -33,10 +33,9 @@ ///////////////////////////////////////////////////////////////////////////// // CameraData -void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_is_frustum, bool p_vaspect, const Vector2 &p_taa_jitter, float p_taa_frame_count, uint32_t p_visible_layers) { +void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter, float p_taa_frame_count, uint32_t p_visible_layers) { view_count = 1; is_orthogonal = p_is_orthogonal; - is_frustum = p_is_frustum; vaspect = p_vaspect; main_transform = p_transform; @@ -49,13 +48,12 @@ void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, taa_frame_count = p_taa_frame_count; } -void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_is_frustum, bool p_vaspect, uint32_t p_visible_layers) { +void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect, uint32_t p_visible_layers) { ERR_FAIL_COND_MSG(p_view_count != 2, "Incorrect view count for stereoscopic view"); visible_layers = p_visible_layers; view_count = p_view_count; is_orthogonal = p_is_orthogonal; - is_frustum = p_is_frustum; vaspect = p_vaspect; Vector planes[2]; diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h index 3197a7f4b8..b01ab2dbc2 100644 --- a/servers/rendering/renderer_scene_render.h +++ b/servers/rendering/renderer_scene_render.h @@ -306,7 +306,6 @@ public: // flags uint32_t view_count; bool is_orthogonal; - bool is_frustum; uint32_t visible_layers; bool vaspect; @@ -319,8 +318,8 @@ public: Vector2 taa_jitter; float taa_frame_count = 0.0f; - void set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_is_frustum, bool p_vaspect, const Vector2 &p_taa_jitter = Vector2(), float p_taa_frame_count = 0.0f, uint32_t p_visible_layers = 0xFFFFFFFF); - void set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_is_frustum, bool p_vaspect, uint32_t p_visible_layers = 0xFFFFFFFF); + void set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter = Vector2(), float p_taa_frame_count = 0.0f, uint32_t p_visible_layers = 0xFFFFFFFF); + void set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect, uint32_t p_visible_layers = 0xFFFFFFFF); }; virtual void render_scene(const Ref &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray &p_instances, const PagedArray &p_lights, const PagedArray &p_reflection_probes, const PagedArray &p_voxel_gi_instances, const PagedArray &p_decals, const PagedArray &p_lightmaps, const PagedArray &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, float p_window_output_max_value, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_render_info = nullptr) = 0;