@@ -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,16 @@ 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+ // NOTE: This assumes a rectangular projection plane, i.e. that:
586+ // - the matrix is a projection across z-axis (i.e. is invertible and columns[0][1], [0][3], [1][0] and [1][3] == 0)
587+ // - the projection plane is rectangular (i.e. columns[0][2] and [1][2] == 0 if columns[2][3] != 0)
588+ Size2 half_extents = p_cam_projection.get_viewport_half_extents ();
589+ 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 );
590+ return Rect2 (bottom_left, 2 * half_extents);
582591}
583592
584593void RaycastOcclusionCull::buffer_update (RID p_buffer, const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal) {
@@ -595,11 +604,12 @@ void RaycastOcclusionCull::buffer_update(RID p_buffer, const Transform3D &p_cam_
595604 Scenario &scenario = scenarios[buffer.scenario_rid ];
596605 scenario.update ();
597606
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 ());
607+ Rect2 vp_rect = _get_viewport_rect (p_cam_projection);
608+ Vector2 bottom_left = vp_rect.position ;
609+ bottom_left += _get_jitter (vp_rect, buffer.get_occlusion_buffer_size ());
610+ Vector3 near_bottom_left = Vector3 (bottom_left.x , bottom_left.y , -p_cam_projection.get_z_near ());
601611
602- buffer.update_camera_rays (p_cam_transform, near_bottom_left, 2 * viewport_half , p_cam_projection.get_z_far (), p_cam_orthogonal);
612+ buffer.update_camera_rays (p_cam_transform, near_bottom_left, vp_rect. get_size () , p_cam_projection.get_z_far (), p_cam_orthogonal);
603613
604614 scenario.raycast (buffer.camera_rays , buffer.camera_ray_masks .ptr (), buffer.camera_rays_tile_count );
605615 buffer.sort_rays (-p_cam_transform.basis .get_column (2 ), p_cam_orthogonal);
0 commit comments