Spawn particle at edge of screen

不问归期 提交于 2019-12-13 05:29:59

问题


I've searched far and wide, so if there's a similar question please forgive me but I just couldn't find it.

To put what I'm trying to do in context: I want to create an infinitely-generated field of stars that disappear as they go offscreen and reappear at the edge of the screen where the camera is moving. I'm working with a top-down view, so it must be pretty simple to achieve this, but alas I haven't a clue.

I'm using the following code to determine whether a star has gone off-screen and then replace it:

//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;
        }
    }

Since I'm using a perspective camera, I know I'll need to somehow factor in camera.fov and other perspective elements, but as you can tell I'm no expert on the third dimension.

Assuming I have an angle or normalized vector telling me the direction the view is panning, how would I go about creating a vertex along the edge of the screen regardless of its Z position?

If I'm not clear enough, I'll be happy to clarify. Thanks.


回答1:


I know this is an old question, but I came across it while looking for an answer and found a simple, trigonometry reliant method to get the left edge of the camera frustum, and I'm sharing it in case someone else might find it useful:

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

Basically, this gets the leftmost point, but if you don't multiply by the aspect ratio you should get a point in a circle around your camera frustum, so you could translate a point any direction away from the cameras focus and it would always be outside the frustum.

It works by assuming that the imaginary plane that is the camera is perpendicular to the line connecting the camera and its focus, so there is a straight angle. This should work if you want objects further away as well (so if you want them at a further point from the camera you just need to increase the distance between the focus and the camera).




回答2:


Well, countless headaches and another question later, I've come up with a fairly makeshift answer. Just in case by some unlikely chance someone else has the same question, the following function plots a point on the scene relative to the camera's current view with whatever Z specified:

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

The x and y, in this case, both range from -1 to 1 for bottom-left to top-right. You can use position/window.Width and position/window.Height for extra precision (using mouse coordinates or what have you).



来源:https://stackoverflow.com/questions/20582048/spawn-particle-at-edge-of-screen

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!