We have a solution. It’s clearly a rare problem else this thread would be swarming with replies and abundant answers would float easily to the top of Google searches. Since neither is true, it’s been a lot of digging to solve this, so I’m recording the solution here in the hopes some other poor soul will find their answer more easily than I did.
The Solution
The solution is to Import Images as Textures with the following Settings:
Mode: Lossless (I’d previously chosen Mode: Video RAM)
Mipmaps: On
If you’ve already Imported the Textures, simply amend the settings as above, and click ‘Reimport’. Then enjoy correctly rendered Mipmaps in HTML5 on Mobile!
A Fuller Explanation to Help the Answer Be Found
Correctly Identifying the Problem
In my case, and for HTML5 exports on Mobile only, the Texture applied to the Albedo of the Material would appear to fade away to blackness, the further it was from the Camera.
The Material fading with distance behaved in every way like it would be caused by some z-buffer, z-distance, distance culling, distance fog, setting in the Material, the Mesh, the Camera or the WorldEnvironment. This hypothesis led me down some false alleyways and fruitless searching for a solution. I thoroughly explored all the settings for the WorldEnvironment, the Camera, the Mesh, and the Material. No amount of fiddling with distance, proximity, fog, culling, would fix it. The cause was none of these. Finding a solution was made harder by not even knowing what terms to search for.
After some trial and error experimentation I discovered that the Texture on the Material Albedo wasn’t fading to black with distance, it was fading to Transparency. It only looked black because my WorldEnvironment was black.
Finding A Clue
Finally understanding what was really happening allowed me to refine my searches for answers which led me to these two tidbits which led to the true cause and the true solution.
This reply from @Calinou back in 2021 provided the needed redirection:
This discussion on GitHub provided additional nuance:
Because another Material in my world, with identical settings other than the Texture applied to the Albedo, was rendering correctly, and because the Albedo Textures of both Materials were the same size and the same DXT5 RGBA8 format, I’d overlooked the significance of Import Settings. Yet the solution I needed was all about that.
Broken Mipmaps Look Like Distance Fade/Fog
In simple terms Mipmaps are reduced resolution versions of a Texture which are substituted for the full resolution Texture according to distance from the camera. This reduces load on the rendering pipeline and avoids moire patterns, that ‘grainy’ effect when detailed Textures are viewed from a distance using quick and dirty scaling methods. When working correctly the engine seamlessly substitutes these lower resolution Textures and blends between them for a beautiful render.
However, it turns out there may be a ‘bug’ in this version of Godot that means Mipmaps are broken in this situation. For whatever reason they either don’t seem to be generated, or don’t seem to be used in the Mobile HTML5 engine, even if you set the Mipmaps setting to ‘on’, depending on your Import Settings. Consequently the engine appears to go through the motions of substituting lower resolution Textures where objects are further from the Camera, but because the Mipmaps either aren’t there or aren’t properly used, the engine substitutes with nothing (fresh air), so your Material fades to Transparency over distance instead. This ‘looks’ like distance fade, but really it’s that lower resolution Textures for the further away part of your object aren’t being rendered. This seems to only occur in the HTML5 export of a scene on Mobile only.
The Solution
The solution is to Import Images as Textures with the following Settings:
Mode: Lossless (I’d previously chosen Mode: Video RAM)
Mipmaps: On
If you’ve already Imported the Textures, simply amend the settings as above, and click ‘Reimport’. Then enjoy correctly rendered Mipmaps in HTML5 on Mobile!