Unique Scenario:
Within my scene, I have implemented a vertex shader that positions a plane mesh along the xz-axis at the exact location of the camera. As a result, when the camera is in motion, the plane mesh moves synchronously with it. This creates the illusion that, during camera movement, the plane mesh remains stationary relative to the viewer. Everything appears to be functioning correctly.
Issue Encountered:
However, an anomaly arises when I push the camera (and consequently the plane mesh) beyond a certain threshold -- the mesh suddenly vanishes. Upon investigation, I've noted a correlation between this disappearance and the dimensions of the plane; essentially, the larger the plane, the more leeway I have in moving the camera before facing disappearance.
Moreover, in my test environment, the disappearing act only occurs when navigating on the negative x-axis, positive x-axis, or negative z-axis. Strangely enough, no disappearance unfolds when traveling along the positive z-axis.
I suspect this quandary could be linked to some form of clipping issue, although I am not entirely certain. Despite attempting to recalculate the bounding box for the plane mesh, there has been no resolution thus far.
Any insights or suggestions would be greatly appreciated.
Cheers
Fiddle:
To demonstrate the problem, I have constructed a fiddle: http://jsfiddle.net/p8wZ6/10/
In this fiddle, an additional box mesh has been included to better illustrate the camera's movement:
- To alter the axis of camera movement (by default on the negative z-axis), comment/uncomment the appropriate line of code within the tick method.
- To adjust the size of the plane, modify 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;
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>
Sourcecode JS:
var scene;
var camera;
var light;
var renderer;
var controls;
var onTick;
var planeMesh;
var boxMesh;
var heightmap;
var clock;
function createPlane(){
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(){
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);
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(){
camera.position.z -= .1;
requestAnimationFrame(onTick);
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);
}
init();
createMesh();
startRendering();