У меня есть простая THREE.Scene, где основным содержимым является сетка THREE.Line, которая визуализирует путь на основе ключевого кадра, по которому камера будет следовать для некоторой анимации по сценарию. Затем существует одна сетка на основе THREE.SphereGeometry, которая всегда перемещается в текущее положение камеры.
В настоящее время НЕПРАВИЛЬНЫЙ результат выглядит следующим образом (фрактальный фон визуализируется независимо, но с использованием одного и того же ввода ключевого кадра - и, в конечном итоге, идея состоит в том, что визуализация «пути камеры» заканчивается в том же масштабе/проекции, что и соответствующий фрактальный фон...) :
База представляет собой массив ключевых кадров, каждый из которых представляет modelViewMatrix для определенного положения/ориентации камеры и напрямую используется для управления вершинным шейдером для фона, например:
varying vec3 eye, dir;
void main() {
gl_Position = vec4(position, 1.0);
eye = vec3(modelViewMatrix[3]);
dir = vec3(modelViewMatrix * vec4(position.x , position.y , 1, 0));
}
(насколько я понимаю, «глаз» — это в основном положение камеры, в то время как «режим» отражает ориентацию камеры, и то, как он используется во время марша луча, неявно приводит к перспективной проекции)
Соответствующие объекты сетки создаются следующим образом:
visualizeCameraPath: function(scene) {
// debug: visualize the camera path
var n= this.getNumberOfKeyFrames();
var material = new THREE.LineBasicMaterial({
color: 0xffffff
});
var geometry = new THREE.Geometry();
for (var i= 0; i<n; i++) {
var m= this.getKeyFrameMatrix(true, i);
var pos= new THREE.Vector3();
var q= new THREE.Quaternion();
var scale= new THREE.Vector3();
m.decompose(pos,q,scale);
geometry.vertices.push( new THREE.Vector3( pos.x, pos.y, pos.z ));
}
this.camPath = new THREE.Line( geometry, material );
this.camPath.frustumCulled = false; // Avoid getting clipped - does not seem to help one little bit
scene.add( this.camPath );
var radius= 0.04;
var g = new THREE.SphereGeometry(radius, 10, 10, 0, Math.PI * 2, 0, Math.PI * 2);
this.marker = new THREE.Mesh(g, new THREE.MeshNormalMaterial());
scene.add(this.marker);
}
чтобы воспроизвести анимацию, я обновляю камеру и позицию маркера следующим образом (думаю, это уже неправильно, как я использую входную матрицу «m» непосредственно на «shadowCamera» — хотя я думаю, что она содержит правильную позицию):
syncShadowCamera(m) {
var pos= new THREE.Vector3();
var q= new THREE.Quaternion();
var scale= new THREE.Vector3();
m.decompose(pos,q,scale);
this.applyMatrix(m, this.shadowCamera); // also sets camera position to "pos"
// highlight current camera-position on the camera-path-line
if (this.marker != null) this.marker.position.set(pos.x, pos.y, pos.z);
},
applyMatrix: function(m, targetObj3d) {
var pos= new THREE.Vector3();
var q= new THREE.Quaternion();
var scale= new THREE.Vector3();
m.decompose(pos,q,scale);
targetObj3d.position.set(pos.x, pos.y, pos.z);
targetObj3d.quaternion.set(q.x, q.y, q.z, q.w);
targetObj3d.scale= scale;
targetObj3d.updateMatrix(); // this.matrix.compose( this.position, this.quaternion, this.scale );
targetObj3d.updateMatrixWorld(true);
},
Я пробовал несколько вещей в отношении камеры, и на снимке экрана показан вывод с отключенным «this.projectionMatrix» (см. код ниже).
createShadowCamera: function() {
var speed = 0.00039507;
var z_near = Math.abs(speed);
var z_far = speed * 65535.0;
var fH = Math.tan( this.FOV_Y * Math.PI / 360.0 ) * z_near;
var fW = Math.tan( this.FOV_X * Math.PI / 360.0 ) * z_near;
// orig opengl used: glFrustum(-fW, fW, -fH, fH, z_near, z_far);
var camera= new THREE.PerspectiveCamera();
camera.updateProjectionMatrix = function() {
// this.projectionMatrix.makePerspective( -fW, fW, fH, -fH, z_near, z_far );
this.projectionMatrix= new THREE.Matrix4(); // hack: fallback to no projection
};
camera.updateProjectionMatrix();
return camera;
},
Моя первоначальная попытка состояла в том, чтобы использовать те же настройки, что и шейдер opengl для фрактального фона (см. glFrustum выше). К сожалению, кажется, что мне еще удалось правильно сопоставить входную "modelViewMatrix" (и проекцию, неявно выполняемую raymarching в шейдере) с эквивалентными настройками THREE.PerspectiveCamera (ориентация/projectionMatrix).
Есть ли здесь специалист по расчету матриц, который знает, как получить правильные преобразования?