Skip to content

Commit 11c6593

Browse files
committed
Use p_cam_projection.get_endpoints() to calculate the viewport location
Fixes #104193 In OpenXR the viewport location is not centered on the transform origin
1 parent 0028fd6 commit 11c6593

File tree

2 files changed

+23
-12
lines changed

2 files changed

+23
-12
lines changed

modules/raycast/raycast_occlusion_cull.cpp

+22-11
Original file line numberDiff line numberDiff line change
@@ -525,14 +525,14 @@ void RaycastOcclusionCull::buffer_set_size(RID p_buffer, const Vector2i &p_size)
525525
buffers[p_buffer].resize(p_size);
526526
}
527527

528-
Vector2 RaycastOcclusionCull::_jitter_half_extents(const Vector2 &p_half_extents, const Size2i &p_viewport_size) {
528+
Vector2 RaycastOcclusionCull::_get_jitter(const Rect2 &p_viewport_rect, const Size2i &p_buffer_size) {
529529
if (!_jitter_enabled) {
530-
return p_half_extents;
530+
return Vector2();
531531
}
532532

533533
// Prevent divide by zero when using NULL viewport.
534-
if ((p_viewport_size.x <= 0) || (p_viewport_size.y <= 0)) {
535-
return p_half_extents;
534+
if ((p_buffer_size.x <= 0) || (p_buffer_size.y <= 0)) {
535+
return Vector2();
536536
}
537537

538538
int32_t frame = Engine::get_singleton()->get_frames_drawn();
@@ -568,8 +568,8 @@ Vector2 RaycastOcclusionCull::_jitter_half_extents(const Vector2 &p_half_extents
568568
jitter = Vector2(0.5f, 0.5f);
569569
} break;
570570
}
571-
572-
jitter *= Vector2(p_half_extents.x / (float)p_viewport_size.x, p_half_extents.y / (float)p_viewport_size.y);
571+
Vector2 half_extents = p_viewport_rect.get_size() * 0.5;
572+
jitter *= Vector2(half_extents.x / (float)p_buffer_size.x, half_extents.y / (float)p_buffer_size.y);
573573

574574
// The multiplier here determines the jitter magnitude in pixels.
575575
// It seems like a value of 0.66 matches well the above jittering pattern as it generates subpixel samples at 0, 1/3 and 2/3
@@ -578,7 +578,17 @@ Vector2 RaycastOcclusionCull::_jitter_half_extents(const Vector2 &p_half_extents
578578
// False shown can lower percentage that are occluded, and therefore performance.
579579
jitter *= 0.66f;
580580

581-
return p_half_extents + jitter;
581+
return jitter;
582+
}
583+
584+
Rect2 _get_viewport_rect(const Projection &p_cam_projection) {
585+
// TODO: this is proposed as a feature of Projection at https://github.com/godotengine/godot/pull/104311
586+
// NOTE: This assumes a rectangular projection plane, i.e. that :
587+
// - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0)
588+
// - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0)
589+
Size2 half_extents = p_cam_projection.get_viewport_half_extents();
590+
Point2 bottom_left = -half_extents * Vector2(p_cam_projection.columns[3][0] * p_cam_projection.columns[3][3] + p_cam_projection.columns[2][0] * p_cam_projection.columns[2][3] + 1, p_cam_projection.columns[3][1] * p_cam_projection.columns[3][3] + p_cam_projection.columns[2][1] * p_cam_projection.columns[2][3] + 1);
591+
return Rect2(bottom_left, 2 * half_extents);
582592
}
583593

584594
void RaycastOcclusionCull::buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal) {
@@ -595,11 +605,12 @@ void RaycastOcclusionCull::buffer_update(RID p_buffer, const Transform3D &p_cam_
595605
Scenario &scenario = scenarios[buffer.scenario_rid];
596606
scenario.update();
597607

598-
Vector2 viewport_half = p_cam_projection.get_viewport_half_extents();
599-
Vector2 jitter_viewport_half = _jitter_half_extents(viewport_half, buffer.get_occlusion_buffer_size());
600-
Vector3 near_bottom_left = Vector3(-jitter_viewport_half.x, -jitter_viewport_half.y, -p_cam_projection.get_z_near());
608+
Rect2 vp_rect = _get_viewport_rect(p_cam_projection);
609+
Vector2 bottom_left = vp_rect.position;
610+
bottom_left += _get_jitter(vp_rect, buffer.get_occlusion_buffer_size());
611+
Vector3 near_bottom_left = Vector3(bottom_left.x, bottom_left.y, -p_cam_projection.get_z_near());
601612

602-
buffer.update_camera_rays(p_cam_transform, near_bottom_left, 2 * viewport_half, p_cam_projection.get_z_far(), p_cam_orthogonal);
613+
buffer.update_camera_rays(p_cam_transform, near_bottom_left, vp_rect.get_size(), p_cam_projection.get_z_far(), p_cam_orthogonal);
603614

604615
scenario.raycast(buffer.camera_rays, buffer.camera_ray_masks.ptr(), buffer.camera_rays_tile_count);
605616
buffer.sort_rays(-p_cam_transform.basis.get_column(2), p_cam_orthogonal);

modules/raycast/raycast_occlusion_cull.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ class RaycastOcclusionCull : public RendererSceneOcclusionCull {
161161
bool _jitter_enabled = false;
162162

163163
void _init_embree();
164-
Vector2 _jitter_half_extents(const Vector2 &p_half_extents, const Size2i &p_viewport_size);
164+
Vector2 _get_jitter(const Rect2 &p_viewport_rect, const Size2i &p_buffer_size);
165165

166166
public:
167167
virtual bool is_occluder(RID p_rid) override;

0 commit comments

Comments
 (0)