设想:
在我的场景中,我实现了一个顶点着色器,它将平面网格放置在相机位置的 xz 轴上。
因此,如果相机移动,平面网格也会随之移动。这会产生这样的视觉效果:在移动相机时,平面网格似乎保持固定在原位。这似乎工作正常。
Problem:
如果我将相机(以及平面网格)移动到一定程度,网格会突然消失。
我意识到消失和平面的大小之间似乎存在关系,即平面越大,在平面网格消失之前我可以移动相机的越多。
另外,在我的测试场景中,平面网格仅在负 x 轴、正 x 轴或负 z 轴上移动时才会消失。当沿 z 轴正方向移动时,它不会消失。
我认为这与某种剪辑有关,但可能是错误的。重新计算平面网格的边界框没有效果。
有任何想法吗?
Cheers
Fiddle:
我创建了一个显示问题的小提琴:http://jsfiddle.net/p8wZ6/10/
在小提琴中,我添加了一个额外的盒子网格,以更好地可视化相机实际移动的情况。
- 要更改相机移动的轴(默认为负 z 轴)(取消)注释刻度方法中相应的代码行。
- 要更改平面的大小,请更改 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();