Сценарий:
В моей сцене я применил вершинный шейдер, который позиционирует плоскость сетки по оси xz в положении камеры. Итак, если камера движется, плоскость сетки перемещается вместе с ней. Это приводит к визуальному эффекту, что при перемещении камеры плоскостная сетка остается неподвижной. Кажется, это работает правильно.
Сетка внезапно исчезает в три раза. Отсечение?
Проблема:
Если переместить камеру (и, следовательно, плоскость сетки) в определенной степени, сетка внезапно исчезает.
Я понял, что, по-видимому, существует связь между исчезновением и размером плоскости, т. Е. Чем больше плоскость, тем больше я могу перемещать камеру до исчезновения плоскости сетки.
Кроме того, на моей тестовой сцене плоская сетка исчезает только при движении по отрицательной оси х, положительной оси х или отрицательной оси z. Он не исчезает при движении по положительной оси z.
Я предполагаю, что это как-то связано с каким-то отсечением, но может быть и неправильным. Пересчет ограничивающей рамки плоской сетки не имел никакого эффекта.
Любые идеи?
Приветствие
Fiddle:
Я создал скрипку, которая показывает проблему: http://jsfiddle.net/p8wZ6/10/
В скрипке я добавил дополнительную сетку коробки, чтобы лучше визуализировать, что камера на самом деле двигается.
- Чтобы изменить ось, по которой камера перемещается (по умолчанию отрицательная ось Z) (не), прокомментируйте соответствующую строку кода в методе тика.
- Чтобы изменить размер плоскости, измените значение размера в методе createPlane.
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>
Sourcecode 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();
Самолет не перемещается, а камера. Поэтому, в конечном счете, самолет выходит за пределы усеченного участка камеры и подрезается - как и должно быть. – WestLangley
Хм, на самом деле я перемещаю камеру и самолет. Камера перемещается, устанавливая свое свойство положения, плоскость перемещается исключительно в вершинном шейдере. Поэтому мне кажется, что камера не принимает во внимание репозициюg в вершинном шейдере. – padde
Итак, в основном мне интересно, есть ли способ избежать этого (неправильного?) Обрезания при перемещении геометрии в вершинном шейдере. Или я делаю что-то совершенно неправильное здесь? – padde