【发布时间】:2015-05-14 17:47:17
【问题描述】:
如果我想在 WebGL 中更改对象的大小或位置,我会获取该对象的原始顶点数据 {x,y,z} 并将其传递给顶点着色器,在此与矩阵相乘,它包含有关转换的信息,从而产生一组新的坐标,该坐标只有我的 GPU 知道,但我不可见。
效果很好,就唯一重要的是屏幕上的图片,但我希望能够在没有关于矩阵乘法的其他信息的情况下保存转换后的顶点,就像 x、y、z 值一样,就像原始数据一样。
我的想法是,在 JavaScript 中将转换矩阵与原始顶点数据相乘的最后一步,但我就是不让它工作!
我编写了以下函数,将 4x4 矩阵与 x,y,z 值数组相乘,通过添加第四个值 {1.0} 将 vec3-data 更改为 vec4-data...
function matrixVectorProduct (mat4, data) {
var result = new Array( );
for (var i = 0; i < data.length / 3; i++) {
var n = i * 3;
var vec4 = [data[n], data[n + 1], data[n + 2], 1.0];
var x = mat4[0] * vec4[0] + mat4[1] * vec4[1] +
mat4[2] * vec4[2] + mat4[3] * vec4[3];
var y = mat4[4] * vec4[0] + mat4[5] * vec4[1] +
mat4[6] * vec4[2] + mat4[7] * vec4[3];
var z = mat4[8] * vec4[0] + mat4[9] * vec4[1] +
mat4[10] * vec4[2] + mat4[11] * vec4[3];
var w = mat4[12] * vec4[0] + mat4[13] * vec4[1] +
mat4[14] * vec4[2] + mat4[15] * vec4[3];
result.push(x, y, z, w);
}
return result;
}
...但除了我不知道如何将 vec4 值转换回 vec3 值这一事实之外,整个概念肯定有问题:
假设我们有一个简单三角形的顶点
var vertices = [0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, -1.0, 0.0];
我们创建了一个 4x4 矩阵
function createMat4 ( ) {
var mat4 = new Float32Array(16);
mat4[0] = 1; mat4[1] = 0; mat4[2] = 0; mat4[3] = 0;
mat4[4] = 0; mat4[5] = 1; mat4[6] = 0; mat4[7] = 0;
mat4[8] = 0; mat4[9] = 0; mat4[10] = 1; mat4[11] = 0;
mat4[12] = 0; mat4[13] = 0; mat4[14] = 0; mat4[15] = 1;
return mat4;
}
翻译它 - 比如说 [0, 0, -5] - 使用这个函数
function translateMat4 (mat4, vec3) {
var x = vec3[0],
y = vec3[1],
z = vec3[2];
var a = mat4;
mat4[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
mat4[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
mat4[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
mat4[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
return mat4;
}
最后使用上面提到的matrixVectorProduct函数将创建和转换的矩阵与存储在vertices中的顶点数据相乘,结果应该是
translatedVertices = [0.0, 1.0, -5.0, -1.0, -1.0, -5.0, 1.0, -1.0, -5.0];
但它只是[x,y,z,1],因为-5 x 0.0(z值)等于0,所以不能这样工作。
我做错了什么?
【问题讨论】:
-
"我不知道如何将 vec4 值转换回 vec3" 您需要将向量除以 w,这是在着色器中隐式完成的。跨度>
-
@LJ_1102 Moin und danke für die 信息!正如 Entity Black 所说,我将不得不分别编写单独的函数,用于将平移/旋转/缩放矩阵内容转换为顶点数据......
-
好吧,也许我不明白你的目标是什么,但你当然不需要分解你的矩阵变换来将它应用到顶点。也许看看vec3.transformMat4的实现(翻译应用在第498行)。除了 perspective divide for
gl_Position之外,着色器中没有任何“神奇”发生。
标签: javascript webgl