godotengine / godot

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

Visible seams between GridMap tiles (sometimes only with MSAA enabled) #16337

Open ghost opened 6 years ago

ghost commented 6 years ago

image

Is hard to see. You need to open the image full size. There are no visible seams with MSAA Disabled but with 2x or higher I start seeing seams and edges of 3D meshes.

My guess is the texture or mesh is shrunk by a small factor in order to produce the edge aliasing.

I use a Gridmap is a cell size 1 , 1 , 1 and the tiles are all designed to be exactly 1 x 1 x 1 and the UV maps are made exactly to the dot for 64 x 64 textures.

This is on latest Godot 3.0 release

TomWor commented 6 years ago

Also happens on mesh edges, maybe related to unfiltered textures? I have a repo here with a demo: https://github.com/Worgames/superspacearcade_godot screenshot from 2018-06-29 23-17-32

reduz commented 6 years ago

There is a cell_scale property you can use, with some values like 1.001 that will get rid of these problems.

reduz commented 6 years ago

Maybe we should document this better?

Bauxitedev commented 6 years ago

Try disabling Compress on the import settings of your .dae and re-generate the MeshLibrary. That did the trick for me.

TomWor commented 6 years ago

@reduz cell_scale is only relevant to grid map right? I have the same issue on an imported dae mesh.

@Bauxitedev I deleted the generated meshes, removed the "compress" attribute from the import settings and reimported the mesh - sadly, the issue remains.

randomness128 commented 6 years ago

Are you using a texture atlas? With MSAA, the primitive doesn't have to cover the center of the pixel to be visible, but shading is calculated at the center of the pixel regardless. This can cause interpolated vertex attributes (such as UVs) to instead be extrapolated for a point slightly off the edge of the primitive. This is an issue with MSAA in general, not Godot. Try moving your UVs slightly inward so extrapolated UV coordinates will still use the same texel.

reduz commented 6 years ago

@Bauxitedev I disabled vertex compress by default because many were having issues with it, left compress of other stuff

@TomWor If you are using a recent master, i fixed this by disabling vertex compression by default

TomWor commented 6 years ago

@reduz Would love to test, but my current build of master closes the game window instantly on play. Works fine with the current 3.1 alpha though (not counting the MSAA issue). Should I even open a bug for this as it's master and no official release?

bojidar-bg commented 5 years ago

What is the state of this issue?

EzraT commented 5 years ago

This still happens for me using 3.1 Beta 10, using a texture atlas and uncompressed meshes. The seams only appear when MSAA is enabled, doesn't matter what level. I tried adjusting the cell_scale property in my GridMap, but it does not get rid of the seams, it only introduces slight, (but still noticable) clipping issues.

UPDATE: No MSAA: no_msaa MSAA: msaa

TomWor commented 5 years ago

I think I can confirm that @randomness128 is right at least about the issue I'm facing. I'm using a texture atlas and because of the nature of it (voxel-style, nearest neighbour) the pixels bleed over. I exported the same model with vertex colors and the problem was gone. (which sadly is not a solution for me because it yields to many vertices) I also want to mention that this doesn't happen in Unity, their MSAA algorithm must do something different. Maybe the problem happens because the texture atlas doesn't repeat itself at the edges or something?

Calinou commented 5 years ago

@TomWor Is the issue lessened if you slightly expand/shrink your meshes but keep the textures at the same size?

akien-mga commented 4 years ago

Does this still happen in latest 3.2 builds? If so, does it happen with both GLES2 and GLES3? Finally, if you can reproduce it, please upload a minimal reproduction project that shows the issue.

EzraT commented 4 years ago

Reproduction Project: msaa_seams.zip

Very obvious seams, only when MSAA is enabled. Tested in both GLES3 and GLES2 using 3.2 beta 5, and a nightly build: 7f56ef365, same results for both.

Updated with a screenshot: image

Calinou commented 4 years ago

@EzraT Is the issue lessened if you slightly expand/shrink your meshes but keep the textures at the same size?

EzraT commented 4 years ago

@Calinou No, not really, as far as I can tell that just introduces more problems, z-fighting flickering or physical seams between the meshes, along with the texture seams discussed here.

AlexFlasch commented 4 years ago

I'm unsure if its related, but I'm also getting some jittery artifacts along seams only with MSAA disabled. I'm hesitant to report this example as an actual issue, as I haven't ruled out external causes (assets, GridMap settings, Camera, etc) for the odd artifacting displayed here. You can see it here just to the left of the player.

The seams become permanently visible with MSAA enabled very similarly to examples that have already been provided. image

Both the video in the link above as well as the attached image were taken while running 3.2.3.rc1 on win10 with a GTX 1080 Ti.

My GridMap settings in the attached media have a cell size of Vec3(2, 2, 2), and cell scale of 1.

Our game intends to make fairly heavy use of the GridMap node, so this is a bit of a sticking point for us. Has anyone else with this issue found any workarounds that can help mitigate the issue?

We've tried slightly increasing cell scale to 1.001 as well as modifying cell size by small increments as well, but unfortunately they didn't seem to help.

Calinou commented 4 years ago

Has anyone else with this issue found any workarounds that can help mitigate the issue?

Try adding a green plane (with the same color as the grass) below the GridMap floor to make seams less visible.

AlexFlasch commented 4 years ago

Try adding a green plane (with the same color as the grass) below the GridMap floor to make the seams less visible

Thanks for the suggestion! I just tried that out, as well as making a plane that just barely sticks out near the top of the grass tile in the MeshLibrary itself, and unfortunately it doesn't seem to have had any effect.

Here is the size of the plane I used just beneath the GridMap (changed to blue to show that it stretches across most of the GridMap.) image

With the top face of ground level tiles in the GridMap being at Y coordinate 2.0, I changed the plane to be the same color as the grass, and moved it to Y 1.999, and I'm unfortunately still able to see seams. (You can see where the plane ends when its just underneath the GridMap tiles at the top of the picture) image

Calinou commented 4 years ago

cc @lawnjelly

lawnjelly commented 4 years ago

This is very probably due to precision issues due to floating point error in the matrix math. Normal rendering hiding it and anti aliasing showing it up. I seem to remember answering a similar problem for the voxel addon guys a few months ago.

As reduz says, aside from merging vertices, a common solution is adding a small increase in scale for each element, although it has to be applied in the right way (relative to the element centre, not simply a global scale). I'll have a look in the source just to check it's being applied correctly.

Edit: Scale does seem to be set correctly, in the local basis. (unless there's a place in gridmap I missed)

lawnjelly commented 4 years ago

Reproduction Project: msaa_seams.zip

Very obvious seams, only when MSAA is enabled.

In this project the seams look due to texture filtering. You need padding if you are using texture atlas.

Just to clarify - you need padding even without filtering, because of precision error on borders. You can also contract the UVs a little as @randomness128 suggested, this is what we do in GLES batching for the same problem (uv_contract).

There may be 2 problems being discussed here. For UV / filtering issues the above are some solutions. For geometry seams, scaling should help.

Depending on how common the particular workflow is, it is sometimes possible to automate adding padding to atlases and modifying UVs. But I'm not familiar enough with gridmap to give any opinion on this.

AlexFlasch commented 4 years ago

After doing some research on MSAA and how its handled, as well as re-reading randomness128's suggestion after lawnjelly referred back to it, I wasn't able to entirely remove the seams, but they're much, much less noticeable.

Each face of our cubes were 64x64 pixels, and they were stored in one UV map making the entire albedo map 128x128. We initially tried adding a single pixel border around the textures, and adjusted the UVs to be within that 1 pixel border. For some reason this seemed to actually make the seams even more noticeable (at least on 2x MSAA)

But when we added a 10 pixel border around the entire albedo map, and reassigned the UVs to wrap the initial 64x64 textures we've gotten this instead. image

(side note, the remainder of the seams near the player are still present because the padding hasn't yet been applied to all tiles in the mesh library)

Here is a comparison of how our original and padded albedo map looked to get our results in case anyone stumbles upon this issue in the future. image

The seams are still slightly visible in the top left corner of the world, but I think this should suffice. 😄 Worst case we can add a bit of a vignette or some sort of post processing to help cover up the remainder of it.

AlexFlasch commented 4 years ago

As a separate suggestion:

I'm not very familiar with the specifics with modern OpenGL, but would it be possible to have a GL_CLAMP_TO_EDGE type flag for materials to somewhat emulate this padding effect? I'm unsure if that would positively affect the MSAA, but it seems like it could help with it grabbing similar colors when it tries to sample outside of the UVs.

lawnjelly commented 4 years ago

As a separate suggestion:

I'm not very familiar with the specifics with modern OpenGL, but would it be possible to have a GL_CLAMP_TO_EDGE type flag for materials to somewhat emulate this padding effect? I'm unsure if that would positively affect the MSAA, but it seems like it could help with it grabbing similar colors when it tries to sample outside of the UVs.

Unfortunately CLAMP_TO_EDGE only works for the absolute edges of textures, so won't help with texture atlases (it can help with non repeating regular single textures though). Texture arrays can also be used to solve this instead of atlases, but they aren't available in GLES2.

We initially tried adding a single pixel border around the textures, and adjusted the UVs to be within that 1 pixel border. For some reason this seemed to actually make the seams even more noticeable (at least on 2x MSAA)

Also note texture compression can affect this. Texture compression tends to work in blocks (I believe 4x4 is common) and if your atlas edges span a block this can result in artifacts on edges. Using uncompressed textures or better still avoiding these edges can help here.

i.e. If you original atlas tiles were 64x64, make them 68x68 including 4 texels of padding, giving 8 texels between the actual tiles (or use 8 texels of padding etc).

Also for 3d, you should consider the effect of mipmapping. Mipmaps are made at 1/2, 1/4 etc sizes of the original texture and are shown as you move further from the texture. So padding which might be ok up close may still end up showing seams as further mipmaps are shown. The solution to this is to increase the padding to take account of it (obviously there's a limit, as the furthest mipmap could be just 1 texel!).

Calinou commented 4 years ago

It's possible to clamp UV coordinates using a shader, but this has a performance cost. See also https://github.com/godotengine/godot-proposals/issues/651.

Calinou commented 2 years ago

Like for https://github.com/godotengine/godot/issues/35067:

Would centroid sampling be able to alleviate this? I don't know if it's available in GLES3 though. If it's likely limited to desktop OpenGL only, would have to be conditionally added on shaders on desktop platforms only (which would add a fair amount of complexity).

Centroid sampling is definitely not available in OpenGL 2.x/GLES2.

More information on centroid sampling: https://www.rastergrid.com/blog/gpu-tech/2021/10/multisampling-primer/#:~:text=be%20aware%20of.-,texture%20sampling,-We%20talked%20about

TokisanGames commented 2 years ago

One of these three solutions provided by clayjohn and lawnjelly may fix this issue. https://github.com/godotengine/godot/issues/35067#issuecomment-1058617216

czlowiekimadlo commented 1 year ago

I have recently encountered this issue in 3.5.1. I'm using models made in MagicaVoxel, then processed in blender to reduce geometry. Seams on tiles are bad enough, but I'm also getting this on more complex objects (like ruined buildings) placed on map, and it is quite jarring. Since those are quite complex, padding the texture is not an option for me, it would take dozens of hours of manual work.

What is more interesting to me is that even with MSAA disabled, I am still getting this issue, although way, way less. I think the bug might actually not be linked to MSAA, and it only makes it more visible.

LunaticWyrm467 commented 1 year ago

I'm also getting a similar issue, and it's quite bad on lower resolutions. Edit: this is on Godot V4 Stable image

FaerDerr commented 1 year ago

Can confirm, gridmap is showing weird artifcats even in godot 4.0, and scaling the size doesn't seems to change much : image

Calinou commented 1 year ago

@LunaticWyrm467 @FaerDerr Please upload a minimal reproduction project to make this easier to troubleshoot.

Note that if using a texture atlas (like in @EzraT's MRP), this is due to texture filtering not working correctly due to missing padding between atlas tiles: https://github.com/godotengine/godot/issues/27837

I've updated @EzraT's MRP for 4.x for reference, and can confirm the issue still occurs with MSAA enabled. However, that MRP uses a texture atlas, so the cause is different as I mentioned above.

msaa_seams_4.x.zip

LunaticWyrm467 commented 1 year ago

Gridmap_Seams.zip

MRP up above ^ (Requires walking around (arrow keys) and grid seams will occasionally be visible. Modifying the angle of the DirectionalLight3D also has some effect towards revealing more/less seams.

Note: I think this might be an issue with decimal precision, as my game relies on each grid cell to be of the size 1 x sqrt(2) x sqrt(2) due to the top-down perspective.

Zylann commented 1 year ago

Both issues occurred when someone tried MSAA in my Minecraft-like demo:

The error renders the same size in screen space, so if a correction were to be done, it would have to support all view distances by not looking weird at close range and not happening again when far away.

In my case this happens within the meshes, which are chunks of voxels, where voxels are not necessarily cubes and can have been UV-mapped in Blender, so finding an easy algorithm to automate a fix that would work at any view distance doesn't sound straightforward.

elvisish commented 1 year ago

I'm having this problem a LOT: image

What's the current workaround to minimize seams?

Calinou commented 1 year ago

What's the current workaround to minimize seams?

Several workarounds are mentioned in the above comments, outside of disabling MSAA and using another antialiasing solution.

elvisish commented 1 year ago

What's the current workaround to minimize seams?

Several workarounds are mentioned in the above comments, outside of disabling MSAA and using another antialiasing solution.

I'm not using MSAA and I can't using antialiasing as it's a retro game. I'm using gridmaps with MeshInstance boxes that are 1 1 1 and use ShaderMaterials, not atlases. It only happens really when I move around, is there a fix for this?

J0Beck commented 1 year ago

I had a similar issue, I tried rotatin the gridmap along the y axis a couple of degrees and that helped reduce the number of lines

BurningFluffer commented 10 months ago

I have this too. The meshes are made with perfect snap in blender, but gridmap often places them with gaps. Disabling MSAA did not help. Scaling also doesn't help, since that straight up makes the planes missalign, though I would expect them all to remain centered - is the problem with how GridMaps determine cell center? Edit: Nvm, scaling my meshes would make them missalign, but expanding them in proper directions in Blender also didnt help. It seems to be an issue with rotation - quatornions are very impercice. Do they use trigonometry or just +- flips on axis? I imagine the latter would not have as much inpercision.

CammiePone commented 8 months ago

Can confirm that it's still a problem on 4.2.1. I haven't tested 4.3's rcs yet, so I don't know if a change there may have magically fixed it. I've tried everything people have suggested here and nothing really fixes it, or even noticeably reduces its effect

Hopefully this can get figured out and fixed soon

https://github.com/godotengine/godot/assets/16853086/5854b946-01df-4f2e-bf61-7b3465ea1fd3

BurningFluffer commented 8 months ago

I've discovered that there was a issue with blender that was causing it in my case. Even if based on the default cube and snapped to it, verteces are NOT in perfect positions. Instead, each vertex should be given position manually in the tool tab (key N to see). Assigning them manually fixed it in my case. However, Kinematic character is unable to slide down without periodically hopping, unlike sliding in any direction that isn't same as gravity. Idk if that's gaps, or just a issue with GridMap+Kinematic body.

CammiePone commented 8 months ago

I wish i could say it was a blender issue for me, but it's also visible on the default box mesh made in Godot itself

CammiePone commented 8 months ago

so a friend of mine has discovered something that might help with fixing this. apparently this occurs only when the meshes that are next to each other have side-facing geometry. if i just have a plane, this doesn't happen

elvisish commented 8 months ago

so a friend of mine has discovered something that might help with fixing this. apparently this occurs only when the meshes that are next to each other have side-facing geometry. if i just have a plane, this doesn't happen

Thanks, I use plane meshes to cover up the worst looking of these that occur, but for games built with cubes with sides that are darker/lighter or have different textures the problem still remains.

BurningFluffer commented 8 months ago

apparently this occurs only when the meshes that are next to each other have side-facing geometry

It feels like that kinda forces the marching cubes approach, where there is only the geometry actually needed for the total shape. I suppose the cubes need to be separated into individual planes, and you combine planes instead of blocks. Would definately make it more of a hassle.

robbyph commented 4 months ago

I am experiencing this issue in Godot 4.2.2

I am using a texture atlas on my gridmaps, however, I am not using MSAA of any kind, and MSAA is completely disabled. The gridmaps use a MeshLibrary (.tres) created in Godot based off of a .glb file exported from Blender. These meshes in my gridmap snap together perfectly fine in Blender, but not in Godot.

If it would be helpful, I used this tutorial here. He even mentions this issue with the gaps at the end of the video.

I have tried:

I've also noticed that most of these artifacts are most visible at the periphery of the Player's vision, as you can see in the attached images. It's really most noticeable though, when the player is moving around.

floor walls

Calinou commented 4 months ago

I am using a texture atlas on my gridmaps, however, I am not using MSAA of any kind, and MSAA is completely disabled.

This is an unrelated issue, and one that will happen on any real-time engine that uses mipmaps for rendering. You need to add padding between the textures in the texture atlas so that mipmaps don't cause different textures to blend together. How much padding you need to add depends on the individual tile size, but typically, you want at least 4 pixels on each side. These pixels should repeat the base texture as usual (or at least use the average color of the texture).

You can troubleshoot whether mipmapping is the cause by disabling mipmaps on the atlas texture in the Import dock. This will cause textures to become grainy at a distance, but if the cause is indeed due to the texture atlas, the lines should be gone.

robbyph commented 4 months ago

You can troubleshoot whether mipmapping is the cause by disabling mipmaps on the atlas texture in the Import dock. This will cause textures to become grainy at a distance, but if the cause is indeed due to the texture atlas, the lines should be gone.

I tried disabling mipmaps on the atlas texture, however, the lines are unfortunately not gone.

Calinou commented 4 months ago

Do lines disappear if you switch the material filter mode to Nearest in the BaseMaterial3D properties? (If the material was imported from Blender, you need to change the filter mode in Blender, or assign an external material from Godot.)

robbyph commented 4 months ago

Do lines disappear if you switch the material filter mode to Nearest in the BaseMaterial3D properties? (If the material was imported from Blender, you need to change the filter mode in Blender, or assign an external material from Godot.)

That was it! I had my stuff set to cubic, rather than Closest, which is what I believe it's called in Blender. After switching to Nearest there are no gaps!

If you wouldn't mind, could you explain to me a bit further why changing the filtering mode to Closest fixed this? I assume it has something to do with the atlas and the bleed you said before?

Additionally, I was using the Cubic filter in order to make my texures blurry and not so pixelated. Is there a way to have both?