场景:
在我的场景中,我实现了一个顶点着色器,它在相机位置的 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/