UV texture coordinates on InstancedMesh


I’m trying to make UV mapping on InstancedMesh using atlas texture and don’t know how to make it appropriate way due to misunderstanding. I’ve implemented shader changing using onBeforeCompile and successfully changed UV coordinates but got the followings problems:

  1. lights etc. stopped interract with an object that was modified using shader… I think it is connected with order of replacement somehow in onBeforeCompile…
  2. how to make it distinct inside of fragmentShader for which side apply an uv offset… it applies to all sides, but I need only 1 side (all other sides of an object already mapped correctly). I suppose there should be some ids for appropriate vertices to distinct ?

the code is the following:

let atlas = new THREE.MeshPhysicalMaterial( { map: normalMap, flatShading: false, side: THREE.FrontSide, metalness: 0.5, reflectivity: 0.94, clearcoat: 0.48, clearcoatRoughness: 0.24 , roughness: 1 } );

var uvOffsets = [];
uvOffsets.push(0, 0.55);
uvOffsets.push(0, 0);
geometry.addAttribute( ‘instanceUV’, new THREE.InstancedBufferAttribute( new Float32Array( uvOffsets ), 2 ) );

atlas.onBeforeCompile = ( shader ) => {
shader.vertexShader = shader.vertexShader.replace(
#define STANDARD’,
#define STANDARD attribute vec2 instanceUV; varying vec2 vinstanceUV;
#include <begin_vertex>’,
#include <begin_vertex> vinstanceUV = instanceUV;

shader.fragmentShader = shader.fragmentShader.replace(
   '#define STANDARD',
  `#define STANDARD
   varying vec2 vinstanceUV;`
   '#include <fog_fragment>',
  `#include <fog_fragment>
   gl_FragColor = texture2D(map, (vUv+vinstanceUV) );`


var mesh = new THREE.InstancedMesh( geometry, atlas,2);
var matrix = new THREE.Matrix4();
for ( var i = 0; i < 2; i ++ ) {
matrix.setPosition(new THREE.Vector3(i*0.6,1.1,0))
mesh.setMatrixAt( i, matrix );

Thanks in advance!

Finally, I’ve resolved these issues by deleting fragmentShader at all and adding to shader.vertexShader the following lines:

#include <uv_vertex>’,
#include <uv_vertex> if(normal.z>0.0) vUv = ( uvTransform * vec3( uv+instanceUV, 1 ) ).xy;

But now it seems that merged version of this looks better… i don’t know :)…is it possible at all or I’m wrong.

upd… I’ve just forgot change Material from Standard to Physical in merged version…that’s why it was looking different… :slight_smile: