godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
88.96k stars 20.18k forks source link

Volumetric Fog shows artifacts at camera edge at certain angles inside Fog Volumes #74790

Open Lippanon opened 1 year ago

Lippanon commented 1 year ago

Godot version

v4.0.stable.official [92bee43ad]

System information

Windows 10, Vulkan

Issue description

Closer to the edges of Fog Volumes (but still at reasonable distance) certain camera angles will display very noticeable artifacts that cover part of the camera. None of the project settings related to Volumetric Fog or Environment settings seem to alleviate the problem. Camera's near plane value also doesn't seem to help.

Keep in mind, the camera is still clearly inside the fog volume. The problem occurs in all axes.

Steps to reproduce

It's visible in the editor in the MRP, position the camera near the edge of the FogVolume and look around as shown.

Minimal reproduction project

volfog bug.zip

Posting video at bottom because anything after seems to get eaten by github for some reason.

clayjohn commented 1 year ago

Looks like a culling issue to me . I wonder if the FogVolume is getting culled when it is still intersecting the camera's frustum.

Lippanon commented 1 year ago

Looks like a culling issue to me . I wonder if the FogVolume is getting culled when it is still intersecting the camera's frustum.

I wasn't sure how to test this, but I tried editing:

Unrelated but my webm previews stopped working, though opening the video link directly shows it's still valid, don't know how to fix the OP.

idchlife commented 1 year ago

This is a very severe issue IMO.

I have this as well and I don't know any workarounds.

Slight look left/right/up/down cuts fog like in video provided by @Lippanon

Basically FogVolume is unusable for now. I can't add it to a long corridor because of this issue.

Any idea how to overcome this?

Latest version, 4.1.1

Lippanon commented 1 year ago

I would also appreciate any tips on where in the codebase to make changes to narrow the source of the bug.

clayjohn commented 1 year ago

You can look here for the shape in the shader

https://github.com/godotengine/godot/blob/970be7afdc111ccc7459d7ef3560de70e6d08c80/servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl#L201-L206

And here is where the AABB is calculated in froxel space

https://github.com/godotengine/godot/blob/970be7afdc111ccc7459d7ef3560de70e6d08c80/servers/rendering/renderer_rd/environment/fog.cpp#L665-L688

idchlife commented 1 year ago

I can also mention that this bug occurs even with shader material instead of fog material.

viksl commented 1 year ago

Hi, would you mind making a screenshot and putting it here, the video is down, or put the video on youtube perhaps?

idchlife commented 1 year ago

Hi, would you mind making a screenshot and putting it here, the video is down, or put the video on youtube perhaps?

@viksl you can play it via direct link: https://github.com/godotengine/godot/assets/115422160/761a49d5-b2a5-4c54-8adc-85a2dfa93b71

viksl commented 1 year ago

I tried putting another fog volume next to it to see better if it also happens, it does happen too, here're screenshots of it happening step by step:

obrazek obrazek obrazek

As you can see in the last one it gets cut of around the camera edge, pretty much no setting has any influence on this. I'm not sure it's related but it might help someone to debug this?

EDIT: Also this only happens when there's the fog volume with negative density to cut off the shape, without that it's fine.

EDIT2: You don't even need the cut off fog volume as shown here, this is just camera positioned to get a cut off like this (the entire screen should he covered by the fog as in the second picture - same position just different camera rotation): obrazek obrazek

density_only_map and light_only_map show black areas when this happens in case anyone is interested.

Mervius commented 1 year ago

You might be able to work around it by using the global shape and having a shader that cuts off the fog based on certain global positions. Managed to get a local disc of fog that way that doesn't flicker with camera movement. It's kinda janky, but is only a few extra lines of code in the fog shader,

viksl commented 1 year ago

The problem with this it's not related to the cutting the fog off. So if someone uses fog volumes this will be happening to them too even without the negative density. When you move your camera in a certain way (not difficult) and then move into the fog the fog will be disappearing until it's almost all gone unfortunately :'/.

Mervius commented 1 year ago

The problem with this it's not related to the cutting the fog off. So if someone uses fog volumes this will be happening to them too even without the negative density. When you move your camera in a certain way (not difficult) and then move into the fog the fog will be disappearing until it's almost all gone unfortunately :'/.

Yes, it doesn't seem to happen with the global shape, so you can essentially cut off that shape in the shape you originally wanted in a shader. So if you wanted a cylinder, you set the density of every space in world coordinates that's further than some distance from a defined point on two axis to nothing

Calinou commented 1 year ago

I can confirm this on 4.2.dev 6758a7f8c (Linux, GeForce RTX 4090 with NVIDIA 535.98).

Note that disabling temporal reprojection doesn't fix the issue. Here are videos with volume size and depth both set to 512, to make it clearer:

https://github.com/godotengine/godot/assets/180032/e980bf3f-f35f-49d6-97c1-5d42655cd4e1

https://github.com/godotengine/godot/assets/180032/728853c5-ca74-4733-bea7-f9037216195b

viksl commented 1 year ago

Here's the full issues I was describing, notice you don't need two fog volumes to cut off one, also notice how the fog gets completely cut off around camera edges: https://youtu.be/PlpQ7BNlEz4

It also happens when you are outside the fog, it's just more difficult to spot, though at some angles it's quite glaring, here's one when it would be difficult: obrazek On the left the blue lines are a corner, it should be full of fog, no fade and full density settings. In a different angle you can see the whole fog volume with fog but the end part cut off (not a length setting issue) too.

viksl commented 1 year ago

Just want to ping everyone to check something out, if you switch the lines:

min = Vector3i(int32_t(fog->width) - 1, int32_t(fog->height) - 1, int32_t(fog->depth) - 1);
max = Vector3i(1, 1, 1);

For these:

min = Vector3i(0, 0, 0);
max = Vector3i(int32_t(fog->width), int32_t(fog->height), int32_t(fog->depth));
// I don't think the loop to find the max and or min is necessary with this since your assign the max and min values here which the point can go beyond anyway.

All the issues go away for me at least. This is likely not the solution but it might help you figure out where to look at. The froxelization function might be the first candidate to check as Clay mentioned above.

EDIT:

To check the shapes in the shader code I extracted the calculations to a shader code and used it with the FogVolume which had Shape set to World (Global) and all of these worked as expected so I guess this part of the code as suggested by @clayjohn above is probably ok and the issue might be in the froxelization, fog_near_size, fog_far_size, the fog shader or both the cpp and the shader approaches as clay suggested. The test files are here in case you want to test it or use in your project until the volumes are fixed: https://github.com/viksl/GodotFogVolumes

SA-Lowell commented 10 months ago

Definitely hoping this gets fixed soon. I'm working on a small teaser for my game and this is becoming very glaring. I'll likely use the provided codebase workaround in the meantime for any stuff I want to show off.

ecmjohnson commented 9 months ago

I believe the culling behaviour is incorrect as @clayjohn mentioned: it is not sufficient to consider the fog volume's corners when determining the range of froxel cells to run compute on. I think this particular failure case is illustrated in the below diagram:

PXL_20231212_013904800

When fog corner A is clamped to the view frustum corner C, the minimum value from the visible far fog volume corner results in a portion of the fog volume being ignored. You can see this in-engine because the boundary of the artifact is inline with the far fog corners (see below). Slightly rotating the camera can result in fog corner A suddenly clamping to frustum corner B and then things work as expected since this gives a minimum value of 0.

issue_clarification

I'm still not sure what the solution is, but I should be able to come up with a proposal soon