-
-
Notifications
You must be signed in to change notification settings - Fork 97
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
Add custom projection mode to Camera3D, make Camera3D store its CameraMatrix and expose CameraMatrix to user code #2713
Comments
Related to godotengine/godot#7499 My understanding is this feature is used for creating oblique frustums (mirrors / portals). Would a more limited feature like PROJECTION_OBLIQUE be sufficient to cover your proposed usecases? |
Yes, our specific use-case for this is creating portals/mirrors, particularly in VR. I would add also that the ability to seperate the view and clipping frustum seperately would likely go further in allowing optimisation, because we could limit the clipping plane to the confines of the portal. |
I was also working on a portal plugin and needed this (in addition to other things, like stencil buffering). |
It's one of the few things I've missed about switching to godot, having full access to the camera projection matrix. This portal plugin looks like it could be amazing if it could be completed with oblique frustum projection being available. |
That's also the only use case I know, but in general I think having access to a Camera's matrix is a better solution. Specially since the changes I propose would also simplify adding new projection modes in the future. At the moment, the VisualServerScene::render_camera function scales with the amount of projection modes, as well as many of the functions in Camera. CameraMatrix cm;
if (mode == PROJECTION_ORTHOGONAL) {
cm.set_orthogonal(size, viewport_size.aspect(), p_z_depth, far, keep_aspect == KEEP_WIDTH);
} else {
cm.set_perspective(fov, viewport_size.aspect(), p_z_depth, far, keep_aspect == KEEP_WIDTH);
} This appears 3 times in camera.cpp. Storing the Camera's matrix in a variable would make the code a lot simpler. |
Exposing the possibility to set the matrix directly would be really nice in my opinion. It will also allow for more artistic effects like morphing between two matrices (even if not perspective/mathematically correct during morph you can achieve quite some interesting effects). |
I want this to make it easier to fake 2d-style isometric and orthographic perspectives using 3d assets. Right now I need to stretch the world in bizarre ways to get the same effect, and it loses me a lot of control. |
I left this hanging for a long time due to school. So I just edited to comply with not touching the Variant class and to update it for Godot 4, and I'll start working on it now! |
Bump 🙂 Have you made progress so far? |
Sadly, no. I really want to work on this, but school is hitting hard. I think I'll get to it once I graduate at the end of the year. I have been reading the code and making minor changes to see what effects modifying this or that has, but not much more. |
Hey all, I've just successfully implemented an Oblique Near Plane projection camera via the Godot source code. Technically, I have Igor Kosyanenko to thank for doing the heavy lifting, specifically: figuring out how to apply Eric Lengyel's near clipping matrix transformation algorithm. Igor originally posted his project status here: And Eric's algorithm is found here (also linked in Igor's post): None of Igor's project or source code is available anymore, so I had to make the adjustments to the engine (specifically: additions) adding the new camera type. I have done my best to make the additions as minimal as possible (pretty much get the engine to compile, and render the proper oblique near plane). The code can be found on my forked Godot repo on this branch: let me know what you think! Lastly, if you don't check out Igor's post: he specifically got stuck because his skybox was warping when seen through the portals camera view. The solution turned out to be setting a custom FOV for the skybox of whatever environment the portal camera can see. This is a short video showing the problem, and the solution: |
This is really amazing, I'll try it later, thanks so much for all of your work! |
Thanks! I'm really grateful for everyone who took part in the discussion about this camera type over the years (which I came across in my research). All the back and forth between everyone really pointed me in the right direction of how to implement it. This comment in particular pointed me to the right part of the engine to put the additions: It really just goes to show how important documentation is. If anyone along the way hadn't bothered to post their progress, there's no telling where I'd be in the process right now. |
This is amazing! I still think giving the user access to the camera matrix is a good idea. But this covers my use case. I'll check it out when I have the time to get back to this! |
Actually, now that you mention it... I think it would be a good idea to transition the gdscript code for finding the clipping plane in camera space to the camera itself. That way, it would be easy to pass the camera the origin and normal of any plane, and get an oblique near clipping plane from that, rather than needing to attach a script every time (though you would still need a script to continuously update the values) While I'm at it.. I'll make an attempt at exposing the CameraMatrix... Thoughts? |
Hey, I know I'm posting a lot here, I just know most of you are interested in implementing portals, which is my main reason for making additions to the engine (I need them too). turns out that multiple setters was.. working somehow? but apparently also broken? I believe I may have just convinced myself it worked. In any case, godot does not like more than 1 parameter for setters, so I switched to a dictionary format for the oblique camera. In addition to that, I've just finished implementing a new feature to the spatialmaterial, which will allow the specification of an arbitrary world plane to clip a mesh with. Initially it was just a special shader code I found from a video: and it worked well for basic uses, but I realized that when importing models with attached materials, I would have to convert those materials into shaders, and then inject the clipping code manually.. for every material on the model, and for every model (and that just won't cut it for me). So after more deliberation than I care to admit (trying to figure out if I could use a 'next pass' shader to accomplish the same effect) I resolved to make an addition to the spatialmaterial, which can be toggled on and off. The code for it is on the same branch as before, but here's a video showing both features in more detail (probably best to watch at 2x speed, i'm talking slower than it felt like). |
I don't think modifying |
Sorry, I'm new to contributing to open source projects, and I understand that there's an etiquette I'm not yet aware of. My last post was only to express a necessary fix to the oblique camera I hadn't realized was broken, and an additional change I had made to the engine on the same branch to the spatialmaterial. It was not a feature proposal, but for anyone who might pull from my branch might have noticed and wondered about why it was there (or possibly why it wasn't there in the official release). I'm presently just starting the process of looking into how to go about setting up a pull-request formally for the oblique camera, there's a lot more documentation involved than I realized, so it won't happen immediately. On the spatialmaterial: it addressed my needs precisely, and is very useful for the 'passing through the portal' effect without needing to inject code into every material-made-a-shader manually. I'm just enthusiastic about how much easier it is to improve the engine for my needs than I expected, but nothing I have presented thus far has been with the expectation that it would be integrated into the upstream repo. |
@qaptoR since you write that you are new, are you aware of the contributors chat? It's located at https://chat.godotengine.org/ There also is a |
Wow, okay. I sat down to get to work on this and the rendering system has gotten so much more complex since Godot 3. The handling and passing around of Sadly what was a non-trivial but doable change when I proposed it has grown in scope drastically. I think it would be best to close this with @qaptoR's eventual pull request. I still think storing a I will open another issue once I have a better idea of what storing a |
I'll be able to start working on the pull request after December 15th when finals are over, for anyone wondering why there is no progress on that in nearly 3 weeks, I was only able to tackle it over reading break. |
DxUr, did that custom projections PR make it into the 4.2 beta that's currently in testing? |
This is my implementation, idk if it added to 4.2 then I'll make a pull request later. I'm so lazy to do that. |
I'm also interested in this feature when I need this for doing oblique projection planes. Currently working on a project with portals and non-euclidean worlds where modifying the projection matrix is a must. |
I spent some time on this topic, because it's the base of my current project. I use Godot 4.1.2. I think the editor is better like this:
You can find my code here: https://github.com/PitouGames/godot/tree/custom_projection
Don't hesitate to give feedback! |
@mathiasmellemstuen |
I totally agree with this. Making the projection matrix available only from code is probably the right way based on the reasoning you stated. Not sure how many will benefit from setting the coefficients manually in editor anyways. Personally I would really appreciate if you go through with this. |
@mathiasmellemstuen ok, I'll do it, I hope they accept it for 4.2. |
4.2 is in feature freeze, so any new features will have to target 4.3 at the earliest. You can still open a PR now, but it won't be merged for 4.2. |
@mathiasmellemstuen |
Can any one tell the team to merge it, I really need it in my projects and compiling from source is waste of time. |
could we please merge the PR? from the code it's clear that the code doesn't break existing functionality, but bring the new one, which was requested already 3y ago and exists in unity for quite long time. or at least prepend '[experimental]' label on the dropdown |
Some issues were reported with that PR: godotengine/godot#84454 (comment) Also, it still needs a review from a rendering maintainer before it can be merged. |
My use case for custom projections in Camera3D is to orthogonally skew the whole world to give walls the appearance of height even when the camera is pointing straight down (mockup faked in Blender by moving the verts of the wall tops). This seems like a common use case for various kinds of 2.5 top down games. Related technique is discussed on this page: https://manabreak.github.io/devlog/satos/3d/2019/08/16/3d-to-2d.html |
I would really appreciate the option to experiment with different projections, e.g. spherical projection, without having to do weird workarounds in spatial shaders. What Godot projects are currently missing in 3D fidelity compared to other major engines can be made up for with art direction, but access to the projection matrix is going to be an important tool for creating a distinctive art direction. Is there anything those of us hoping for this feature can do to help move this forward? |
Note that being able to adjust the projection matrix isn't sufficient on its own to implement things like panini projection. Alternative camera projections generally require a post-processing shader, or sometimes even stitching multiple camera renders together for particularly wide angles to avoid distortion. |
Oh yes, many of the most interesting effects require more than just a custom camera projection matrix. But this is certainly one step along the way, and a helpful tool to have in any case. |
This would be a greatly valuable feature for my use case. Lack of custom projection is a holdup for moving a concept I've been working on from Unity to Godot. |
This comment was marked as off-topic.
This comment was marked as off-topic.
Now that 4.3 is out, how is it looking for getting this into 4.4? |
Describe the project you are working on
I'm working on a portal plugin.
Describe the problem or limitation you are having in your project
I need to use oblique frustum projection to allow for the portals' cameras to clip content that's behind the portal plane. Which is currently impossible in Godot.
Describe the feature / enhancement and how it helps to overcome the problem or limitation
The enhancement would be to add a new projection mode, PROJECTION_CUSTOM to the Camera class, which would allow the developer to directly set the matrix to be used for projection. For my specific case, that would allow me to use oblique frustum projection. It would also address any other projection that any developer could want to use. And it would probably allow for some weird distortion effects as well.
Also, if a new projection is added with a CameraMatrix exposed to the user, it would make sense to migrate the entire Camera class and camera rendering to work with a CameraMatrix object belonging to each Camera instead of calculating the matrices from the Cameras' parameters.
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
I think this can be done in a few steps:
Here's a little mockup:
If this enhancement will not be used often, can it be worked around with a few lines of script?
Most definitely not
Is there a reason why this should be core and not an add-on in the asset library?
It requires considerable (although not very invasive) changes to two core classes and the rendering system.
The text was updated successfully, but these errors were encountered: