Got it!
I finally understand what the problem actually is and why this happens!
Thanks again to everyone who took the time to help me with my question.
Really appreciated!
TL;DR
So…
If you’re interested -like me- in understanding what’s happening here and -more importantly- WHY it happens… You’re -of course- in the right place.
It all started with this CodePen, which I’d already shared previously:
At first, it wasn’t clear to me how the fwidth
function could perfectly detect and highlight where these artifacts were appearing.
It obviously wasn’t a coincidence; it had to be part of or somehow related to the problem, I thought.
And I was right.
Setting aside the details of how fwidth
works and the complex math behind it…
I found that the values this function handles are also the main components of the internal function responsible for determining which mipmap level to use for each texel.
Take this example:
Here I’m rendering the texture as-is, without any additional processing…
If you move the camera around with your mouse, you’ll probably notice that the more you view the plain at an angle, the blurrier the texture gets.
That’s -of course- due to mipmaps!
But HOW does the computer know which level to apply to each texel?
Try the same thing with this:
See the pattern?
The higher the fwidth
value, the blurrier the mipmap becomes. That’s it.
But again… Why these artifacts, then?
When you render a texture “the-simple-way” (texture2d(map, uv);
), as I did in my second CodePen, you leave the task to the computer (or rather: to the GPU) to automatically detect the correct mipmap level.
Do to so, it calculates these internal values (used also by fwidth
) based on the difference between the UV coordinates you pass to texture2d
for a specific texel and those for the adjacent texels.
When tiling is used -of course- each texel on the tile border will have a large difference compared to adjacent tiles’ ones.
THAT’S WHY in my first CodePen, fwidth
highlights those texels!
And that’s WHY these artifacts appear!
Usually, the smaller the mipmap, the more the colors blends together.
That’s why the artifacts have always been an average color of the entire texture!
«Mmmh… Ok… So how do you solve this?»
There are two different ways.
The first one is to force a specific mipmap level (called “Level of Detail” or “LOD”).
The lower this number is, the clearer the mipmap level will be used.
Here’s an example:
The “problem” with this solution is that it essentially disables mipmapping altogether, similar to using NearestFiltering
.
The second one -however- is to tell the GPU which LOD to use without letting it automatically compute it.
Here’s an example:
As you can see, in this case, when you move the camera around, you’ll still see mipmaps in action.
With this example texture, the result may not look as ideal as it could.
In my case, where tiles are more similar and uniform, the result is simply stunning!
For a scenario like this, I’d suggest writing an even smarter shader to achieve a better result.
Maybe, I’ll work on this in the future.
I’d probably start by merging this logic, in some way, as well:
If you’ve read this far, thank you for your time and patience in following my thoughts and my less-than-ideal English.
Thanks again, everyone.