从此网站: http://www.toymaker.info/Games/html /vertex_shaders.html

我们有以下代码段:

// transformations provided by the app, constant Uniform data
float4x4 matWorldViewProj: WORLDVIEWPROJECTION;

// the format of our vertex data
struct VS_OUTPUT
{
  float4 Pos  : POSITION;
};

// Simple Vertex Shader - carry out transformation
VS_OUTPUT VS(float4 Pos  : POSITION)
{
  VS_OUTPUT Out = (VS_OUTPUT)0;
  Out.Pos = mul(Pos,matWorldViewProj);
  return Out;
}

我的问题是:为什么结构VS_OUTPUT有一个4维向量作为它的位置?不是位置只是x,y和z?

有帮助吗?

解决方案

因为您需要w坐标进行透视计算。从顶点着色器输出后,DirectX执行透视除以w。

基本上如果你有32768,-32768,32768,65536作为输出顶点位置,那么在w除以后得到0.5,-0.5,0.5,1。此时w可以被丢弃,因为它不再需要。然后,此信息将通过视口矩阵传递,该矩阵将其转换为可用的2D坐标。

编辑:如果你看看如何使用投影矩阵执行矩阵乘法,你可以看到这些值是如何放在正确的位置的。

采用D3DXMatrixPerspectiveLH中指定的投影矩阵

2*zn/w  0       0              0
0       2*zn/h  0              0
0       0       zf/(zf-zn)     1
0       0       zn*zf/(zn-zf)  0

并将其应用于随机x,y,z,1(注意顶点位置w将始终为1)顶点输入值得到以下

x' = ((2*zn/w) * x) + (0 * y) + (0 * z) + (0 * w)
y' = (0 * x) + ((2*zn/h) * y) + (0 * z) + (0 * w)
z' = (0 * x) + (0 * y) + ((zf/(zf-zn)) * z) + ((zn*zf/(zn-zf)) * w)
w' = (0 * x) + (0 * y) + (1 * z) + (0 * w)

您可以立即看到w和z不同。 w coord现在只包含传递给投影矩阵的z坐标。 z包含更复杂的东西。

所以..假设我们的输入位置为(2,1,5,1),我们的zn(Z-Near)为1,zf(Z-Far为10),aw(宽度)为1和啊(身高)1。

通过我们传递这些值

x' = (((2 * 1)/1) * 2
y' = (((2 * 1)/1) * 1
z' = ((10/(10-1)  * 5 + ((10 * 1/(1-10)) * 1)
w' = 5

扩展我们然后得到

x' = 4
y' = 2
z' = 4.4
w' = 5

然后我们执行最后的视角划分,我们得到

x'' = 0.8
y'' = 0.4
z'' = 0.88
w'' = 1

现在我们有了最终的坐标位置。这假设x和y的范围是-1到1,z的范围是0到1.正如您所看到的那样,顶点在屏幕上。

作为一个奇怪的奖励你可以看到,如果| x'|或| y'|或| z'|大于| w'|或者z'小于0表示顶点在屏幕外。此信息用于将三角形剪切到屏幕。

无论如何,我认为这是一个非常全面的答案:D

Edit2:警告我正在使用ROW主要矩阵。列主要矩阵被转置。

其他提示

旋转由3维矩阵指定并由矢量平移。您可以在“单个”中执行两个变换。通过将它们组合成单个4 x 3矩阵来进行操作:

rx1 rx2 rx3 tx1
ry1 ry2 ry3 ty1
rz1 rz2 rz3 tz1

然而,由于这不是正方形,因此存在无法执行的各种操作(一个反转)。通过添加额外的行(无效):

0   0   0   1

所有这些操作都成为可能(如果不容易的话)。

Goz在他的答案是通过制作“1”和“1”。非标识值矩阵成为透视变换。

剪切是此过程的重要部分,因为它有助于可视化几何体的变化。剪切阶段实质上丢弃了原始中位于以原点为中心的2单元立方体之外的任何点(好的,你必须重建部分剪切但在这里无关紧要的图元)。

有可能构建一个直接将世界空间坐标映射到这样一个立方体的矩阵,但从远处平面到近平面的逐渐移动将是线性的。也就是说,当距离观察者一英里时,一只脚(朝向观察者)的移动将导致与距离相机几英尺处的一只脚的移动相同的尺寸增加。

但是,如果我们在向量(w)中有另一个坐标,我们可以将向量分组为w,并且我们的基元不会表现出上述行为,但我们仍然可以使它们最终在2中-unit cube above。

有关详细说明,请参阅 http://www.opengl.org /resources/faq/technical/depthbuffer.htm#0060 http:// en .wikipedia.org /维基/ Transformation_matrix#Perspective_projection

一个简单的答案就是说,如果你不告诉管道什么是w,那么你没有给它足够的关于你的预测的信息。这可以直接验证,而无需了解管道对它的作用......

您可能知道4x4矩阵可以根据每个部分的功能分成几部分。进行旋转或缩放操作时,左上角的3x3矩阵会发生变化。翻译时会更改第四列。如果您检查透视矩阵,它会改变矩阵的底行。然后,如果您查看Matrix-Vector乘法的完成方式,您会看到矩阵的底行仅影响向量的合成w分量。因此,如果你没有告诉管道w它将没有你所有的信息。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top