当我渲染我的模型的 3000 个实例并将它们保留在视图区域中时,我得到 55FPS,但是如果我有 5000 个模型实例但将其中 2000 个实例保留在视图区域之外,我仍然得到 40 FPS。
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 10000);
它是否有可能正确剔除,但它必须确定它是否被剔除会减慢它的速度?我主要来自https://github.com/mrdoob/three.js/blob/master/examples/webgl_buffergeometry_instancing_dynamic.html
编辑* 我知道我可以使用 geometry.maxInstancedCount = trackCount; 这很有帮助,但它与剔除并不完全相同,因为我有当前视口外的轨迹,但它仍然会影响性能
有什么建议?或想法?
对于实例几何,three.js 不能进行任何视锥体剔除,因为没有关于对象最终位置的信息。这将在顶点着色器中计算,而three.js 不知道那里发生了什么。
任何剔除发生的最早时间是在为每个实例的每个顶点运行顶点着色器之后。这已经解释了您所看到的帧率下降。尽管可见的对象/三角形数量相同,但顶点着色器调用的数量高达 166%。
如果你想自己实现剔除,你可以尝试为每一帧重新排列属性缓冲区中的实例(跳过不可见的实例)并将最大实例数调整为可见实例的数量。这可能有点违反直觉,但在每一帧上重新计算所有实例属性缓冲区实际上可以在这里提供更好的性能。
要进行可见性测试,最简单的方法可能是使用THREE.Frustum()类和frustum.containsPoint(). 那看起来像这样
const frustum = new Frustum();
const projScreenMatrix = new Matrix();
// assume instances is an array of objects containing all the
// relevant information for all instances
const instances = [
// {position: ...}, {position: ...}, ...
];
// for every frame
projScreenMatrix.multiplyMatrices(
camera.projectionMatrix,
camera.matrixWorldInverse
);
frustum.setFromMatrix(projScreenMatrix);
let visibleInstanceCount = 0;
for (let i = 0; i < instanceCount; i++) {
const pos = instances[i].position;
if (!frustum.containsPoint(pos)) {
continue;
}
// add instance to instance-attribute buffers
pos.toArray(instancePositionBuffer, visibleInstanceCount * 3);
visibleInstanceCount++;
}
geometry.maxInstanceCount = visibleInstanceCount;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
464 次 |
| 最近记录: |