首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >THREE.js对单个>500 k多面物体的光线投射速度很慢,与球体的直线相交

THREE.js对单个>500 k多面物体的光线投射速度很慢,与球体的直线相交
EN

Stack Overflow用户
提问于 2019-02-26 11:43:07
回答 4查看 1.8K关注 0票数 7

在我的项目中,我让一个球员绕着一个地球仪走。地球不仅仅是一个球体,它有山脉和山谷,所以我需要球员们改变位置。为此,我从玩家的位置向单个物体(地球仪)投射一条射线,并得到它们相交的点,并相应地改变玩家的位置。我只是当玩家移动的时候,而不是在每一个画面上。

对于一个复杂的对象,它要花费很长时间。对于一个具有大约1米的多边形(面) (1024x512段、球面)的对象,它需要200 It。光线投射到每个人的脸上吗?

是否有一种传统的快速方法来实现这一点,比如一些加速结构(八叉树)?bvh?--从我的谷歌搜索中,我似乎还没有找到这样的东西,包括在三)或其他思维的开箱即用(没有光线投射)方法?

代码语言:javascript
复制
        var dir = g_Game.earthPosition.clone();
        var startPoint = g_Game.cubePlayer.position.clone();
        var directionVector = dir.sub(startPoint.multiplyScalar(10));
        g_Game.raycaster.set(startPoint, directionVector.clone().normalize());
        var t1 = new Date().getTime();
        var rayIntersects = g_Game.raycaster.intersectObject(g_Game.earth, true);
        if (rayIntersects[0]) {
            var dist = rayIntersects[0].point.distanceTo(g_Game.earthPosition);
            dist = Math.round(dist * 100 + Number.EPSILON) / 100;
            g_Player.DistanceFromCenter = dist + 5;
        }
        var t2 = new Date().getTime();
        console.log(t2-t1);

提前谢谢你

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-02-28 20:35:46

我认为你应该把你的地球的高度地图渲染成一个纹理,假设你的地形不是动态的。将其全部读入一个类型化数组中,然后每当玩家移动时,您只需将她的坐标倒置到纹理中,查询它、偏移和乘,就可以在O(1)时间内得到所需的内容。

这取决于你如何生成高度图。实际上,如果你有一个凹凸不平的地球仪,那么首先你应该从高度图开始,然后在你的顶点着色器中使用它来渲染地球(输入的球体非常平滑)。然后,您可以使用相同的高度图来查询玩家的Z。

票数 8
EN

Stack Overflow用户

发布于 2019-03-01 10:49:09

不要使用three.js雷克斯特。

考虑一下提供function intersectTriangle(a, b, c, backfaceCulling, target)function intersectTriangle(a, b, c, backfaceCulling, target)

建议的优化:

  1. 如果玩家从一些已知的位置开始,⇒你必须知道他的初始高度,−不需要光线投射(或者只做一次全网格慢交叉)
  2. 如果玩家用小步数移动,那么下一次的射线广播将很可能是会像以前一样相交。

优化#1−记得前面的脸,然后先用光线投射它。

  1. 如果玩家不跳转,那么下一次的将很有可能是将相邻的脸与玩家之前所在的脸相交。

优化#2−构建了一个缓存,以便给定一个face,您可以在O(1)时间内检索相邻的脸。

如果您的星球不是实时生成的,则可以从文件加载此缓存。

因此,随着我的方法,每次移动,你做O(1)从缓存和光线投射1-6面读取操作。

赢!

票数 13
EN

Stack Overflow用户

发布于 2019-02-28 20:13:54

对于一个复杂的对象,它要花费很长时间。对于一个具有大约1米的多边形(面) (1024x512段、球面)的对象,它需要200 It。光线投射到每个人的脸上吗?

开箱即用,THREE.js在对网格进行光线投射时会检查每个三角形,并且没有将加速度结构内置到3中。

我已经与其他人在三目bvh包(githubnpm)上工作,以帮助解决这个问题,这可能会帮助你达到你想要的速度。下面是您使用它的方法:

代码语言:javascript
复制
import * as THREE from 'three';
import { MeshBVH, acceleratedRaycast } from 'three-mesh-bvh';

THREE.Mesh.prototype.raycast = acceleratedRaycast;

// ... initialize the scene...

globeMesh.geometry.boundsTree = new MeshBVH(globeMesh.geometry);

// ... initialize raycaster...

// Optional. Improves the performance of the raycast
// if you only need the first collision
raycaster.firstHitOnly = true;
const intersects = raycaster.intersectObject(globeMesh, true);

// do something with the intersections

自述中提到了一些注意事项,所以请记住这些(修改了网格索引,只支持非动画BufferGeometry,等等)。还有一些内存优化可以完成,但也有一些可调整的选项来帮助调优。

我很想听听这对你是怎么回事!请在如何改进包的问题上留下反馈意见。希望这能帮上忙!

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54884776

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档