How to avoid leaf kebabs?

I’m importing a tree mesh from blender and then placing thin instanced leaves on the branches that have a particular vertex color. Unfortunately they appear in the middle of the branches like pieces of kebab on a stick.

How can I distribute them more naturally along the branches? Not one per vertex, but spaced out and coming out of the branches at a reasonable angle?

function displayScenery(sceneryPieces, worldBoundingBox, scene) {
  const midpoints = {};
  midpoints.x = (worldBoundingBox.maxX + worldBoundingBox.minX)/2;
  midpoints.y = (worldBoundingBox.maxY + worldBoundingBox.minY)/2;

  for (const [id, piece] of Object.entries(sceneryPieces)) {
    if (piece.type === "deciduousTree") {
      //Insert deciduousTree
      console.log("insert tree");
      let rotationDeg = piece.rotation || 0;  // fallback to 0 if undefined
      let rotationRad = BABYLON.Angle.FromDegrees(rotationDeg).radians(); // convert degrees to radians

      let x = piece.x;
      let y = piece.y;

      BABYLON.SceneLoader.ImportMesh("", "objects/", "beechTree1.glb", GLOBALS.scene, function (meshes) {
        meshes[0].position = new BABYLON.Vector3((x - midpoints.x), 0.5, (y - midpoints.y));
        meshes[0].rotation = new BABYLON.Vector3(0, rotationRad, 0);  // Y-axis rotation
        meshes.forEach(mesh => {
          const colors = mesh.getVerticesData(BABYLON.VertexBuffer.ColorKind);
          const positions = mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
          
          if (!colors || !positions) return;
          
          const leafMatrices = [];
          for (let i = 0; i < positions.length; i += 3) {
            const r = colors[(i * 4) / 3];
            if (r > 0.5) {
              const local = new BABYLON.Vector3(
                positions[i],
                positions[i + 1],
                positions[i + 2]
              );
          
              const worldPos = BABYLON.Vector3.TransformCoordinates(local, mesh.getWorldMatrix());
          
              const mat = BABYLON.Matrix.Compose(
                new BABYLON.Vector3(0.25, 0.25, 0.25),                  // scale
                BABYLON.Quaternion.FromEulerAngles(-Math.PI / 2, Math.random() * Math.PI * 2, 0), // random Y rotation
                worldPos                                               // position
              );
          
              leafMatrices.push(mat);
            }
          }


          addThinInstanceLeaves(leafMatrices);
          
          mesh.removeVerticesData(BABYLON.VertexBuffer.ColorKind);
        });
      });
    }
  }
}

1 Like

Add additional rotation and translation to each leaf matrix before pushing onto leafMatrices.

from your code snippet, simply adding randomness to local position should do the trick