【问题标题】:Spawn particle at edge of screen在屏幕边缘生成粒子
【发布时间】:2016-08-13 03:16:36
【问题描述】:

我已经搜索了很多地方,所以如果有类似的问题,请原谅我,但我就是找不到。

将我正在尝试做的事情放在上下文中:我想创建一个无限生成的星星场,当它们离开屏幕时消失并重新出现在相机移动的屏幕边缘。我正在使用自上而下的视图,所以实现这一点一定很简单,但可惜我不知道。

我正在使用下面的代码来确定一颗星星是否已经离开屏幕然后替换它:

//update camera frustum
camera.projScreenMatrix.multiplyMatrices(
    camera.projectionMatrix,
    camera.matrixWorldInverse
    );

camera.frustum.setFromMatrix(camera.projScreenMatrix);

//loop through stars
var stars=scene.stars.geometry.vertices;

for(var i=0;i<stars.length;i++) {
    if(!camera.frustum.containsPoint(stars[i])) {
        stars[i]=new THREE.Vector3(

            // fill in the blank

            );
        scene.stars.geometry.verticesNeedUpdate=true;
        }
    }

由于我使用的是透视相机,我知道我需要以某种方式考虑camera.fov 和其他透视元素,但正如你所知,我不是三维方面的专家。

假设我有一个角度或归一化向量告诉我视图平移的方向,我将如何沿着屏幕边缘创建一个顶点,而不管其 Z 位置如何?

如果我不够清楚,我很乐意澄清。谢谢。

【问题讨论】:

    标签: three.js


    【解决方案1】:

    我知道这是一个老问题,但我在寻找答案时遇到了它,并找到了一种简单的、依赖三角函数的方法来获取相机平截头体的左边缘,我正在分享它以防其他人可能觉得有用:

    // Get half of the cameras field of view angle in radians
    var fov = camera.fov / 180 * Math.PI / 2;
    // Get the adjacent to calculate the opposite
    // This assumes you are looking at the scene
    var adjacent = camera.position.distanceTo( scene.position );
    // Use trig to get the leftmost point (tangent = o / a)
    var left = Math.tan( fov ) * adjacent  * camera.aspect;
    

    基本上,这会得到最左边的点,但如果你不乘以纵横比,你应该在相机平截头体周围得到一个圆点,这样你就可以在远离相机焦点的任何方向平移一个点,它总是在截锥体之外。

    它的工作原理是假设作为相机的假想平面垂直于连接相机及其焦点的线,因此存在一个直角。如果您也希望物体更远,这应该可以工作(因此,如果您希望它们距离相机更远,您只需要增加焦点和相机之间的距离)。

    【讨论】:

    • @ChrysUgwu 是的,因为当您删除纵横比乘法时,此计算会在距焦点距离处为您提供一个围绕相机平截头体的圆圈。您可能需要逆向计算纵横比(height/width 而不是 width/height)。
    • 我试过了,但它不准确,也许我做错了。
    【解决方案2】:

    好吧,无数次头痛和稍后的另一个问题,我想出了一个相当临时的答案。以防万一其他人有同样的问题,以下函数在场景上绘制一个点,相对于相机的当前视图,无论 Z 指定如何:

    //only needs to be defined once
    var projector=new THREE.Projector();
    
    //input THREE.Vector3
    function(vector) {
        var z=vector.z;
        vector.z=0;
        projector.unprojectVector(vector,camera);
        return camera.position.clone().add(
            vector
                .sub(camera.position)
                .normalize()
                .multiplyScalar(
                    -(camera.position.z-z)/vector.z
                    )
            );
    

    xy,在这种情况下,从左下角到右上角的范围都是 -1 到 1。你可以使用position/window.Widthposition/window.Height 来获得额外的精度(使用鼠标坐标或你有什么)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-14
      相关资源
      最近更新 更多