gpt4 book ai didi

opengl - 为什么 GL 为您将 `gl_Position` 除以 W 而不是让您自己做?

转载 作者:行者123 更新时间:2023-12-03 12:05:14 28 4
gpt4 key购买 nike

注意:我了解基本数学。据我了解,典型的 perspective各种数学库中的函数生成一个矩阵,该矩阵将 z 值从 -zNear 转换回 -zFar 回到 -1 到 +1,但前提是结果除以 w具体的问题是 GPU 为您执行此操作而不是您自己执行此操作可以获得什么?
换句话说,假设 GPU 没有神奇地划分 gl_Position通过 gl_Position.w相反,您必须手动进行,如

attribute vec4 position;
uniform mat4 worldViewProjection;

void main() {
gl_Position = worldViewProjection * position;

// imaginary version of GL where we must divide by W ourselves
gl_Position /= gl_Position.w;
}
是什么让这个想象中的 GL 中断了?它会起作用还是在值除以 w 之前传递值?为 GPU 提供额外需要的信息?
请注意,如果我真的这样做,纹理映射透视就会中断。

"use strict";
var m4 = twgl.m4;
var gl = twgl.getWebGLContext(document.getElementById("c"));
var programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);

var bufferInfo = twgl.primitives.createCubeBufferInfo(gl, 2);

var tex = twgl.createTexture(gl, {
min: gl.NEAREST,
mag: gl.NEAREST,
src: [
255, 255, 255, 255,
192, 192, 192, 255,
192, 192, 192, 255,
255, 255, 255, 255,
],
});

var uniforms = {
u_diffuse: tex,
};

function render(time) {
time *= 0.001;
twgl.resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

gl.enable(gl.DEPTH_TEST);
gl.enable(gl.CULL_FACE);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

var projection = m4.perspective(
30 * Math.PI / 180,
gl.canvas.clientWidth / gl.canvas.clientHeight,
0.5, 10);
var eye = [1, 4, -6];
var target = [0, 0, 0];
var up = [0, 1, 0];

var camera = m4.lookAt(eye, target, up);
var view = m4.inverse(camera);
var viewProjection = m4.multiply(projection, view);
var world = m4.rotationY(time);

uniforms.u_worldInverseTranspose = m4.transpose(m4.inverse(world));
uniforms.u_worldViewProjection = m4.multiply(viewProjection, world);

gl.useProgram(programInfo.program);
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
twgl.setUniforms(programInfo, uniforms);
gl.drawElements(gl.TRIANGLES, bufferInfo.numElements, gl.UNSIGNED_SHORT, 0);

requestAnimationFrame(render);
}
requestAnimationFrame(render);
body {  margin: 0; }
canvas { display: block; width: 100vw; height: 100vh; }
<script id="vs" type="notjs">
uniform mat4 u_worldViewProjection;
uniform mat4 u_worldInverseTranspose;

attribute vec4 position;
attribute vec3 normal;
attribute vec2 texcoord;

varying vec2 v_texcoord;
varying vec3 v_normal;

void main() {
v_texcoord = texcoord;
v_normal = (u_worldInverseTranspose * vec4(normal, 0)).xyz;
gl_Position = u_worldViewProjection * position;
gl_Position /= gl_Position.w;
}
</script>
<script id="fs" type="notjs">
precision mediump float;

varying vec2 v_texcoord;
varying vec3 v_normal;

uniform sampler2D u_diffuse;

void main() {
vec4 diffuseColor = texture2D(u_diffuse, v_texcoord);
vec3 a_normal = normalize(v_normal);
float l = dot(a_normal, vec3(1, 0, 0));
gl_FragColor.rgb = diffuseColor.rgb * (l * 0.5 + 0.5);
gl_FragColor.a = diffuseColor.a;
}
</script>
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<canvas id="c"></canvas>

但是,这是因为 GPU 实际上需要 z 和 w 不同,还是只是 GPU 设计,如果我们执行 w,不同的设计可以得出它需要的信息划分我们自己?
更新:
在问了这个问题后,我最终写了 this article that illustrates the perspective interpolation .

最佳答案

我想扩展 BDL 的答案。它不仅仅是关于透视插值。这也是关于剪辑的。空间值gl_Position应该提供的称为剪辑空间,这是在除以 w 之前。
OpenGL 的(默认)剪辑体积在剪辑空间中定义为

-w <= x,y,z <= w   (with w varying per vertex)
除以 w 后,我们得到
-1 <= x,y,z <= 1   (in NDC coordinates).
但是,如果您尝试在除以 w 后进行剪裁,并在 NDC 中检查该立方体,您会遇到问题,因为所有剪裁空间点都满足了这一点:
 w <= x,y,z <= -w (in clip space)
也将满足 NDC 约束。
这里的事情是相机后面的点将被转换到相机前面的某个地方,镜像(因为 x/-1-x/1 相同)。这也发生在 z协调。有人可能会争辩说这是无关紧要的,因为根据典型投影矩阵的构造,相机后面的任何点都投影在远平面的后面(在比远平面更远的意义上),因此它将位于观看体积之外在任一情况下。
但是,如果您有一个图元,其中至少一个点位于 View 体积内,并且至少一个点位于相机后面,那么您应该有一个与近平面相交的图元。 但是,除以 w 后,它将与 far 相交现在坐飞机! .因此,在除法之后,在 NDC 空间中进行剪裁要正确得多。我试图在这张图中形象化:
top-down view of eye space and NDC with and without clipping
(该图是按比例绘制的,投影的深度范围比任何人通常使用的要短得多,以更好地说明问题)。
剪辑是作为硬件中的固定功能阶段完成的,并且必须在除法之前完成,因此您应该提供正确的剪辑空间坐标以进行处理。
(注意:实际的 GPU 可能根本不使用额外的裁剪阶段,它们实际上也可能使用无裁剪的光栅化器,就像在 Fabian Giesen's blog article there 中推测的那样。有一些像 Olano and Greer (1997) 这样的算法。但是,这一切都通过执行直接在齐次坐标中进行光栅化,所以我们仍然需要 w ...)

关于opengl - 为什么 GL 为您将 `gl_Position` 除以 W 而不是让您自己做?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41085117/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com