13

I'm making a 360 viewer, so textures are inside a cylinder. Problem is that they appear inverted horizontally.

I know about texture.flipY but I haven't found a texture.flipX on the source.

So how can I flip a texture horizontally, or along the x axis, directly in the code? (not using an image editor)

Pier
  • 9,372
  • 15
  • 57
  • 108

4 Answers4

22

To flip a texture horizontally, you can do the following:

texture.wrapS = THREE.RepeatWrapping;
texture.repeat.x = - 1;

As mentioned in the comments, this approach requires the texture to be a power-of-two in size.

three.js r.87

WestLangley
  • 97,891
  • 9
  • 255
  • 258
  • 1
    I did this, but instead of flipping the texture I got 1px of the texture expanded across the whole object. – Pier Apr 30 '15 at 19:57
  • 1
    I tried this with a dynamic texture from a camera and rendered to an in-scene plane and it worked nicely. plane1.material.map.wrapS = THREE.RepeatWrapping; plane1.material.map.repeat.x = -1; – steveOw Sep 19 '15 at 21:55
  • This works, but it also requires power-of-two texture sizes. – leviathanbadger Jul 17 '17 at 14:27
  • Same issue as @Pier, 1px of the image gets stretched across the face. The image is 512 x 1024. – Ben Davis May 05 '18 at 02:02
  • for a texture with size not power of two, `RepeatWrapping` will fail on iOS safari – Summer Sun Jun 22 '21 at 09:17
11

The answer was easier than I thought.

cylinder.scale.x = -1;

And don't forget to add

material.side = THREE.DoubleSide;
Pier
  • 9,372
  • 15
  • 57
  • 108
  • well your question was pertaining to textures not objects. – gaitat Apr 30 '15 at 18:12
  • for pure textures (i.e images) use a library like [filter.js](https://github.com/foo123/FILTER.js) (ps i'm author) – Nikos M. Apr 30 '15 at 18:20
  • Thanks for the suggestion @NikosM. – Pier Apr 30 '15 at 18:23
  • 4
    three.js does not support a negative scale factor, and it can lead to undesirable consequences, such as reverse winding order and incorrect normals. I would not recommend the approach suggested in this answer -- even though you may have seen it used elsewhere. – WestLangley Apr 30 '15 at 18:58
  • Given there is no texture.flipX, this seem the only practical approach. I found I also need rotate the object that the texture is mapped to: object.rotation.y = Math.PI; – robshearing Aug 07 '16 at 07:13
  • I think a more practical approach is to go through the geometry UV coordinates and flip them. – leviathanbadger Jul 17 '17 at 14:29
1

It might seem a bit of an overkill, but I think a nice way to do it is to turn it by 180 degrees (PI radians) around it's center then flip it:

texture.center = new THREE.Vector2(0.5, 0.5);
texture.rotation = Math.PI;
texture.flipY = false;
0

Another approach here is to change the geometry. In the cylinder geometry you specify thetaStart and thetaLength for the cylinder section you want to render, and usually you choose a positive angle, i.e. thetaLength>0. If instead you pass thetaStart + thetaLength and -thetaLength to CylinderBufferGeometry, the cylinder is rendered clockwise instead of counter-clockwise, and all face normals now point inwards. So, there is no need to flip the texture anymore.

Elmar Zander
  • 1,235
  • 17
  • 29