如何在 Aframe 中使用 Three.InstancedMesh [英] How to use Three.InstancedMesh in Aframe

查看:20
本文介绍了如何在 Aframe 中使用 Three.InstancedMesh的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试基于以下示例使用 ThreeJs InstancedMesh 在 Aframe 中实现实例化:https://github.com/mrdoob/three.js/blob/master/examples/webgl_instancing_dynamic.html

I'm trying to implement instancing in Aframe using the ThreeJs InstancedMesh based on the example here: 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;
    },

我看不到任何错误或相关消息,但没有任何实例化对象正在呈现.不幸的是,我真的没有一个很好的方法来发布一个例子.有谁知道我做错了什么?提前致谢!

No errors or relevant messages that I can see, but none of the instanced objects are rendering. I don't really have a good way to post an example unfortunately. Anyone know what I'm doing wrong? Thanks in advance!

注意:似乎正在渲染对象是因为添加此组件时绘制的三角形数量急剧增加.但是,它们在任何地方都不可见,我也无法在 aframe 检查器中找到它们

Note: It seems that the objects are being rendered because the number of triangles being drawn increases drastically when I add this component. However, they are not visible anywhere and I can't find them in the aframe inspector either

推荐答案

这是一个非常具体的问题,主题非常广泛,因此:

It's a very case specific question with a quite extensive topic, so:

一般来说,使用 THREE.InstancedMeshes 很简单,而且你做对了:

In general, using THREE.InstancedMeshes is simple, and you got it right:

// 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 模型示例 此处

Example of an instanced gltf model here

您的代码做了很多工作,如果可以将其精简到最低限度会更容易.然而我认为只有一个主要问题 - this.model 没有在任何地方设置,所以 setMatrix 函数什么都不做.除此之外,您可能需要禁用平截头体剔除 (mesh.frustumCulling = false),或设置边界球体 - 否则对象 可能会在基础对象不在视线范围内消失.

Your code is doing a lot, and it would be easier if it could be stripped to a bare minimum. Yet I think there is only one major issue - this.model isn't set anywhere, so the setMatrix function does nothing. Other than that you may need to disable frustum culling (mesh.frustumCulling = false), or set a bounding sphere - otherwise the objects may dissapear when the base object is out of sight.

设置后,您的代码似乎可以正常工作

这篇关于如何在 Aframe 中使用 Three.InstancedMesh的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆