我有一个简单的 THREE.Scene,其中主要内容是一个 THREE.Line 网格,它可视化相机将遵循的一些脚本动画的基于关键帧的路径。然后有一个基于 THREE.SphereGeometry 的网格,始终重新定位到当前相机位置。
当前错误的结果看起来像这样(分形背景是独立渲染的,但使用相同的关键帧输入 - 最终的想法是“相机路径”可视化最终以与相应分形背景相同的比例/投影结束......) :
base 是一个关键帧数组,每个关键帧代表特定相机位置/方向的模型视图矩阵,并直接用于驱动背景的顶点着色器,例如:
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));
}
(据我了解,“eye”基本上是相机位置,而“dir”反映了相机的方向,并且在光线行进期间使用它的方式隐含地导致透视投影)
相应的网格对象是这样创建的:
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);
}
为了播放动画,我像这样更新相机和标记位置(我想我如何直接在“shadowCamera”上使用输入矩阵“m”已经是错误的 - 尽管我认为它包含正确的位置):
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”(以及由着色器中的光线行进隐式执行的投影)映射到等效的 THREE.PerspectiveCamera 设置(方向/投影矩阵)。
这里有没有矩阵计算专家,知道如何获得正确的变换?