godot icon indicating copy to clipboard operation
godot copied to clipboard

Add Custom Projection to Camera3D

Open DxUr opened this issue 2 years ago • 25 comments

Add custom_projection property to Camera3D

  • Bugsquad edit, closes: https://github.com/godotengine/godot-proposals/issues/2713*

DxUr avatar Nov 04 '23 17:11 DxUr

Can you test what happens if you create a projection that produces invalid output values, like NaN and what happens if they are injected into the renderer, it could cause serious issues (like what happens when you do the same for audio, where it cuts all audio)

AThousandShips avatar Nov 05 '23 09:11 AThousandShips

Can you test what happens if you create a projection that produces invalid output values, like NaN and what happens if they are injected into the renderer, it could cause serious issues (like what happens when you do the same for audio, where it cuts all audio)

Actually this implementation affect just the projection matrix it works very well with oblique projection... , then it's for people that want to do some tweaks like 3d looks parallel in one dimensions, then it doesn't cause issues with viewports ..., I think it's so useful. I started working on global shader overriding which will allow doing stuffs like curved world..., my problem now with the camera frustum. Edit: you can't past Null value to set_custom_projection;

DxUr avatar Nov 05 '23 11:11 DxUr

What do you mean? I'm not asking for that, I'm asking what happens if you provide a broken Projection, that transforms values to NaN, the problem isn't "what limitations does it have?", it is "will adding an invalid projection mess up the rendering or crash?"

AThousandShips avatar Nov 05 '23 11:11 AThousandShips

What do you mean? I'm not asking for that, I'm asking what happens if you provide a broken Projection, that transforms values to NaN, the problem isn't "what limitations does it have?", it is "will adding an invalid projection mess up the rendering or crash?"

I tested playing with the projection as i can it never crash the rendering.

DxUr avatar Nov 05 '23 11:11 DxUr

Try with something like: Projection.create_orthogonal(-1, 1, -1, 1, 0, INF)

If it causes problems then that would be helped by having the methods suggested in:

  • https://github.com/godotengine/godot/pull/77481

AThousandShips avatar Nov 05 '23 11:11 AThousandShips

Projection.create_orthogonal(-1, 1, -1, 1, 0, INF)

I tested it, then it does not cause any problems, even with the frustum.

DxUr avatar Nov 05 '23 22:11 DxUr

I also need this for my project, and I also have my own implementation (roughly the same): https://github.com/PitouGames/godot/tree/custom_projection

I don't understand why the projection matrix is accessible in the editor GUI in this PR after your comment: https://github.com/godotengine/godot-proposals/issues/2713#issuecomment-1773917923. User will still be able to show it with scripts like that:

extends Camera3D


@export var projection_matrix: Projection

func _process(delta):
	custom_projection = projection_matrix

There are the camera's functions set_perspective, set_orthogonal, set_frustum but the set_custom to switch the camera to the custom mode from code is missing (or I didn't found it).

Can we also take advantage of this PR to move the field "Current" up? It's in the middle of projection settings. image

PitouGames avatar Nov 10 '23 00:11 PitouGames

Can we also take advantage of this PR to move the field "Current" up? It's in the middle of projection settings.

While we're at it, I'd move Current at the very top and move Keep Aspect just above FOV. The way FOV is interpreted (vertical or horizontal) depends on the value of Keep Aspect.

Calinou avatar Nov 10 '23 10:11 Calinou

I don't understand why the projection matrix is accessible in the editor GUI in this PR after your comment

Actually I just make it accessible because it makes it a little bit harder to test some values theoretically then making it accessible from the editor is pointless as the projection must be recalculated if the viewport had resized but still annoying to export another projection as a script variable then make a setter..., I think it's OK now.

DxUr avatar Nov 10 '23 17:11 DxUr

See also:

  • https://github.com/godotengine/godot/pull/85529

AThousandShips avatar Nov 30 '23 09:11 AThousandShips

Hello, I stumbled upon a problem playing with this PR. It appear that shadows doesn't render correctly when the camera projection is set to custom and mimic orthogonal view (even if we just copy the projection matrix from another camera) : image

It seems to work just fine when mimic a perspective view : image

I'm sure that the two camera have the same projection matrix since I basically did : $SubViewport2/Camera3D.custom_projection = $SubViewport/Camera3D.get_camera_projection()

I know that the problem as something to do with the shadow rendering but can't figure out what exactly ...

BrunkMortel avatar Jan 03 '24 09:01 BrunkMortel

@BrunkMortel I'll check it because I don't have this issue in my projects, can provide which renderer are you using?

DxUr avatar Jan 06 '24 09:01 DxUr

@DxUr I'm using the Forward+ renderer and everything else is by default. Here is a simple scene setup that show the probleme : simple_scene.zip

BrunkMortel avatar Jan 06 '24 11:01 BrunkMortel

Tested locally (rebased against master https://github.com/godotengine/godot/commit/fa48a51183567934984b381ad8ec281cb24d66ba) on NVIDIA. I get a Vulkan device lost error if I adjust the Camera3D's projection matrix in the editor while the project is running:

ERROR: Vulkan: Did not create swapchain successfully. Error code: VK_NOT_READY
   at: prepare_buffers (drivers/vulkan/vulkan_context.cpp:2491)
ERROR: Vulkan: Cannot submit graphics queue. Error code: VK_ERROR_DEVICE_LOST
   at: swap_buffers (drivers/vulkan/vulkan_context.cpp:2571)

This only occurs if SDFGI is enabled. VoxelGI doesn't have these errors but renders incorrectly if any values in the custom projection are modified.

Also, running a project with a Camera3D that has its projection mode to Custom prints the following error (even if run outside the editor):

ERROR: Camera is not inside the scene tree.
   at: get_camera_projection (./scene/3d/camera_3d.cpp:212)

Directional shadow rendering also breaks if you change any values in the custom camera projection, with the following errors printed:

ERROR: Condition "!res" is true. Returning: false
   at: get_endpoints (./core/math/projection.cpp:502)
ERROR: Condition "!res" is true. Continuing.
   at: _light_instance_setup_directional_shadow (./servers/rendering/renderer_scene_cull.cpp:2153)

Point light shadow rendering breaks with certain values too (even though the rest of the scene still renders), but not as often as directional shadows. There are also no errors printed in this case.

Testing project: test_pr_84454.zip

Calinou avatar Jan 29 '24 17:01 Calinou

@DxUr what's the status on this? Is there work to be done or are you waiting on more feedback?

BryceBarbara avatar Feb 23 '24 05:02 BryceBarbara

@DxUr I would like to continue working on this PR, since it's nearly complete and I would benefit from it.

otonashixav avatar Mar 08 '24 13:03 otonashixav

I will fix all the issues that people face with this PR as soon as possible so I would like to be merged before 4.3

DxUr avatar Mar 08 '24 14:03 DxUr

Hope this helps then: https://github.com/otonashixav/godot/tree/pr/DxUr/84454; I've fixed the issues reported so far, though I don't know if my solutions are satisfactory since I'm not really well versed in 3D.

otonashixav avatar Mar 08 '24 15:03 otonashixav

I've just tried using otonashixav's branch, and every seems to work without error for my use case (orthogonal camera with custom aspect ratio).

One thing I will note is that the complete lack of a camera gizmo in custom projection mode is somewhat annoying. Showing the view frustum (maybe with an artificially shortened far plane) could be good, or barring that, something like what DirectionalLight3D has just to indicate direction

Haydoggo avatar Mar 15 '24 08:03 Haydoggo

I will make a PR with my branch this weekend if this PR isn't ready by then, since it seems like 4.3 will enter beta soon based on the dev5 blogpost.

otonashixav avatar Mar 20 '24 10:03 otonashixav

Hope this helps then: https://github.com/otonashixav/godot/tree/pr/DxUr/84454; I've fixed the issues reported so far, though I don't know if my solutions are satisfactory since I'm not really well versed in 3D.

Thank you for fixing all the issues, I checked your solution and I think it's enough.

DxUr avatar Mar 23 '24 07:03 DxUr

@otonashixav But it works fine for me, I had tried every possible case!

DxUr avatar Mar 23 '24 11:03 DxUr

I mean it does work fine. I'm just concerned about some points that the reviewers might be able to clear up.

otonashixav avatar Mar 23 '24 11:03 otonashixav

If I tilt the camera perspective upwards, the object "moves" downwards, but the background sky also moves downwards (into the brown area) instead of showing the sky above the object (see video). The same thing happens when you tilt the camera perspective down, only in the opposite direction. Is this intentional or a bug?


My specific use case

I want to create an camera array to make one big screenshot usig multiple cameras with custom projection but the sky is incorrect.

Using one camera Using 4 cameras with custom projection
Test2 Test1

https://github.com/godotengine/godot/assets/71942164/2b8f0ab6-fc8b-405c-9d41-67ff83a0e99c

Video project: customprojection.zip I used the latest build artifacts (one hour ago) on Windows 11.

havi05 avatar Mar 23 '24 13:03 havi05

If I tilt the camera perspective upwards, the object "moves" downwards, but the background sky also moves downwards (into the brown area) instead of showing the sky above the object (see video). The same thing happens when you tilt the camera perspective down, only in the opposite direction. Is this intentional or a bug?

This is not a bug, this is expected due to what a projection matrix is. The Projection matrix is 4x4 Matrix, you should not change it manually you must use a script to do that, Than you can fix the tilting by playing with all components. Note that using a proper calculations is required.

DxUr avatar Mar 23 '24 22:03 DxUr

The Projection matrix is 4x4 Matrix, you should not change it manually you must use a script to do that, Than you can fix the tilting by playing with all components. Note that using a proper calculations is required.

In this case, it should be marked read-only in the inspector to prevent accidental changes. This can be done using PROPERTY_USAGE_READ_ONLY in _bind_methods().

Calinou avatar Apr 04 '24 00:04 Calinou

Is the PROPERTY_USAGE_READ_ONLY flag all that is needed for this PR to be merged or are we waiting on responses to the comments from @otonashixav?

BryceBarbara avatar Apr 12 '24 19:04 BryceBarbara

Thanks for writing this PR. I don't mind building from source but would love to see this merged so I can be confident relying on it in my project. Are there any remaining blockers? If more needs to be done, I'd be happy to help out.

mattdiener avatar Apr 23 '24 18:04 mattdiener

This hasn't been reviewed entirely yet, so it needs to be reviewed properly first, so nothing you can help with necessarily, we're getting close to feature freeze as well meaning this is likely not going to be in 4.3

AThousandShips avatar Apr 23 '24 18:04 AThousandShips