2

In a three.js rendering, I have a small texture which I want to repeat multiple times. For this texture there is the map, a displacement map, a normal map, an ambient occlusion map and a specular map. As long as the repeating pattern is 1 in the x and 1 in the y direction, the image looks as expected. There is displacement where expected.

1by1 image array

If the repeat values are greater than 1, all of the maps appear to scaled correctly except for the displacement map. The displacement map does not appear to be repeated. The displace is the same as shown in the previous image.

5by5 image array

A code snippet for applying these maps to a plane follows:

///////////////////////////////////////////////
// add texture plane for a test

xRep = 1;
yRep = 1;

var loader = new THREE.TextureLoader();
var tex = loader.load('images/img.png');
tex.wrapS = tex.wrapT = THREE.RepeatWrapping;
tex.repeat.set(xRep, yRep);

var nloader = new THREE.TextureLoader();
var ntex = loader.load('images/img-normal.png');
ntex.wrapS = ntex.wrapT = THREE.RepeatWrapping;
ntex.repeat.set(xRep, yRep);

var aloader = new THREE.TextureLoader();
var atex = aloader.load('images/img-ao.png');
atex.wrapS = atex.wrapT = THREE.RepeatWrapping;
atex.repeat.set(xRep, yRep);

var dloader = new THREE.TextureLoader();
var dtex = dloader.load('images/img-v003-disp.png');
dtex.wrapS = dtex.wrapT = THREE.RepeatWrapping;
dtex.repeat.set(xRep, yRep);

var sloader = new THREE.TextureLoader();
var stex = sloader.load('images/img-v003-spec.png');
stex.wrapS = stex.wrapT = THREE.RepeatWrapping;
stex.repeat.set(xRep, yRep);

var faceMaterial = new THREE.MeshPhongMaterial({
     color: 0xa0a0a0,
     shininess: 30,
     //map               : tex,  
     //bumpMap           : tex,
     //bumpScale         : 1,
     displacementMap: dtex,
     displacementScale: 10,
     normalMap: ntex,
     //normalScale       : (1,1),
     aoMap: atex,
     //aoMapIntensity    : 1,
     specularMap: stex
       //_last: 0
   });

face = new THREE.Mesh(new THREE.PlaneGeometry(50, 50, 256, 256),
     faceMaterial);
   face.position.z = 50;
   face.receiveShadow = true;
   face.castShadow = true;

scene.add(face);

How can this snippet be modified so the displacement map is repeated the same as the other maps?

Note: This issue appear to be related to the discussion at issue #7826 on Git hub.

WestLangley
  • 102,557
  • 10
  • 276
  • 276
Ed Tate
  • 333
  • 1
  • 10
  • One option would be to create a new image for your displacement map from your current map via a canvas, taking into account the offset and repeat. Something similar to [THIS](http://stackoverflow.com/questions/37866251/is-it-possible-to-use-2-textures-one-on-top-of-the-other-as-a-material-without/37888476#37888476) – 2pha Aug 08 '16 at 02:17

1 Answers1

2

You want your displacement map to repeat, but the displacement map does not honor the offset repeat value in the current version of three.js.

A work-around is to modify the UVs of your geometry.

Suppose you want the displacement map to be repeated 3 times. Then, multiply your UVs by 3.

Using PlaneBufferGeometry, follow this pattern to do so:

var uvs = geometry.attributes.uv.array;

for ( var i = 0; i < uvs.length; i ++ ) uvs[ i ] *= 3;

For the other textures, if you wanted to, you could compensate by scaling their repeat values accordingly:

texture.repeat.set( 1 / 3, 1 / 3 );

If you are changing the buffer geometry UVs after rendering at least once, you will need to set:

mesh.geometry.attributes.uv.needsUpdate = true;

Also, be sure to read this post.

three.js r.79

Community
  • 1
  • 1
WestLangley
  • 102,557
  • 10
  • 276
  • 276
  • How is this done if the repetitions are different for the x and y directions? For example if x repeats 5 times and y repeats 2 times? – Ed Tate Aug 08 '16 at 18:12
  • Just scale the x- and y- uv components differently. – WestLangley Aug 08 '16 at 18:33
  • No problem. Thanks for the assistance. The recommendation looks good. There has not been time to test this. Once its verified to work, I'll hit the accept. – Ed Tate Aug 26 '16 at 11:21