javascript - Mesh 在 three.js 中突然消失了。剪裁?

标签 javascript three.js webgl

场景:
在我的场景中,我实现了一个顶点着色器,它在相机位置的 xz 轴上定位一个平面网格。 因此,如果相机移动,平面网格也会随之移动。这导致视觉效果,即在移动相机时,平面网格似乎保持固定在原地。这似乎工作正常。

问题:
如果我将相机(以及平面网格)移动到一定程度,网格就会突然消失。
我意识到消失和平面的大小之间似乎有关系,即平面越大,在平面网格消失之前我可以移动相机的次数越多。

此外,在我的测试场景中,平面网格仅在沿负 x 轴、正 x 轴或负 z 轴移动时消失。在正 z 轴上移动时它不会消失。

我假设它与某种剪裁有关,但可能是错误的。重新计算平面网格的边界框没有效果。

有什么想法吗?

干杯

fiddle :
我创建了一个显示问题的 fiddle :http://jsfiddle.net/p8wZ6/10/

在 fiddle 中,我添加了一个额外的盒子网格,以更好地可视化相机实际移动。
- 要更改相机移动的轴(默认为负 z 轴)(取消)在 tick 方法中注释相应的代码行。
- 要更改平面的大小,请更改 createPlane 方法中的大小值。

源代码着色器:

<script id="vertexShader" type="x-shader/x-vertex">
    void main() {
        vec4 pos = vec4( position, 1.0 );

        vec4 wPos = modelMatrix * pos;

        wPos.x += cameraPosition.x;
        wPos.z += cameraPosition.z;

        // standard
        // vec4 pPos = projectionMatrix * modelViewMatrix * pos;
        // keep fixed
        vec4 pPos = projectionMatrix * viewMatrix * wPos;

        gl_Position = pPos;
    }
</script>

<script id="fragmentShader" type="x-shader/x-fragment">
    void main() {
        gl_FragColor.rgb = vec3(0.7, 0.7, 0.7);
        gl_FragColor.a = 1.0;
}
</script>


源代码JS:

var scene;
var camera;
var light;
var renderer;
var controls;
var onTick;
var planeMesh;
var boxMesh;
var heightmap;
var clock;


function createPlane(){
    // disappearance seems related to size of geometry.
    // the larger the longer it takes until disappearance.
    var size = 20;
    var geom = new THREE.PlaneGeometry(size, size, 20, 20);

    return geom;
}


function createBox(){
    var geom = new THREE.CubeGeometry(2, 2, 4);

    return geom;
}

function createMesh(){
    // plane
    var geom = createPlane();

    var shaderMaterial = new THREE.ShaderMaterial({
        vertexShader: document.getElementById( 'vertexShader' ).textContent,
        fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
        side: THREE.DoubleSide,
        wireframe: true
    });

    planeMesh = new THREE.Mesh(geom, shaderMaterial);
    var axis = new THREE.AxisHelper(4);
    planeMesh.rotation.x = -90 * (Math.PI / 180);
    planeMesh.add(axis);
    scene.add(planeMesh);

    // box
    geom = createBox();

    var material = new THREE.MeshBasicMaterial( {
        color: 0xff00ff,
    });

    boxMesh = new THREE.Mesh(geom, material);
    boxMesh.position.x = 5;
    boxMesh.position.z = -15;
    axis = new THREE.AxisHelper(4);
    boxMesh.add(axis);
    scene.add(boxMesh);
}

function startRendering(){
    onTick();
};

function onTick(){
    // move camera

    // causes disappearance
    // neg. z
     camera.position.z -= .1;
    // pos. x
    // camera.position.x += .1;
    // neg. x
    // camera.position.x -= .1;

    // causes no disappearance
    // pos. z
    // camera.position.z += .1;

    requestAnimationFrame(onTick);
    //controls.update(clock.getDelta());    
    renderer.render(scene, camera);
}

function init(){
    renderer = new THREE.WebGLRenderer();
    renderer.setClearColor( 0xffffff, 1 );
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    scene = new THREE.Scene();
    scene.add(new THREE.AxisHelper(4));

    camera = new THREE.PerspectiveCamera(65, window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.set(0, 1, 0);

    light = new THREE.DirectionalLight(0xffffff, 1);
    light.shadowCameraVisible = true;
    light.position.set(0, 0, 100);
    scene.add(light);

    //clock = new THREE.Clock();
    //controls = new THREE.FirstPersonControls(camera);
    //controls.movementSpeed = 20;
    //controls.lookSpeed = .1;
}

init();
createMesh();
startRendering();

最佳答案

你有一个根本性的误解。

您正在移动 CPU 中的相机。您正在 GPU 中移动平面的顶点。

相机的截锥体计算对顶点着色器中的顶点位移一无所知。

作为解决方法,您可以设置

 planeMesh.frustumCulled = false;

更好的解决方案是仅将平面添加为相机的子级,并忽略顶点位移。

planeMesh.position.set( 0, -1, 0 );
camera.add( planeMesh );
scene.add( camera );

如果使用第二种方法,您必须将相机添加到场景图中。

three.js r.65

关于javascript - Mesh 在 three.js 中突然消失了。剪裁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21184061/

相关文章:

Javascript 获取子数组的第二个元素(以逗号分隔)

opengl-es - 使用 2D 纹理解决方法的 WebGL/three.js 中的 3D 纹理?

javascript - 三.JS:根据不同的tilesets渲染大 map (Texture Atlas)

javascript - Three.js 渲染器是否克隆对象位置?

javascript - 单击按钮时的 jQuery 用户输入

javascript - Firefox 中的输入类型 "number"与 Knockout 的绑定(bind)问题

javascript - 为什么我的变量显示为空?

html - 未初始化的 WebGL Canvas 的替代方案

javascript - 在 JavaScript/HTML5 中显示 3D 模型

webgl - Three.js 无法加载纹理