I use this image for the textures, and this is the code I use to set up the material:
let textureLoader = new THREE.TextureLoader();
let texture = textureLoader.load("../static/blocks.png");
texture.repeat.x = 1/16;
texture.repeat.y = 1/16;
texture.offset.x = 0/16;
texture.offset.y = 15/16;
texture.magFilter = THREE.NearestFilter; // Give textures pixelated appearance
let material = new THREE.MeshBasicMaterial({
map: texture,
});
I want to be able to have a different texture.offset x and y value for each block. This is roughly how I set up the InstancedMesh, where blocks is an array of objects representing blocks:
// transform is used to hold the matrix that will be applied to objects
let transform = new THREE.Object3D();
let geometry = new THREE.BoxBufferGeometry(1, 1, 1);
let mesh = new THREE.InstancedMesh(geometry, material, blocks.length);
for (let i = 0; i < blocks.length; i++) {
block = blocks[i];
transform.position.set(block.x, block.y, block.z);
mesh.setMatrixAt(i, transform.matrix);
}
I am able to set a different position for each block, but I want to also have a different texture offset as well. How do I do this?
You need to modify both the shader and the instanced mesh i believe. The geometry needs a THREE.InstancedBufferAttribute of size 2 at least to hold your offset,s and at least one additional uniform to describe the size of the texture atlas.
I’m not sure if this can be done with InstancedMesh out of the box.
If you only have say 4 different textures, and 2000 instances, it would make sense to use 4 different InstancedMesh and it would work without any modification.
However, if you have 2000 instances, and need to apply 2000 different textures at the same time, you have to create not one but most likely several atlases. To have some resolution say 16x16 you can only fit a certain amount of those segments in one texture. Depending on how many textures the material is using, you may only have a limited amount available to split your sprites so you might have to split it up into several InstancedMesh still. Either way, i don’t think this is possible out of the box