Skip to content Skip to sidebar Skip to footer

Threejs Instance Multiple Objects With Different Sizes And Positions

just yesterday i started to tried the InstancedBufferGeometry method because i want to render thousand of objects with a good performance. In my case i want to instance cube geomet

Solution 1:

First, position should not be re-defined. ShaderMaterial injects common attributes, including position, and your definition conflicts with that. If you'd like to define everything yourself, look into RawShaderMaterial.

Second, remember, you're defining the vertices, indices, and normals for ONE cube, then using shaders/instancing to manipulate the rest. Only instance-specific data should be defined as InstancedBufferAttributes.

Take a look at this example:

var cubeGeo = new THREE.InstancedBufferGeometry().copy(new THREE.BoxBufferGeometry(10, 10, 10));
//cubeGeo.maxInstancedCount = 8;

cubeGeo.addAttribute("cubePos", new THREE.InstancedBufferAttribute(new Float32Array([
  25, 25, 25,
  25, 25, -25, -25, 25, 25, -25, 25, -25,
  25, -25, 25,
  25, -25, -25, -25, -25, 25, -25, -25, -25
]), 3, 1));

var vertexShader = [
  "precision highp float;",
  "",
  "uniform mat4 modelViewMatrix;",
  "uniform mat4 projectionMatrix;",
  "",
  "attribute vec3 position;",
  "attribute vec3 cubePos;",
  "",
  "void main() {",
  "",
  " gl_Position = projectionMatrix * modelViewMatrix * vec4( cubePos + position, 1.0 );",
  "",
  "}"
].join("\n");
var fragmentShader = [
  "precision highp float;",
  "",
  "void main() {",
  "",
  " gl_FragColor = vec4(1.0, 0.0, 0.0, 0.5);",
  "",
  "}"
].join("\n");

var mat = new THREE.RawShaderMaterial({
  uniforms: {},
  vertexShader: vertexShader,
  fragmentShader: fragmentShader,
  transparent: true
});

var mesh = new THREE.Mesh(cubeGeo, mat);

scene.add(mesh);

Like you, I've created a cube (just one cube). I then add an InstancedBufferAttribute named cubePos which will change the positions of the cubes (cubePos applies to ALL vertices in this example). This is similar to your translate attribute.

As far as stretching the cubes, it looks like you may be close with your position attribute. It may work as you expect if you simply give it a name that is not built-in, like stretch.

Personally, since it looks like you're stretching it equally in both directions, I'd probably just pass in a single value per instance, and use it to scale the cube in both Y directions.

Post a Comment for "Threejs Instance Multiple Objects With Different Sizes And Positions"