相机旋转后的WebGL平移(以FPS格式) [英] WebGL translation after rotation of the camera (as an FPS)

查看:253
本文介绍了相机旋转后的WebGL平移(以FPS格式)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经用c ++和OpenGL完成了一些项目,现在我正在用html5和WebGL创建一个简单的项目.

I've already done some projects with c++ and OpenGL, now I'm creating a simple project with html5 and WebGL.

问题是,旋转相机后,移动始终沿默认轴移动,而不是沿旋转轴移动.例如:我向前移动->没问题,我将摄像机向右旋转了90度->没问题,现在我要指出的是,如果我向前走,则摄像机将沿着世界坐标轴(因此,在摄像机的前面, (例如FPS游戏),但相机始终朝着z轴的起点(正向的起点轴)移动.奇怪的是我的代码在OpenGL上运行良好,而现在在webGL上不再运行.

The problem is, after I rotate the camera, the movement is always along the default axes and not along the rotated ones. For example: I move forward -> no problem, I rotate the camera by 90 degrees right -> no problem, now I aspect that, if I go forward, the camera goes right on the world axes (so in front of the camera, as an FPS game) but the camera goes always towards the starting z axis (the starting forward axis). The weird thing is that my code worked well with OpenGL and now works no more with webGL.

代码的主要部分是用JavaScript编写的.我使用"glMatrix-0.9.5.min"库来简化矩阵计算.

The main part of the code is written in JavaScript. I use the "glMatrix-0.9.5.min" library to simplify matrix calculation.

这些是保存摄像机状态的变量:

These are the variables to save the camera state:

var px = 0.0, py = 2.0, pz = 10.0, ang = 0.0, elev = 0.0, roll = 0.0;
var DELTA_ANG = 0.5, DELTA_MOVE = 0.5;

这是我计算模型视图矩阵并将其传递给着色器的部分:

This is the part in which I calculate the model view matrix and pass it to the shader:

mat4.identity(mvMatrix);    
mat4.translate(mvMatrix, [-px, -py, -pz], mvMatrix);
mat4.rotateX(mvMatrix, degToRad(elev), mvMatrix);   
mat4.rotateY(mvMatrix, degToRad(-ang), mvMatrix);   
mat4.rotateZ(mvMatrix, degToRad(roll), mvMatrix);  
gl.uniformMatrix4fv(shaderProgram.mv_matrix, false, new Float32Array(mvMatrix));

这就是我处理按键事件的方式(当前,PressedKeys是一个数组,我在其中保存了最后的输入):

And this is how I handle the key events (currentlyPressedKeys is an array in which I save the last input):

// rotations    
if(currentlyPressedKeys[J])
{
    ang -= DELTA_ANG;
}
if(currentlyPressedKeys[L])
{
    ang += DELTA_ANG;   
}
if(currentlyPressedKeys[I])
{
    elev += DELTA_ANG;
}
if(currentlyPressedKeys[K])
{
    elev -= DELTA_ANG;  
}
if(currentlyPressedKeys[E]) 
{
    roll += DELTA_ANG;
}
if(currentlyPressedKeys[Q]) 
{
    roll -= DELTA_ANG;
}   

// movements
if(currentlyPressedKeys[A])
{
    px -= DELTA_MOVE * Math.cos(ang * Math.PI / 180.0);
    py += DELTA_MOVE * Math.sin(roll * Math.PI / 180.0);
    pz -= DELTA_MOVE * Math.sin(ang * Math.PI / 180.0);
}
if(currentlyPressedKeys[D])
{
    px += DELTA_MOVE * Math.cos(ang * Math.PI / 180.0);
    py -= DELTA_MOVE * Math.sin(roll * Math.PI / 180.0);
    pz += DELTA_MOVE * Math.sin(ang * Math.PI / 180.0);
}
if(currentlyPressedKeys[W])
{
    px += DELTA_MOVE * Math.sin(ang * Math.PI / 180.0);
    py += DELTA_MOVE * Math.sin(elev * Math.PI / 180.0);
    pz -= DELTA_MOVE * Math.cos(ang * Math.PI / 180.0); 
}
if(currentlyPressedKeys[S])
{
    px -= DELTA_MOVE * Math.sin(ang * Math.PI / 180.0);
    py -= DELTA_MOVE * Math.sin(elev * Math.PI / 180.0);
    pz += DELTA_MOVE * Math.cos(ang * Math.PI / 180.0);
}       

// height
if(currentlyPressedKeys[R])
{
    py += DELTA_MOVE;
}
if(currentlyPressedKeys[F])
{
    py -= DELTA_MOVE;
}   

最后,这是简单的顶点着色器(仅使用mat4.perspective计算了透视矩阵):

Finally, this is the simple vertex shader (the perspective matrix was simply calculated with the mat4.perspective):

attribute vec3 position;
attribute vec3 normal;
attribute vec2 uv;

uniform mat4 p_matrix, mv_matrix;    

varying vec3 f_position;
varying vec3 f_normal;
varying vec2 f_uv;

void main() {
    gl_Position = p_matrix * mv_matrix * vec4(position, 1.0);   
    f_position = position;  
    f_normal = normal;  
    f_uv = uv;
}

我不明白与OpenGL有什么不同吗?

I can't understand what could be the difference from OpenGL, any idea?

推荐答案

我解决了,问题是我在计算摄像机位置时忘记了一些组件. 这是正确的代码:

I solved, the problem was I forgot some components in the calculation of camera position. This is the correct code:

// movements
if(currentlyPressedKeys[A])
{       
    px -= DELTA_MOVE * Math.cos(ang * Math.PI / 180.0);
    px -= DELTA_MOVE * Math.cos(roll * Math.PI / 180.0);
    py -= DELTA_MOVE * Math.sin(elev * Math.PI / 180.0);
    py += DELTA_MOVE * Math.sin(roll * Math.PI / 180.0);
    pz -= DELTA_MOVE * Math.sin(ang * Math.PI / 180.0);
    pz -= DELTA_MOVE * Math.sin(elev * Math.PI / 180.0);        
}
if(currentlyPressedKeys[D])
{
    px += DELTA_MOVE * Math.cos(ang * Math.PI / 180.0);
    px += DELTA_MOVE * Math.cos(roll * Math.PI / 180.0);
    py += DELTA_MOVE * Math.sin(elev * Math.PI / 180.0);
    py -= DELTA_MOVE * Math.sin(roll * Math.PI / 180.0);
    pz += DELTA_MOVE * Math.sin(ang * Math.PI / 180.0);
    pz += DELTA_MOVE * Math.sin(elev * Math.PI / 180.0);
}
if(currentlyPressedKeys[W])
{
    px += DELTA_MOVE * Math.sin(ang * Math.PI / 180.0);
    px += DELTA_MOVE * Math.sin(roll * Math.PI / 180.0);
    py -= DELTA_MOVE * Math.sin(elev * Math.PI / 180.0);
    py += DELTA_MOVE * Math.sin(roll * Math.PI / 180.0);
    pz -= DELTA_MOVE * Math.cos(ang * Math.PI / 180.0);
    pz -= DELTA_MOVE * Math.cos(elev * Math.PI / 180.0);        
}
if(currentlyPressedKeys[S])
{
    px -= DELTA_MOVE * Math.sin(ang * Math.PI / 180.0);
    px -= DELTA_MOVE * Math.sin(roll * Math.PI / 180.0);
    py += DELTA_MOVE * Math.sin(elev * Math.PI / 180.0);
    py -= DELTA_MOVE * Math.sin(roll * Math.PI / 180.0);
    pz += DELTA_MOVE * Math.cos(ang * Math.PI / 180.0);
    pz += DELTA_MOVE * Math.cos(elev * Math.PI / 180.0);
}       

迷雾就是它在OpenGL中的工作方式,但是现在是正确的.

The mistery is how it worked in OpenGL, but now it's correct.

这篇关于相机旋转后的WebGL平移(以FPS格式)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆