Camera WebGL在视线中移动对象

Camera WebGL在视线中移动对象,camera,webgl,Camera,Webgl,我定义了我的模型视图矩阵,定义了一个函数lookAt,它表示相机的眼睛、我所表示的对象的位置以及相机的“向上”向量。如何在相机的视线内移动对象?有什么建议吗?如果我定义了指向对象位置的向量,并从相机的眼睛开始(因此如果我定义了视线),我如何使用它使对象沿着这个方向移动 这是我的lookAt函数 function lookAt( eye, at, up ) { if ( !Array.isArray(eye) || eye.length != 3) { throw "l

我定义了我的模型视图矩阵,定义了一个函数lookAt,它表示相机的眼睛、我所表示的对象的位置以及相机的“向上”向量。如何在相机的视线内移动对象?有什么建议吗?如果我定义了指向对象位置的向量,并从相机的眼睛开始(因此如果我定义了视线),我如何使用它使对象沿着这个方向移动

这是我的lookAt函数

  function lookAt( eye, at, up )
{
    if ( !Array.isArray(eye) || eye.length != 3) {
        throw "lookAt(): first parameter [eye] must be an a vec3";
    }

    if ( !Array.isArray(at) || at.length != 3) {
        throw "lookAt(): first parameter [at] must be an a vec3";
    }

    if ( !Array.isArray(up) || up.length != 3) {
        throw "lookAt(): first parameter [up] must be an a vec3";
    }

    if ( equal(eye, at) ) {
        return mat4();
    }

    var v = normalize( subtract(at, eye) );  // view direction vector
    var n = normalize( cross(v, up) );       // perpendicular vector
    var u = normalize( cross(n, v) );        // "new" up vector

    v = negate( v );

    var result = mat4(
        vec4( n, -dot(n, eye) ),
        vec4( u, -dot(u, eye) ),
        vec4( v, -dot(v, eye) ),
        vec4()
    );

    return result;
}

老实说,我不明白你在看函数。它不像大多数look-at函数那样设置转换

这里有一个不同的lookAt函数,它生成一个摄像机矩阵,一个将摄像机定位在世界上的矩阵。这与生成视图矩阵的lookAt函数形成了对比,该矩阵可以在摄像机前移动世界上的所有东西

function lookAt(eye, target, up) {
  const zAxis = v3.normalize(v3.subtract(eye, target));
  const xAxis = v3.normalize(v3.cross(up, zAxis));
  const yAxis = v3.normalize(v3.cross(zAxis, xAxis));

  return [
    ...xAxis, 0,
    ...yAxis, 0,
    ...zAxis, 0,
    ...eye, 1,
  ];
}
给你

我发现摄像机矩阵更有用,因为摄像机矩阵(或注视矩阵)可以用来让头部注视其他物体。炮塔看目标,眼睛看兴趣,作为一个视图矩阵几乎只能用于一件事。你可以从另一个得到一个。但是,由于一个场景中有炮塔、眼睛和跟踪物体的角色头部,可能需要50多个注视矩阵,因此生成这种矩阵并取1个逆矩阵或一个视图矩阵似乎比生成50多个视图矩阵并必须反转除1个以外的所有矩阵更有用

通过获取摄影机矩阵的轴并乘以某个标量,可以相对于摄影机面对的方向移动任何对象。X轴将垂直于相机左右移动,Y轴垂直于相机上下移动,Z轴沿相机所面对的方向向前/向后移动

摄影机矩阵的轴是

+----+----+----+----+
| xx | xy | xz |    |  xaxis
+----+----+----+----+
| yx | yy | yz |    |  yaxis
+----+----+----+----+
| zx | zy | zz |    |  zaxis
+----+----+----+----+
| tx | ty | tz |    |  translation
+----+----+----+----+
换句话说

const camera = lookAt(eye, target, up);
const xaxis = camera.slice(0, 3);
const yaxis = camera.slice(4, 7);
const zaxis = camera.slice(8, 11);
现在,您可以使用

matrix = mult(matrix, zaxis);  // moves 1 unit away from camera
将zaxis乘以要移动的数量

moveVec = [zaxis[0] * moveAmount, zaxis[1] * moveAmount, zaxis[2] * moveAmount];
matrix = mult(matrix, moveVec);  // moves moveAmount units away from camera
或者,如果你的翻译存储在别处,只需将zaxis添加到

// assuming tx, ty, and tz are our translation
tx += zaxis[0] * moveAmount;
ty += zaxis[1] * moveAmount;
tz += zaxis[2] * moveAmount;
const vs=`
均匀mat4 u_世界视图投影;
属性向量4位置;
属性向量2 texcoord;
可变vec4 v_位置;
可变矢量2 v_texcoord;
void main(){
v_texcoord=texcoord;
gl_位置=u_世界视图投影*位置;
}
`;
常数fs=`
精密中泵浮子;
可变矢量2 v_texcoord;
均匀的二维u_纹理;
void main(){
gl_FragColor=纹理2D(u_纹理,v_texcoord);
}
`;
“严格使用”;
常数m4=twgl.m4;
常数v3=twgl.v3;
const gl=document.getElementById(“c”).getContext(“webgl”);
//编译着色器、链接程序、查找位置
const programInfo=twgl.createProgramInfo(gl[vs,fs]);
//调用gl.createBuffer、gl.bindBuffer、gl.bufferData以获取位置、texcoords
const bufferInfo=twgl.primitives.createCubeBufferInfo(gl);
//调用gl.createTexture、gl.bindTexture、gl.texImage2D、gl.texParameteri
常量tex=twgl.createTexture(gl{
最小值:gl最近值,
杂志:德国劳埃德船级社,
src:[
255, 64, 64, 255,
64, 192, 64, 255,
64, 64, 255, 255,
255, 224, 64, 255,
],
});
常量设置={
xoff:0,
约夫:0,
佐夫:0,
};
函数渲染(时间){
时间*=0.001;
twgl.resizeCanvasToDisplaySize(总图画布);
总图视口(0,0,总图画布宽度,总图画布高度);
总帐启用(总帐深度测试);
总账启用(总账消隐面);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
常数fov=45*Math.PI/180;
const aspect=gl.canvas.clientWidth/gl.canvas.clientHeight;
常数zNear=0.01;
常数zFar=100;
常量投影=m4.透视图(视野、纵横比、zNear、zFar);
常数眼=[3,4,-6];
常量目标=[0,0,0];
const up=[0,1,0];
常量摄影机=m4。注视(眼睛、目标、向上);
常量视图=m4。反向(摄像头);
const viewProjection=m4.乘法(投影,视图);
总账使用程序(programInfo.program);
//调用gl.bindBuffer、gl.enableVertexAttributeArray、gl.VertexAttributePointer
twgl.setBuffersAndAttributes(总帐、程序信息、缓冲信息);
常数t=时间*.1;
for(设z=-1;z