如何在Aframe中使用Three.InstancedMesh
How to use Three.InstancedMesh in Aframe
我正在尝试根据此处的示例使用 ThreeJs InstancedMesh 在 Aframe 中实现实例化:https://github.com/mrdoob/three.js/blob/master/examples/webgl_instancing_dynamic.html
此处相关代码部分:
init: function() {
const {count, radius, scale, colors, positions} = this.data;
this.start = true;
this.dummy = new THREE.Object3D();
this.count = count;
this.startObject = new THREE.Object3D();
this.endObject = new THREE.Object3D();
this.instanceColors = new Float32Array(count * 3);
this.instanceColorsBase = new Float32Array(this.instanceColors.length);
this.vertices = [];
this.rotations = [];
for ( var i = 0; i < this.data.count; i ++ ) {
var x = this.data.positions[i][0] * this.data.scale;
var y = this.data.positions[i][1] * this.data.scale;
var z = this.data.positions[i][2] * this.data.scale;
var xEnd = x + this.data.endPositions[i][0] * this.data.scale;
var yEnd = y + this.data.endPositions[i][1] * this.data.scale;
var zEnd = z + this.data.endPositions[i][2] * this.data.scale;
this.vertices.push( x, y, z );
const rotation = this.getDirection({'x':x,'y':y,'z':z},
{'x':xEnd,'y':yEnd,'z':zEnd});
this.rotations.push(rotation.x, rotation.y, rotation.z);
}
let mesh;
let geometry;
let material;
const loader = new THREE.GLTFLoader();
const el = this.el;
loader.load("/assets/arrow/arrow.gltf", function ( model ) {
geometry = model.scene.children[0].children[0].geometry;
geometry.computeVertexNormals();
geometry.scale( 0.03, 0.03, 0.03 );
material = new THREE.MeshNormalMaterial();
mesh = new THREE.InstancedMesh( geometry, material, count );
mesh.instanceMatrix.setUsage( THREE.DynamicDrawUsage );
el.object3D.add(mesh);
} );
this.el.setAttribute("id", "cells");
},
setMatrix: function (start) {
if (this.mesh) {
for ( let i = 0; i < this.count; i ++ ) {
var x = this.data.positions[i][0] * this.data.scale;
var y = this.data.positions[i][1] * this.data.scale;
var z = this.data.positions[i][2] * this.data.scale;
var xEnd = x + this.data.endPositions[i][0] * this.data.scale;
var yEnd = y + this.data.endPositions[i][1] * this.data.scale;
var zEnd = z + this.data.endPositions[i][2] * this.data.scale;
if (start) {
this.dummy.position.set(xEnd, yEnd, zEnd);
} else {
this.dummy.position.set(x, y, z);
}
this.dummy.rotation.x = this.rotations[i][0];
this.dummy.rotation.y = this.rotations[i][1];
this.dummy.rotation.z = this.rotations[i][2];
this.dummy.updateMatrix();
this.mesh.setMatrixAt( i, this.dummy.matrix );
}
this.mesh.instanceMatrix.needsUpdate = true;
}
}
tick: function() {
this.setMatrix(this.start);
this.start = !this.start;
},
我看不到任何错误或相关消息,但 none 个实例对象正在呈现。不幸的是,我真的没有很好的方法来 post 举个例子。有人知道我做错了什么吗?提前致谢!
注意:似乎正在渲染对象,因为添加此组件时绘制的三角形数量急剧增加。但是,它们在任何地方都不可见,我也无法在 aframe 检查器中找到它们
这是一个非常具体的问题,主题非常广泛,所以:
一般来说,使用THREE.InstancedMeshes很简单,你做对了:
// create an instanced mesh
let iMesh = new THREE.InstancedMesh(geometry, material, count)
element.object3D.add(iMesh)
// manipulate the instances
let mtx = new Matrix4()
// set the position, rotation, scale of the matrix
// ...
// update the instance
iMesh.setMatrixAt(index, mtx);
iMesh.instanceMatrix.needsUpdate = true;
实例化 gltf 模型示例 here
您的代码做了很多事情,如果能将其精简到最低限度会更容易。但我认为只有一个主要问题 - this.model
未在任何地方设置,因此 setMatrix
函数什么都不做。除此之外,您可能需要禁用视锥体剔除 (mesh.frustumCulling = false
),或设置边界球体 - 否则当基础对象不在视线范围内时对象 。
我正在尝试根据此处的示例使用 ThreeJs InstancedMesh 在 Aframe 中实现实例化:https://github.com/mrdoob/three.js/blob/master/examples/webgl_instancing_dynamic.html
此处相关代码部分:
init: function() {
const {count, radius, scale, colors, positions} = this.data;
this.start = true;
this.dummy = new THREE.Object3D();
this.count = count;
this.startObject = new THREE.Object3D();
this.endObject = new THREE.Object3D();
this.instanceColors = new Float32Array(count * 3);
this.instanceColorsBase = new Float32Array(this.instanceColors.length);
this.vertices = [];
this.rotations = [];
for ( var i = 0; i < this.data.count; i ++ ) {
var x = this.data.positions[i][0] * this.data.scale;
var y = this.data.positions[i][1] * this.data.scale;
var z = this.data.positions[i][2] * this.data.scale;
var xEnd = x + this.data.endPositions[i][0] * this.data.scale;
var yEnd = y + this.data.endPositions[i][1] * this.data.scale;
var zEnd = z + this.data.endPositions[i][2] * this.data.scale;
this.vertices.push( x, y, z );
const rotation = this.getDirection({'x':x,'y':y,'z':z},
{'x':xEnd,'y':yEnd,'z':zEnd});
this.rotations.push(rotation.x, rotation.y, rotation.z);
}
let mesh;
let geometry;
let material;
const loader = new THREE.GLTFLoader();
const el = this.el;
loader.load("/assets/arrow/arrow.gltf", function ( model ) {
geometry = model.scene.children[0].children[0].geometry;
geometry.computeVertexNormals();
geometry.scale( 0.03, 0.03, 0.03 );
material = new THREE.MeshNormalMaterial();
mesh = new THREE.InstancedMesh( geometry, material, count );
mesh.instanceMatrix.setUsage( THREE.DynamicDrawUsage );
el.object3D.add(mesh);
} );
this.el.setAttribute("id", "cells");
},
setMatrix: function (start) {
if (this.mesh) {
for ( let i = 0; i < this.count; i ++ ) {
var x = this.data.positions[i][0] * this.data.scale;
var y = this.data.positions[i][1] * this.data.scale;
var z = this.data.positions[i][2] * this.data.scale;
var xEnd = x + this.data.endPositions[i][0] * this.data.scale;
var yEnd = y + this.data.endPositions[i][1] * this.data.scale;
var zEnd = z + this.data.endPositions[i][2] * this.data.scale;
if (start) {
this.dummy.position.set(xEnd, yEnd, zEnd);
} else {
this.dummy.position.set(x, y, z);
}
this.dummy.rotation.x = this.rotations[i][0];
this.dummy.rotation.y = this.rotations[i][1];
this.dummy.rotation.z = this.rotations[i][2];
this.dummy.updateMatrix();
this.mesh.setMatrixAt( i, this.dummy.matrix );
}
this.mesh.instanceMatrix.needsUpdate = true;
}
}
tick: function() {
this.setMatrix(this.start);
this.start = !this.start;
},
我看不到任何错误或相关消息,但 none 个实例对象正在呈现。不幸的是,我真的没有很好的方法来 post 举个例子。有人知道我做错了什么吗?提前致谢!
注意:似乎正在渲染对象,因为添加此组件时绘制的三角形数量急剧增加。但是,它们在任何地方都不可见,我也无法在 aframe 检查器中找到它们
这是一个非常具体的问题,主题非常广泛,所以:
一般来说,使用THREE.InstancedMeshes很简单,你做对了:
// create an instanced mesh
let iMesh = new THREE.InstancedMesh(geometry, material, count)
element.object3D.add(iMesh)
// manipulate the instances
let mtx = new Matrix4()
// set the position, rotation, scale of the matrix
// ...
// update the instance
iMesh.setMatrixAt(index, mtx);
iMesh.instanceMatrix.needsUpdate = true;
实例化 gltf 模型示例 here
您的代码做了很多事情,如果能将其精简到最低限度会更容易。但我认为只有一个主要问题 - this.model
未在任何地方设置,因此 setMatrix
函数什么都不做。除此之外,您可能需要禁用视锥体剔除 (mesh.frustumCulling = false
),或设置边界球体 - 否则当基础对象不在视线范围内时对象