问题描述
场景:
在我的场景中,我实现了一个顶点着色器,它将xz轴上的平面网格定位在摄像机的位置。
因此,如果相机移动,平面网格随之移动。这导致视觉效果,即在移动相机时,平面网格似乎保持固定在适当位置。这似乎工作正常。
Scenario:
In my scene I implemented a vertex shader that positions a plane mesh on the xz-axis at the position of the camera.So if the camera moves, the plane mesh moves with it. This leads to the visual effect that, while moving the camera, the plane mesh seems to stay fixed in place. This seems to work correctly.
问题:
如果我移动相机(因此平面网格)到一定程度,网格突然消失。
我意识到平面的消失和平面大小之间似乎存在关系,即平面越大,更多我可以在平面网格消失之前移动相机。
Problem:
If I move the camera (and therefore the plane mesh) to a certain extend, the mesh suddenly disappears.
I realized that there seems to be a relationship between the disappearance and the size of the plane, i.e. the larger the plane, the more I can move the camera before the plane mesh disappears.
此外,在我的测试场景中,平面网格仅在负x轴,正x轴或负z轴上移动时消失。当在正z轴上移动时它不会消失。
Also, in my test scene the plane mesh only disappears when moving on the negative x-axis, positive x-axis or negative z-axis. It does NOT disappear when moving on the positive z-axis.
我认为它与某种削波有关,但可能是错误的。重新计算平面网格的边界框没有任何效果。
I assume it has something to do with some kind of clipping, but may be wrong. Recomputing the bounding box of the plane mesh had no effect.
任何想法?
干杯
小提琴:
我创建了一个显示问题的小提琴:
In小提琴我添加了一个额外的盒子网格,以更好地可视化相机实际移动。
- 更改相机移动的轴(默认为负z轴)(取消)注释相应的代码行在tick方法中。
- 要更改平面的大小,请更改createPlane方法中的大小值。
In the fiddle I added an additional box mesh to better visualize that the camera actually moves.
- To change the axis the camera moves on (negative z-axis by default) (un-)comment the appropriate code line in the tick method.
- To change the size of the plane change the size value in the createPlane method.
源代码着色器:
Sourcecode Shader:
<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中移动平面的顶点。
You are moving the camera in the CPU. You are moving the vertices of the plane in the GPU.
相机的平截头体计算对顶点着色器中的顶点位移一无所知。
The camera's frustum calculation knows nothing about the vertex displacements in the vertex shader.
作为解决方法,您可以设置
As a work-around, you can set
planeMesh.frustumCulled = false;
更好的解决方案是将平面添加为相机的子级,并省略顶点位移。
A better solution is to just add the plane as a child of the camera, and omit vertex displacements.
planeMesh.position.set( 0, -1, 0 );
camera.add( planeMesh );
scene.add( camera );
您必须将相机添加到使用第二种方法的场景图中。
You must add the camera to the scene graph it you use the second approach.
three.js r.65
three.js r.65
这篇关于网格突然在three.js中消失。裁剪?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!