godotengine / godot

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

Glitchy light behaviour on gridmaps in GLES2 and GLES3. #26269

Closed EzraT closed 5 years ago

EzraT commented 5 years ago

Godot version: Godot_v3.1-beta7 Retested in 3.1-RC1, same results.

OS/device including version: Linux Mint 19.1 NVIDIA GP106 [GeForce GTX 1060 6GB], Driver version: 415.27

Issue description: Lights (OmniLights in this case), do not seem to render correctly on GridMaps while using GLES2.

Steps to reproduce: Place lights in any scene that has a GridMap in it, and test using GLES2.

Examples: 02

01

EzraT commented 5 years ago

After some more testing I also found out this sometimes happens in GLES3 as well, just a lot less often than it does in GLES2.

gles3

Retested in 3.1-RC1, still present.

eon-s commented 5 years ago

I cannot reproduce using the kinematic demo and omnilights, can you add a minimal project where you can reproduce it? otherwise this will be hard to test and solve.

Also, looks similar to this old issue #8651.

EzraT commented 5 years ago

@eon-s Reproduction Project: lightbug.zip

After opening it, select OmniLight8, and focus the camera on it with F. After that orbit the camera round it with middle mouse button. It can be a little tricky to get the glitch to show up, the angles are a bit specific, but I can reliably reproduce it this way.

eon-s commented 5 years ago

Using 3.1RC1 On Ubuntu with amdgpu on R5 and GLES3 cannot reproduce it. On GLES2 got this: lightbug See the strange effect on both lights on the floor when looking down.

avril-gh commented 5 years ago

can confirm on build 59aa79f2182c070a7f2c274072da50a5a2934e70 Windows7 x64 GT720 Gles2

1032019_2255_41 color degradation on image is from gif compression. It does not apear in original

EzraT commented 5 years ago

Here's another example: 05 It is much much harder to reproduce in GLES3, but I can sometimes do it on my main project, as shown above.

EzraT commented 5 years ago

Another example of this happening in GLES3: Video

From what I understand, (correct me if I'm wrong), GridMaps are baked into several bigger chunks at runtime. (?)

Originally posted by @reduz in https://github.com/godotengine/godot/issues/3850#issuecomment-320367901

Maybe this explains the weird light seam shown in the video above?

Whats weird about this is that, after editting the gridmap around the area where the problem occurred, (I just removed, and then re-added one of the tiles), it made the seam go away. So what is happening here? Shouldn't the lighting always be stable no matter how the GridMap is baked?

Update: After calling make_baked_meshes in the ready() function of the GridMap, the problem appeared again.

Megalomaniak commented 5 years ago

looking at image in https://github.com/godotengine/godot/issues/26269#issuecomment-470044288

It looks to me like polygon normals get flipped...

clayjohn commented 5 years ago

Just tested out, this will be fixed by https://github.com/godotengine/godot/pull/30570

EzraT commented 5 years ago

Just tested out, this will be fixed by #30570

Correct me if I'm wrong, but I dont think the PR you linked will fix the gridmap seams problem described in this issue, so this should probably stay open regardless.

clayjohn commented 5 years ago

Can you upload an image showing that? I can't reproduce nor can I see that issue from any of the videos.

EzraT commented 5 years ago

@clayjohn Video <---- This one happens in GLES3 as well.

And: 05 And also: 01

Look closely, the lights are sometimes cut off, visible on one chunk of the gridmap, and invisible on the other.

clayjohn commented 5 years ago

Ah yes! I see it now. Thank you.

Also notice how the one getting cut off is the weird bright highlight? But underneath you can see the original light is fine. Its just another symptom with the same underlying issue. Both issues will be fixed by https://github.com/godotengine/godot/pull/30570

If you are interested. What is happening is that some objects are mistakenly retaining a reference to the light that used to effect them, but then that light is removed from the array, making them instead refer to a light already affecting them twice. However, this happens on a per-object basis, so some objects are being lit twice, while their neighbouring object isn't, resulting in the sharp lines.

EzraT commented 5 years ago

Are you sure? The first video in my reply shows an instance of this happening in GLES3, so I doubt that's the case. I thought the light reference issue only happened in GLES2.

clayjohn commented 5 years ago

I didnt realize that one was GLES3. It looks like the same underlying issue. It is still doubling up light intensity but only on a specific object.

Im gonna try to reproduce on GLES3.

edit: Can't reproduce in GLES3 I think that issue you are having is unrelated. In that video sections of your mesh are going dark. We need a separate issue for it. As well as an MRP where it can be reproduced.

EzraT commented 5 years ago

Okay, after trying to reproduce this more I think I know what causes the lights being cut off, its Godot's hard limit of 8 lights per mesh, apparently I'm just using too many lights in my scene. When I lower the amount of OmniLights, the seams dissapear.

So to sum up what I think happens here:

When editting GridMaps in the editor, the gridmap itself is not baked, meaning every cell of the map is treated as its own MeshInstance.(?) But at some point, I'm not entirely sure when this happens, Godot bakes GridMaps into larger chunks, (Source) if there are more then 8 Lights cast on one chunk, and less than 8 on the other, any light cast on more then 1 chunk, results in that light being cut off at certain camera angles.

So I think this is probably a side effect of how lights work in Godot's current renderer, its unfortunate if thats the case. I hope this limit can eventualy be raised or lifted in the upcoming Vulkan renderer, because this is quite limiting for lighting on GridMaps.

clayjohn commented 5 years ago

Good detective work!

That does seem like a frustrating situation. I think the plan for Vulkan is to allow for many more lights per object. As for 3.2, we should see if there is a way to make max number of lights per object a project setting or something.

edit: Here is where the 8 light limit comes from https://github.com/godotengine/godot/blob/8234f5c5a4a51bd67e687556bd54962b2e3f1489/drivers/gles3/rasterizer_scene_gles3.cpp#L5186

EzraT commented 5 years ago

Thanks to you and @SonerSound for the GLES2 fix! I'll see if I can circumvent this problem in the meantime by using a BakedLightMap.

jamie-pate commented 4 years ago

Still getting this behavior in GLES3 in 3.2-stable.

interestingly, setting this code a few frames after _ready cell_octant_size = cell_octant_size seems to fix the issue! I've created a script on the container for my GridMesh nodes to do this automatically:

extends Spatial

func _ready():
    yield(get_tree(), 'idle_frame')
    for c in get_children():
        if c is GridMap:
            # rebuilds gridmap and fixes lighting
            c.cell_octant_size = c.cell_octant_size

See https://streamable.com/22j0z (How it looks without this workaround)

jamie-pate commented 4 years ago

Thanks to you and @SonerSound for the GLES2 fix! I'll see if I can circumvent this problem in the meantime by using a BakedLightMap.

imo BakeLightMaps + GridMap = disaster. (if your gridmap tiles are even slightly complicated, it bakes the gridmap and super-bloats your scenes)

EzraT commented 4 years ago

imo BakeLightMaps + GridMap = disaster. (if your gridmap tiles are even slightly complicated, it bakes the gridmap and super-bloats your scenes)

You are correct, I did not manage to get good enough results with BakedLightMap, by now I think most people are aware already that the current Lightmapping implementation in 3.x is kinda bad. reduz has also said this, hence the upcoming re-write for 4.0, which will be much much better.