Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Frustum Sky projection translation logic shearing #86138

Merged
merged 1 commit into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion drivers/gles3/rasterizer_scene_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2259,6 +2259,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &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;

Expand Down Expand Up @@ -2592,14 +2593,18 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
scene_state.enable_gl_blend(false);
scene_state.set_gl_cull_mode(GLES3::SceneShaderData::CULL_BACK);

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, render_data.cam_transform, sky_energy_multiplier, render_data.luminance_multiplier, p_camera_data->view_count > 1, flip_y, apply_color_adjustments_in_post);
_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);
}

if (rt && (scene_state.used_screen_texture || scene_state.used_depth_texture)) {
Expand Down
1 change: 1 addition & 0 deletions drivers/gles3/rasterizer_scene_gles3.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ 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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1961,7 +1961,13 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co

sky.setup_sky(p_render_data->environment, rb, *p_render_data->lights, p_render_data->camera_attributes, 1, &projection, &eye_offset, p_render_data->scene_data->cam_transform, projection, screen_size, Vector2(0.0f, 0.0f), this);
} else {
sky.setup_sky(p_render_data->environment, rb, *p_render_data->lights, p_render_data->camera_attributes, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, p_render_data->scene_data->cam_transform, p_render_data->scene_data->cam_projection, screen_size, p_render_data->scene_data->taa_jitter, this);
Projection projection = p_render_data->scene_data->cam_projection;
if (p_render_data->scene_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;
}

sky.setup_sky(p_render_data->environment, rb, *p_render_data->lights, p_render_data->camera_attributes, p_render_data->scene_data->view_count, &projection, p_render_data->scene_data->view_eye_offset, p_render_data->scene_data->cam_transform, projection, screen_size, p_render_data->scene_data->taa_jitter, this);
}

sky_energy_multiplier *= bg_energy_multiplier;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -976,7 +976,13 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color

sky.setup_sky(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, 1, &projection, &eye_offset, p_render_data->scene_data->cam_transform, projection, screen_size, Vector2(0.0f, 0.0f), this);
} else {
sky.setup_sky(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, p_render_data->scene_data->cam_transform, p_render_data->scene_data->cam_projection, screen_size, p_render_data->scene_data->taa_jitter, this);
Projection projection = p_render_data->scene_data->cam_projection;
if (p_render_data->scene_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;
}

sky.setup_sky(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, p_render_data->scene_data->view_count, &projection, p_render_data->scene_data->view_eye_offset, p_render_data->scene_data->cam_transform, projection, screen_size, p_render_data->scene_data->taa_jitter, this);
}

sky_energy_multiplier *= bg_energy_multiplier;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1129,6 +1129,7 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class RenderSceneDataRD : public RenderSceneData {
float taa_frame_count = 0.0f;
uint32_t camera_visible_layers;
bool cam_orthogonal = false;
bool cam_frustum = false;
bool flip_y = false;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated, please restore as it helps readability

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, done

// For billboards to cast correct shadows.
Expand Down
12 changes: 7 additions & 5 deletions servers/rendering/renderer_scene_cull.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2734,6 +2734,7 @@ void RendererSceneCull::render_camera(const Ref<RenderSceneBuffers> &p_render_bu
Projection projection;
bool vaspect = camera->vaspect;
bool is_orthogonal = false;
bool is_frustum = false;

switch (camera->type) {
case Camera::ORTHOGONAL: {
Expand Down Expand Up @@ -2762,10 +2763,11 @@ void RendererSceneCull::render_camera(const Ref<RenderSceneBuffers> &p_render_bu
camera->znear,
camera->zfar,
camera->vaspect);
is_frustum = true;
} break;
}

camera_data.set_camera(transform, projection, is_orthogonal, vaspect, jitter, taa_frame_count, camera->visible_layers);
camera_data.set_camera(transform, projection, is_orthogonal, is_frustum, vaspect, jitter, taa_frame_count, camera->visible_layers);
} else {
// Setup our camera for our XR interface.
// We can support multiple views here each with their own camera
Expand All @@ -2787,9 +2789,9 @@ void RendererSceneCull::render_camera(const Ref<RenderSceneBuffers> &p_render_bu
}

if (view_count == 1) {
camera_data.set_camera(transforms[0], projections[0], false, camera->vaspect, jitter, p_jitter_phase_count, camera->visible_layers);
camera_data.set_camera(transforms[0], projections[0], false, 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, camera->vaspect);
camera_data.set_multiview_camera(view_count, transforms, projections, false, false, camera->vaspect);
} 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...
}
Expand Down Expand Up @@ -3633,7 +3635,7 @@ void RendererSceneCull::render_empty_scene(const Ref<RenderSceneBuffers> &p_rend
RENDER_TIMESTAMP("Render Empty 3D Scene");

RendererSceneRender::CameraData camera_data;
camera_data.set_camera(Transform3D(), Projection(), true, false);
camera_data.set_camera(Transform3D(), Projection(), true, false, false);

scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray<RenderGeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), environment, RID(), compositor, p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr);
#endif
Expand Down Expand Up @@ -3711,7 +3713,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int

RENDER_TIMESTAMP("Render ReflectionProbe, Step " + itos(p_step));
RendererSceneRender::CameraData camera_data;
camera_data.set_camera(xform, cm, false, false);
camera_data.set_camera(xform, cm, false, false, false);

Ref<RenderSceneBuffers> render_buffers = RSG::light_storage->reflection_probe_atlas_get_render_buffers(scenario->reflection_atlas);
_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, p_step, mesh_lod_threshold, use_shadows);
Expand Down
6 changes: 4 additions & 2 deletions servers/rendering/renderer_scene_render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@
/////////////////////////////////////////////////////////////////////////////
// CameraData

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, const uint32_t p_visible_layers) {
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, const 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;
Expand All @@ -48,12 +49,13 @@ 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_vaspect) {
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) {
ERR_FAIL_COND_MSG(p_view_count != 2, "Incorrect view count for stereoscopic view");

visible_layers = 0xFFFFFFFF;
view_count = p_view_count;
is_orthogonal = p_is_orthogonal;
is_frustum = p_is_frustum;
vaspect = p_vaspect;
Vector<Plane> planes[2];

Expand Down
5 changes: 3 additions & 2 deletions servers/rendering/renderer_scene_render.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ class RendererSceneRender {
// flags
uint32_t view_count;
bool is_orthogonal;
bool is_frustum;
uint32_t visible_layers;
bool vaspect;

Expand All @@ -314,8 +315,8 @@ class RendererSceneRender {
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_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);
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);
};

virtual void 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 = nullptr, RenderingMethod::RenderInfo *r_render_info = nullptr) = 0;
Expand Down
Loading