Основная проблема заключается в том, что вы тесселяции THREE.PlaneBufferGeometry
в сегментах ширины, но не в сегментах высоты:
groundGeometry = new THREE.PlaneBufferGeometry(
1000, 10000,
100, // <----- widthSegments
100 ); // <----- heightSegments is missing
Теперь вы можете использовать координату z представленияместо для интерполяции:
float factor = -modelViewPosition.z / 2000.0;
var camera, controls, scene, renderer;
var groundGeometry, groundMaterial, groundMesh;
var ambientLight;
init();
initLight();
initGround();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10000 );
camera.position.y = 500;
camera.position.z = 1000;
controls = new THREE.MapControls( camera );
controls.maxPolarAngle = Math.PI / 2;
scene = new THREE.Scene();
scene.add(camera);
var axesHelper = new THREE.AxesHelper( 500 );
scene.add( axesHelper );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function initLight() {
ambientLight = new THREE.AmbientLight( 0x404040 );
scene.add( ambientLight );
}
function initGround() {
groundMaterial = new THREE.ShaderMaterial({
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
transparent: true
});
groundGeometry = new THREE.PlaneBufferGeometry( 1000, 10000, 100, 100 );
groundMesh = new THREE.Mesh( groundGeometry, groundMaterial );
groundMesh.position.z = -3000;
groundMesh.position.y = -100;
groundMesh.rotateX(-Math.PI / 2)
scene.add( groundMesh );
}
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
}
<script type="x-shader/x-vertex" id="vertexShader">
varying float distance;
mat4 rotateX(float rotationX) {
return mat4(
vec4(1.0,0.0,0.0,0.0),
vec4(0.0,cos(rotationX),-sin(rotationX),0.0),
vec4(0.0,sin(rotationX),cos(rotationX),0.0),
vec4(0.0,0.0,0.0,1.0)
);
}
void main()
{
vec4 vPosition = vec4(position, 1.0);
vec4 modelViewPosition = modelViewMatrix * vPosition;
float bend = radians(-90.0);
vec4 newPos = rotateX(bend) * vPosition;
distance = -modelViewPosition.z;
float factor = -modelViewPosition.z / 2000.0;
vPosition = mix(vPosition, newPos, factor);
gl_Position = projectionMatrix * modelViewMatrix * vPosition;
}
</script>
<script type="x-shader/x-fragment" id="fragmentShader">
varying float distance;
void main() {
if (distance < 3000.0) {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
} else {
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
}
}
</script>
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://rawgit.com/mrdoob/three.js/dev/examples/js/controls/MapControls.js"></script>