Three.js Mirrored Normal Maps Flipped Channel


I have added a normal map to a model in Three.js that is mirrored down the middle. It looks like one of the channels (green perhaps?) is flipped on the mirrored side.

<img alt="enter image description here" class="b-lazy" data-src="https://i.stack.imgur.com/SJXnP.png" data-original="https://i.stack.imgur.com/SJXnP.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" />

I have one ambient light, one directional headlight, and one spotlight. Here is the code that I use to make the material:

// Create a MeshPhongMaterial for the model var material = new THREE.MeshPhongMaterial(); material.map = THREE.ImageUtils.loadTexture(texture_color); // Wrapping modes //THREE.RepeatWrapping = 1000; //THREE.ClampToEdgeWrapping = 1001; //THREE.MirroredRepeatWrapping = 1002; material.map.wrapS = THREE.RepeatWrapping; material.map.wrapT = THREE.MirroredRepeatWrapping; if (texture_normal != null) { material.normalMap = THREE.ImageUtils.loadTexture(texture_normal); material.normalMap.wrapS = THREE.RepeatWrapping; material.normalMap.wrapT = THREE.MirroredRepeatWrapping; } material.wrapAround = true; material.morphTargets = true; material.shininess = 15; material.specular = new THREE.Color(0.1, 0.1, 0.1); material.ambient = new THREE.Color(0, 0, 0); material.alphaTest = 0.5; var mesh = new THREE.MorphAnimMesh( geometry, material ); // Turn on shadows mesh.castShadow = true; if (shadows) { mesh.receiveShadow = true; } scene.add( mesh );

I tried all of the different combinations of material.normalMap.wrapS and material.normalMap.wrapT but that didn't solve it (tried diffuse map too). What am I doing wrong?

Thank you!


Normal maps are dependent on the geometry, so you can't just mirror it and expect it to work like a diffuse texture would.

To make it work, you need to flip the normal map's red channel wherever the UVWs are mirrored on the model.

<a href="http://www.polycount.com/forum/showthread.php?t=116922" rel="nofollow">http://www.polycount.com/forum/showthread.php?t=116922</a>


Turns out I was using an older version (1.2) of the Blender Three.js exporter. By switching to the latest version (1.5) of the exporter from the r67 repository, <strike>Three.js now correctly handles mirrored normal maps with its Phong shader out of the box.</strike>

Edit: The Phong Shader was still having issues with the flipped channel. I ended up using the "Normal Map Shader" (see the Three.js examples) and that gave me correct results. Unfortunately the Normal Map Shader doesn't work with Morph animations, only Skeletal.


  • Conditional IO action
  • Primary key with ASC or DESC ordering?
  • Is it safe to use negative integers with size_t?
  • OpenGL shadow peter-panning
  • Tween JS basics on three JS cube
  • Why does this method break std::cout with Cygwin g++?
  • Cythonized function unexpectedly slow
  • Can't delete or rename original file after resizing
  • Select options in sencha touch is not working for android
  • Django invalid literal for int() with base 10
  • ListItem.Attributes.Add not working
  • Diff between two dataframes in pandas
  • Should I or shouldn't I use the CachingConnectionFactory with hornetq 2.4.1
  • WPF - CanExecute dosn't fire when raising Commands from a UserControl
  • How to use RequestBodyAdvice
  • Jetty Server not starting: Unable to establish loopback connection
  • Body moving without any force applied? (Box2d)
  • does jqgrid support a multiple checkbox list for editing
  • java.lang.NoClassDefFoundError: com.parse.Parse$Configuration$Builder on below Lollipop versions
  • JFileChooser in front of fullscreen Swing application
  • jQuery show() function is not executed in Safari if submit handler returns true
  • How to make a tree having multiple type of nodes and each node can have multiple child nodes in java
  • Align navbar back button on right side
  • HTML download movie download link
  • Modifying destination and filename of gulp-svg-sprite
  • How to handle AllServersUnavailable Exception
  • How to model a transition system with SPIN
  • VBA Convert delimiter text file to Excel
  • ORA-29908: missing primary invocation for ancillary operator
  • Linker errors when using intrinsic function via function pointer
  • How to disable jQuery.jplayer autoplay?
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • How to stop GridView from loading again when I press back button?
  • LevelDB C iterator
  • Bitwise OR returns boolean when one of operands is nil
  • sending mail using smtp is too slow
  • Busy indicator not showing up in wpf window [duplicate]
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • How can i traverse a binary tree from right to left in java?
  • How can I use `wmic` in a Windows PE script?