getPerspective 实现原理
来源:6-3 透视投影
核桃丷
2023-04-15
我开发中发现,老师实现的透视投影矩阵与第三方库,在相同参数的情况下,得到的结果不一致,请问下老师这两种实现方式有什么区别。
我测试三种方案
- 老师的
gl-matrix
的mat4
的perspective
- chatgpt 生成的
import {mat4} from 'gl-matrix'
const WIDTH = 500
const HEIGHT = 500
/**
* getPerspectiveMatrix 获取透视投影矩阵 (chatgpt 给出的)
* @param {number} fieldOfView 视野角度,单位为弧度
* @param {number} aspectRatio 宽高比
* @param {number} nearPlane 近平面距离
* @param {number} farPlane 远平面距离
* @returns {Float32Array<number>} 透视投影矩阵,使用 Float32Array 表示
*/
const getPerspectiveMatrix = (fieldOfView, aspectRatio, nearPlane, farPlane) => {
const f = Math.tan(Math.PI * 0.5 - 0.5 * fieldOfView);
const rangeInv = 1.0 / (nearPlane - farPlane);
return new Float32Array([
f / aspectRatio, 0, 0, 0,
0, f, 0, 0,
0, 0, (nearPlane + farPlane) * rangeInv, -1,
0, 0, nearPlane * farPlane * rangeInv * 2, 0
]);
}
// 获取透视投影矩阵 (老师的)
function getPerspective(fov, aspect, far, near) {
fov = fov * Math.PI / 180;
return new Float32Array([
1/(aspect*Math.tan(fov / 2)), 0, 0, 0,
0, 1/(Math.tan(fov/2)),0,0,
0,0,-(far+near)/(far-near),-(2*far*near)/(far-near),
0,0,-1,0,
])
}
const perspectiveMatrix1 = getPerspective(150, WIDTH / HEIGHT, 100, 1) // 老师的
const perspectiveMatrix2 = mat4.perspective(new Float32Array(16), 150, WIDTH / HEIGHT, 1, 100) // gl-matrix
const perspectiveMatrix3 = getPerspectiveMatrix(150, WIDTH / HEIGHT, 1, 100) // chatgpt
console.log(perspectiveMatrix1) // 老师的
console.log(perspectiveMatrix2) // gl-matrix
console.log(perspectiveMatrix3) // chatgpt
返回结果:
得出的结果: gl-matrix = chatgpt != 老师
写回答
6回答
-
核桃丷
提问者
2023-04-17
如果按照着矩阵公式的形状来实现js矩阵函数,这个坐标完全就对应不上10 -
核桃丷
提问者
2023-04-17
官方给出的实现代码是
class Mat4 { static perspective(fovy, aspect, near, far, out = []) { const f = 1 / Math.tan(fovy / 2); out[0] = f / aspect; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = f; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[11] = -1; out[12] = 0; out[13] = 0; out[15] = 0; if (far != null && far !== Infinity) { const nf = 1 / (near - far); out[10] = (far + near) * nf; out[14] = 2 * far * near * nf; } else { out[10] = -1; out[14] = -2 * near; } return out; } }
这个 -1 明明在下标 14上,但是却赋值在了 11上,这个11是竖着数的,但是js数组是横着来的,就不是很理解,老师可以帮忙解释下吗132023-07-06 -
yancy
2023-04-17
可以看下lib文件里的使用,有说明要做矩阵转换
00 -
yancy
2023-04-17
可以看下相关实现,比如:z轴的方向,归一化的处理,坐标的处理。一般的不同是由于z轴方向不同导致的
012023-04-17 -
核桃丷
提问者
2023-04-17
012023-04-17 -
核桃丷
提问者
2023-04-17
关于矩阵顺序:如图
00
相似问题