本文介绍了THREE.js对单个>的光线投射非常慢500k多边形(面)对象,与地球的线相交的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的项目中,我有一个玩家环游世界.地球不仅是一个球体,而且还有山脉和山谷,因此我需要玩家的z位置进行更改.为此,我从玩家的位置向单个物体(地球)发出光线,然后得到它们相交的点,并相应地更改玩家的位置.我只是在播放器移动时播放光线,而不是在每一帧上播放.

对于复杂的对象,它需要永远的时间.具有约1m多边形(面)(1024x512分段球面)的对象大约需要200毫秒.光线投射会投射在每个人的脸上吗?

是否有一种传统的快速方法可以在三个时间内实现这一目标,例如某种加速结构(八叉树?开箱即用(无射线投射)方法?

        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);

提前谢谢

解决方案

我认为您应该将地球的高度图预呈现为纹理,前提是您的地形不是动态的.将所有内容读取到一个类型化的数组中,然后只要播放器移动,您只需将其坐标反向投影到该纹理中,对其进行查询,偏移和相乘即可,您应该在O(1)时间内得到所需的内容. /p>

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

in my project I have a player walk around a globe. The globe is not just a sphere, it has mountains and valleys, so I need the players z position to change. For this I'm raycasting a single ray from player's position against a single object (the globe) and I get the point they intersect and change players position accordingly. I'm only raycasting when the player moves, not on every frame.

For a complex object it takes forever. It takes ~200ms for an object with ~1m polys (faces) (1024x512 segments sphere). Does raycasting cast against every single face ?

Is there a traditional fast way to achieve this in THREE, like some acceleration structure (octree? bvh? -- tbh from my google searches I haven't seem to find such a thing included in THREE) or some other thinking-out-of-the-box (no ray casting) method?

        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);

Thank you in advance

解决方案

I think you should pre-render the height map of your globe into a texture, assuming your terrain is not dynamic. Read all of it into a typed array, and then whenever your player moves, you only need to back-project her coordinates into that texture, query it, offset and multiply and you should get what you need in O(1) time.

It's up to you how you generate that height map. Actually if you have a bumpy globe, then you should probably start with height map in the first place, and use that in your vertex shader to render the globe (with the input sphere being perfectly smooth). Then you can use the same height map to query the player's Z.

这篇关于THREE.js对单个>的光线投射非常慢500k多边形(面)对象,与地球的线相交的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 10:03