Reputation: 431
I want to create ONE single buffer geometry that can hold many materials. I have read that in order to achieve this in BufferGeometry, I need to use groups. So I created the following "floor" mesh:
var gg=new THREE.BufferGeometry(),vtx=[],fc=[[],[]],mm=[
new THREE.MeshLambertMaterial({ color:0xff0000 }),
new THREE.MeshLambertMaterial({ color:0x0000ff })
];
for(var y=0 ; y<11 ; y++)
for(var x=0 ; x<11 ; x++) {
vtx.push(x-5,0,y-5);
if(x&&y) {
var p=(vtx.length/3)-1;
fc[(x%2)^(y%2)].push(
p,p-11,p-1,
p-1,p-11,p-12
);
}
}
gg.addAttribute('position',new THREE.Float32BufferAttribute(vtx,3));
Array.prototype.push.apply(fc[0],fc[1]); gg.setIndex(fc[0]);
gg.computeVertexNormals();
gg.addGroup(0,100,0);
gg.addGroup(100,100,1);
scene.add(new THREE.Mesh(gg,mm));
I am using THREE.js v.101 and I prefer to not create special custom shader for that, or add another vertex buffer to duplicate those I already have, and I prefer to not create 2 meshes as this may get much more complicated with advanced models.
Upvotes: 1
Views: 2153
Reputation: 2334
Check out this: https://jsfiddle.net/mmalex/zebos3va/
fix #1 - don't define group 0
fix #2 - 2nd parameter in .addGroup
is buffer length, it must be multiple of 3 (100 was wrong)
var gg = new THREE.BufferGeometry(),
vtx = [],
fc = [[],[]],
mm = [
new THREE.MeshLambertMaterial({
color: 0xff0000
}),
new THREE.MeshLambertMaterial({
color: 0x0000ff
})
];
for (var y = 0; y < 11; y++)
for (var x = 0; x < 11; x++) {
vtx.push(x - 5, 0, y - 5);
if (x && y) {
var p = (vtx.length / 3) - 1;
fc[(x % 2) ^ (y % 2)].push(
p, p - 11, p - 1,
p - 1, p - 11, p - 12
);
}
}
gg.addAttribute('position', new THREE.Float32BufferAttribute(vtx, 3));
fc[0].push.apply(fc[1]);
gg.setIndex(fc[0]);
gg.computeVertexNormals();
// group 0 is everything, unless you define group 1
// fix #1 - don't define group 0
// fix #2 - 2nd parameter is buffer length, it must be multiple of 3 (100 was wrong)
gg.addGroup(0, 102, 1);
scene.add(new THREE.Mesh(gg, mm));
Upvotes: 1