Convert 2DTexture to Normal Map format realtime.

Hi I’m having some issues with my runtime-loaded normal maps not being filtered properly for iOS. They produce strange shading problems like faces becoming darker than they should. I tried loading in an regular editor-imported copy of the normal map and it looks fine. I think the problem is the texture type is just default when loaded in real-time vs having it set to Normal Map as its Texture Type.

Is there anyway to take a Texture2D, flag/change it to a Normal map in a script, then assign it?

I’m using URP with the default Lit shader btw.

Thanks!

This is the editor imported Normal Map:


vs the real-time one:

No. You cannot mark a texture created at runtime as being a normal map… because textures don’t have a flag that says they’re a normal map. That’s an editor time only thing that’s looking at the texture’s import settings.

However it’s totally possible to have a runtime created texture work as a normal map. Make sure it’s set to be linear when creating the Texture2D.
https://docs.unity3d.com/ScriptReference/Texture2D-ctor.html

Just make sure that last bool is set to true and you’re good to go.

However that means you can’t use the built in UnityWebRequestTexture.GetTexture() or any of the other existing tools for loading textures at runtime. They always create the Texture2D as sRGB (aka that linear bool set to false) and you can’t change it after it’s been created. So you either need to use a different method where you load the texture’s raw bytes, or copy the texture mips using Graphics.CopyTexture() into a Texture2D you create manually.

See this thread:
https://discussions.unity.com/t/848366/9

5 Likes

Thanks! This seems to have worked perfectly! I hadn’t noticed there was an overload like that for the Texture2D constructor.