I am having problem with normal maps on Android(9.0.6 oxygen OS) Google Chrome (84.0.4147.125).
I have a model in glb format that I load from GLTFLoader in my code. The problem is when I open my app on mobile directional light doesn’t work as expected only when there is a normal map is enabled. Contrary to this the model loads fine and light works correctly on macOS(10.15.4) Google Chrome (84.0.4147.135). I thought it might the problem with the normal map coordinate system. So, I inverted the normal map and the results where correct on Mobile(Android) but not on macOS.
I wan’t to keep materials as THREE.DoubleSide and work with same normal map. I know there is difference between Direct-X and OpenGL coordinate system and having normal maps in one coordinate system gives you opposite results in other. But where I am confused is that why is that happening only on Android. Is it something related to OS? Or I am missing something.
I hope I have explained my problem well. Feel free to question in case you don’t understand.
If you apply no normal map, please try to compute tangents via BufferGeometryUtils.computeTangents() and set Material.vertexTangent to true for the respective materials.
Your issue could be a GPU driver bug which is only fixable by using precomputed tangent vectors (instead of computing them on-the-fly in the shader).
It seems you are using WebPack, right? Please try to use the ES6 module version since all global script files will be deleted at the end of the year. Try it with:
@Mugen87 Yes, you are right. I am using webpack. So, I tried BufferGeometryUtils.computeTangents with material.vertexTangent set to true. Still no luck.
Sure @Balamurugan_Sethuraman , The above code worked for me. Though this problem can be Solved with either code or asset change. About the code not working. I have two suggestions. Now that I have better grip on js and three.js I can see two problems with the code I shared above.
Using traverse function instead of looping through child of the loaded object.
The flag gpuHasFrontFacingDoubleSidedBug is checking the gpu name string for the adreno gpu models between 500 to 699.
Here is the updated code for 1.
CheckDoubleSideIssue: function(object3D){
var gpuHasFrontFacingDoubleSidedBug = false;
var debugInfo = this.renderer.getContext().getExtension('WEBGL_debug_renderer_info');
if (debugInfo !== null)
{
var gpu = this.renderer.getContext().getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
gpuHasFrontFacingDoubleSidedBug = gpu.match(/adreno.+(5|6)[0-9][0-9]/gi) !== null;
}
object3D.traverse((child)=>{
if (gpuHasFrontFacingDoubleSidedBug)
{
BufferGeometryUtils.computeTangents(child.geometry);
child.material.vertexTangents = true;
child.material.transparent = true;
child.material.needsUpdate = true;
}
});
},
For the 2nd you can see your GPU name and update the string check accordingly in your code.
Lastly if you have the option to modify the asset. You can follow the answer by @hm711 above.