I’m trying to do something that looks vaguely like Minecraft, though not quite as extreme. I started with a 32x32 tile, adjusted the texture to use nearest neighbor filtering, and created a basic material from that. Trouble is, mipmapping really destroys the texture after a short distance:
Turning off mipmapping leads to flickering lines probably related to anti-aliasing. I tried all the different mipmap settings with no improvement.
Then I simply resized the original to one big 512x512 tile with an external program using the nearest-neighbor algorithm, which gave me vastly better results:
That’s not a terrible workaround, but ideally I’d like to continue using the original 32x32 textures as is. Is there any way to achieve the same results within UE4 with a tiny pixely texture? Perhaps by adding something in the material?
Hey, there are a few solutions you could try. First would be to set the texture sample MipValueMode to “MipBias” and try using negative numbers in the bias. -1 would go back 1 mip distance level, and so on.
The other approach with much more control would be to set “MipLevel” then add a material function called “ComputeMipLevel”, and supply your UVs, and then just input the size of the texture for “TextureSize” that you want the engine to think the texture is. I am not sure in this case but I think you will want to pretend the texture is smaller than 32x32 to push the mips out further. Maybe try 16x16 or 8x8 and see what that looks like.
ComputeMipLevel was actually created to solve a slightly different problem. Sometimes operations that create sharp transitions in the UV value can cause mip maps to do bad things like try to blend to the lowest mip level across a 1 pixel border. In cases like that, you can just recreate the exact mips from a continuous version of the UVs, as long as the scale of the UV’s is relatively the same.
Practically speaking, you are probably best “embigenning” your texture to at least 64 or 128 but I doubt you need to go as high as 512.
Trying different sizes in ComputeMipLevel didn’t make much of a difference.
I get similar results even with larger textures using Nearest filtering. Admittedly I don’t know enough about 3D rendering to say exactly what the problem is, just that a manually resized 512x512 texture with Linear filtering is still the only thing which looks nice both close up (even 256x256 is a bit blurry) and at a distance.
If you do computemiplevel with the actual texture resolution plugged in, the MIPS should look exactly like your first screenshot. Maybe you still has it set to mip bias and not mip level on the same mip mode?
Something worth trying is turning off mip-mapping and blending between two or more versions of the texture with less and less contrast but at the same resolution. You could also do some slight bluing. The lowest contrast one would be used furthest away (this could even be a solid color at far enough a distance) and then fade to more contrast the closer to the camera you get. It would be a sort of manual mip-mapping with a lot more control.
I did something similar by fading to a solid average color of the tiles in a minecraft ratracer to lessen the noise on blocks far away without needing to use an insane amount of rays and it worked quiet well.
Ah ok, sorry. That is what I thought you wanted. That method will only push the mips in or out, it won’t really improve the quality or change what they look like. That’s why I suggested maybe you could try a hybrid approach where you increase the res to 128 or 256 and push the mips out a little bit also.
What Parkar is suggesting is also a good idea. You don’t need to have a separate version of the textures without contrast though, just lerp between the texture itself in A and the texture with a Power and exponent less than 1 for B. For the alpha use the material function CameraDepthFade. It lets you create a depth gradient with offset.
As the exponent gets closer to 0, the result approaches white (1.0). So you might want to try Lerping to a solid color representing the average brightness value of the texture, or darkening the power result instead. Many combinations of possibilities to fix this problem. You could clamp the cameradepthfade also to only partially do this.