我正在尝试在我自己的 webGL 引擎上开发延迟渲染。我已经准备好计算闪电的一切,但我无法从深度缓冲区正确重建位置......
现在,我正在尝试使用 JS 在 CPU 上的着色器中进行计算,如果我能够获得正确的位置,则将其转换为着色器。这是JS代码:
var model = mat4.create();
var view = mat4.create();
var projection = mat4.perspective(mat4.create(), 45, gl.canvas.width/gl.canvas.height, 0.1, 100);
var pos = [0,0,-1,1];
var viewport = gl.getViewport();
var modelview = mat4.multiply(mat4.create(), view, model);
var viewprojection = mat4.multiply(mat4.create(), projection, view);
var mvp = mat4.multiply(mat4.create(), projection, modelview);
var posScreenCoords = vec4.transformMat4(vec4.create(), pos, mvp);
var vec3unproj = vec3.create();
vec3.unproject(vec3unproj, [posScreenCoords[0],posScreenCoords[1],posScreenCoords[2]], viewprojection, viewport);
我知道有一些无用的计算,比如当模型和视图处于同一位置时相乘,但我希望它们在那里只是为了逐步显示。
在标识处,相机面向 [0,0,-1] 世界坐标,所以当我用 MVP 矩阵变换这个坐标以获得屏幕坐标时,它应该会在屏幕中心产生一个点 [0 ,0,Z],这就是我得到的。
此时一切正常。这是我卡住的地方。我的环境与我在着色器中的环境相同,我有一个 XY ,它是屏幕坐标,还有一个 Z 。我必须将这个坐标解投影到世界坐标。我正在使用 gl-matrix 库,但它没有vec3.unproject
并从外部源获取它,但我没有从中获得所需的结果 [0,0,-1]:
var unprojectMat = mat4.create();
var unprojectVec = vec4.create();
vec3.unproject = function (out, vec, viewprojection, viewport) {
var m = unprojectMat;
var v = unprojectVec;
v[0] = (vec[0] - viewport[0]) * 2.0 / viewport[2] - 1.0;
v[1] = (vec[1] - viewport[1]) * 2.0 / viewport[3] - 1.0;
v[2] = 2.0 * vec[2] - 1.0;
v[3] = 1.0;
if(!mat4.invert(m,viewprojection))
return null;
vec4.transformMat4(v, v, m);
if(v[3] === 0.0)
return null;
out[0] = v[0] / v[3];
out[1] = v[1] / v[3];
out[2] = v[2] / v[3];
return out;
};
你可以在这里看到测试。有任何想法吗?谢谢