Open Astrono2 opened 2 years ago
looks like this bug also correlated with this issue https://github.com/godotengine/godot/issues/39812
This issue still exists in Godot 4.0.2.
Bug still exists in 4.1, however if you're using C#, I've found a workaround by using the newly exposed projection matrix & working with System.Numerics
to do the matrix calculations.
From the debug_program.zip provided above, if you make a new Node3dCSharp.cs
file and fill in the following, the raycast will be calculated correctly.
EDIT: Ok, I think I've identified the issue, but those who actually know the codebase should confirm, along with any other places where this issue may occur:
eg. Camera3D::project_local_ray_normal
appears to calculated the ray incorrectly in non-ortho:
It multiplies by Vector2 screen_he = cm.get_viewport_half_extents();
but this does not appear to be enough to getting the ray in world space. It needs to be transformed by the inverse transform matrix, eg. C# equivalent code:
var clipSpaceRay = new Vector3(
((cpos.X / viewport_size.X) * 2.0f - 1.0f),
((1.0f - (cpos.Y / viewport_size.Y)) * 2.0f - 1.0f),
-1 // probably -1 because negative z-axis?
);
var camProjInv = cm.Inverse();
var camProjInvTransf = new Transform3D(camProjInv);
var rayCamLocalSpacePos = camProjInvTransf * clipSpaceRay;
var rayCamLocalSpacePosNorm = rayCamLocalSpacePos.Normalized();
return rayCamLocalSpacePosNorm;
EDIT2: fixed the names above.
@Quinn-L Have you tested with 4.1.1-RC1 which includes the changes made in https://github.com/godotengine/godot/pull/75806?
@Quinn-L Have you tested with 4.1.1-RC1 which includes the changes made in #75806?
Yes, it's still broken in that version. That commit only really exposed the projection matrix rather than fixing the underlying issue (though now easier to have a workaround the issue).
Is there intent to eventually address this issue?
Edit: i see its been brought up in multiple times, looks like there has been some progress, just +1 from this corner of the world.
Is there intent to eventually address this issue?
Not from my side. I don't think anyone else has worked on this specific issue. At the moment it cannot really be fixed as it is blocked by https://github.com/godotengine/godot-proposals/issues/2713. The problem is that orthogonal and perspective projection are hard coded in Camera3D. Frustum projection is "handled" by arbitrarily picking either of those two hard coded implementations. This is what causes the bug.
What has to happen to fix this issue is (imho):
I found writing unit tests for Godot to be far outside my skill set, which is why I stopped working on this issue. The patch I did write at least allows users access to the projection matrix, which is necessary to write a workaround.
Is there a workaround for 3.5? I'm using frustum cameras and if I change the viewport size, all of my frustum_offset calculations are incorrect, I'm wondering if there's some way of multiplying the size of the viewport by the amount as a quick fix.
Godot version
4.0.dev
System information
Arch Linux 5.16.14
Issue description
When using a
Camera3D
'sproject_ray_origin
,project_ray_normal
,project_position
andunproject_position
to translate between world and screen coordinates, if the camera is set to frustum projection, the projected position does not match the screen position. In this example I set up two viewports, one with a frustum camera and an one with an overview perspective camera for debugging. I had a simple script converting positions fromInputEventMouseButton
s into ray origin and normal, then using aRayCast3D
to intersect with the scene (the three prisms have static bodies) The expected result (and the one I got with perspective projection, orthographic projection and frustum projection with no offset) is that the green cylinder (that indicates the world position gotten from the conversion) should point to the box in the back, but instead it points at the wall.Looking into the source, the error is obvious. None of the methods handles frustum projections, there's just a
or
Steps to reproduce
Set up a 3D scene with a frustum camera with a non-zero offset. Set up a script that uses a world-space position generated from to screen positions using one of the aforementioned methods. I recommend moving a 3D object to the position gotten from a click, as it's the easiest way to see the difference.
Minimal reproduction project
Sorry for the messy layout. It's the same project as the screenshot. Change the settings of the
Camera3D
inNode3D.tscn
to test that indeed it does work ondebug_program.zip