Pixel perfect orthographic camera and physics side effects

Godot Version

4.2.1

Question

Hey all! I’m making a 3D pixel art game, using the techniques in games like Enter the Gungeon. After a lot of reading, I found that they use an orthographic camera, and then they scale all the assets on the y and z axis by sqrt(2). I’ve scaled everything on my main 3D node, and it looks really nice, but now, obviously, everything is scaled, and the physics act weird / all the nodes move around at runtime. Is there a way to just scale it from the camera so the physics aren’t effected?

Here is a link to the thread where the dev explains how to do it. Instead of the camera, they tilt the whole game world by 45 degrees and scale just the world (not actors), which would really mess the physics up imo, don’t know how they pulled that off. I’ve been keeping the camera at 45 degrees and scaling everything, though I’m open to try other things.

SubViewports are the solution

First, pixel perfect stuff is easily done by using viewports.
image

Just set the size of a viewport to specific resolution you want to have, then scale SubViewportContainer to fit your entire screen (there might be some hack in the project settings but I prefer to do that manually with code)

Now, because we are not limited to one Viewport, what we can do is to have multiple viewports, each looking at specific cull layers.


Sidenote: it’s a parameter of a Camera3D and not of Viewport

This way character’s Sprite3Ds and enviroment’s MeshInstances can be separated onto different cull layers and rendered separatly.

Sidenote: Viewport has property called World3D and it allows for you to use 2 viewport on the same World3D (i think by default they will, but you can control it through that). look into documentation of World3D to learn more.

EDIT: Methodology below turned out to not work as I wanted to. It does squish stuff by sqrt(2). Mistakes lies that, in the image that I made, i used parallelogram to represent view tilted by 45 degrees, but in reality, its just a rotated rectangle.
Following section is incorrect.

Now when having 2 cameras, we can do that 45° rotation trick, and i speculate it will look something like this:


Walls camera can see and render only walls, Character camera sees and renders only characters.
Sidenote: Character’s camera would have to have transparent background. I am not sure how to do that, but if I had to guess, it would be Enviroment’s background_mode setting.

That’s most of the stuff I know on topic of viewports and cameras, hopefully that helps, and I will try to answer if future questions follow. (I havent made this in-engine, so it’s just knowledge)

Thanks for your reply! Perhaps I am misunderstanding you. I am not having an issue displaying the character, the walls, and the floor, I am having an issue with the scaling. when I display the floors / walls at a 45 degree angle, it compresses them slightly:

unfortunately, the only way to get pixel perfect is to scale the z and y axis by sqrt(2). does your solution solve that? Maybe I’m just not understanding it


this is my goal

I found this article. Looks like it might be how they are able to scale it. I’ll have to read into it more, and make the translation to Godot

All of that seems a bit overkill to me, except that godot’s 3D camera has the aspect linked to the aspect of the viewport dimensions so you can’t just make a wider aspect but render into the same resolution, which would completely sidestep all the fancy stuff. (There is an implementation but it was put on hold it seems PR #52232)

If you can implement something like this then you just need a viewport with a lower vertical resolution than normal that’s appropriately squished into a window of the actual aspect you want and you’ll have pixel perfect resolution and the same kind of perspective as enter the gungeon but without any trickery, everything will appear to be where it actually is.

You could potentially use a custom godot build or try to adapt that PR into a GDExtension if you’re up for that.

I don’t know if that article about unity will apply, someone who knows more about the rendering parts would have to tell you if you can mess with the projection like that.

Okay, i understand the problem at hand now, sorry if i dumped some redundant info before. I went ahead and tested my method, yes it does squash it by sqrt(2).

yeah maybe I’ll just make it in 2D, I don’t feel like putting that kind of work in just to get some better lighting. I’ll see if anyone else has something hackey they can do before I move it to a 2D project.

Going 2D is a good option I think, godot has some nice 2d lighting effects even