Skip to content
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

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

Closed
Tracked by #69579
Lippanon opened this issue Mar 11, 2023 · 18 comments · Fixed by #86103
Closed
Tracked by #69579

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

Lippanon opened this issue Mar 11, 2023 · 18 comments · Fixed by #86103

Comments

@Lippanon
Copy link

Lippanon commented Mar 11, 2023

Godot version

v4.0.stable.official [92bee43]

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.

fogvol.bug.webm
@clayjohn
Copy link
Member

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
Copy link
Author

Lippanon commented Jun 20, 2023

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:

  • get_aabb() in /scene/3d/fog_volume.cpp
  • fog_volume_get_aabb(RID p_fog_volume) in /servers/rendering/renderer_rd/environment/fog.cpp
    Doubling the AABB volume didn't seem to affect it.

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
Copy link

idchlife commented Aug 19, 2023

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
Copy link
Author

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

@clayjohn
Copy link
Member

clayjohn commented Aug 21, 2023

You can look here for the shape in the shader

} else if (params.shape == 3) {
// Box
// https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
vec3 q = abs(local_pos.xyz) - half_size;
sdf = length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0);
}

And here is where the AABB is calculated in froxel space

if (volume_type != RS::FOG_VOLUME_SHAPE_WORLD) {
// Local fog volume.
Vector3i points[8];
Vector3 fog_size = Vector3(fog->width, fog->height, fog->depth);
float volumetric_fog_detail_spread = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_detail_spread(p_settings.env);
points[0] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform);
points[1] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform);
points[2] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, -extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform);
points[3] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, -extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform);
points[4] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform);
points[5] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform);
points[6] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, -extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform);
points[7] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, -extents.y, -extents.z)), fog_end, fog_near_size, fog_far_size, volumetric_fog_detail_spread, fog_size, p_cam_transform);
min = Vector3i(int32_t(fog->width) - 1, int32_t(fog->height) - 1, int32_t(fog->depth) - 1);
max = Vector3i(1, 1, 1);
for (int j = 0; j < 8; j++) {
min = Vector3i(MIN(min.x, points[j].x), MIN(min.y, points[j].y), MIN(min.z, points[j].z));
max = Vector3i(MAX(max.x, points[j].x), MAX(max.y, points[j].y), MAX(max.z, points[j].z));
}
kernel_size = max - min;
} else {

@idchlife
Copy link

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

@viksl
Copy link
Contributor

viksl commented Aug 25, 2023

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

@idchlife
Copy link

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
Copy link
Contributor

viksl commented Aug 25, 2023

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
Copy link

Mervius commented Aug 28, 2023

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
Copy link
Contributor

viksl commented Aug 28, 2023

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
Copy link

Mervius commented Aug 28, 2023

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
Copy link
Member

Calinou commented Aug 28, 2023

I can confirm this on 4.2.dev 6758a7f (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:

simplescreenrecorder-2023-08-28_18.46.08.mp4
simplescreenrecorder-2023-08-28_18.46.19.mp4

@Calinou Calinou removed the confirmed label Aug 28, 2023
@viksl
Copy link
Contributor

viksl commented Aug 28, 2023

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
Copy link
Contributor

viksl commented Sep 14, 2023

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
Copy link

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
Copy link
Contributor

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

@ScarfKat
Copy link

Any chance the relevant PR will make it into 4.4? It seems to have missed its chance with 4.2 and 4.3, and would be super helpful if it was merged.

@akien-mga akien-mga modified the milestones: 4.x, 4.4 Nov 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants