顶点着色器和像素着色器如何相关?

How are vertex shader and pixel shader related?

我知道这个问题已经被问过一百万次了,但我就是不了解一些细节。

举个例子,假设我创建了一个交换链和一个分段 ID3D11Texture2D

我能用它做的是将位图加载到这个 2D 纹理中,然后将其复制到渲染目标(假设两个资源的大小和格式相同)。

现在我想在上面显示一个 sprite。一种解决方案是使用顶点和像素着色器。我的理解问题从这里开始。

顶点着色器:
我想我应该画 2 个三角形(2 个三角形组成一个矩形或四边形)。 DirectX 使用的是左手坐标系,但我想这与这里无关,因为我正在处理 2D 精灵,对吗? 出于同样的原因,我假设我可以忽略 world->view->projection 转换,对吗?其实我这里只需要翻译就可以把精灵放在屏幕上正确的位置,对吧?

这两个三角形的坐标是否应该与 sprite 尺寸相匹配,加上平移? 我应该以什么顺序提供这些顶点?坐标系的原点应该在精灵的中心,还是应该在精灵的左上角?

例如,如果我有 80x70 的精灵,顶点值是多少?

真实顶点:(X、Y、Z - 未应用平移)

1. -40, -35, 0
2. -40,  35, 0
3.  40, -35, 0
4.  40,  35, 0
5. -40,  35, 0
6.  40, -35, 0

对吗?

光栅化步骤应该为精灵中的每个像素调用一次像素着色器。顶点着色器的输出将作为像素着色器的输入。这是否意味着像素着色器应该有权访问精灵,以便在调用时 return 正确的像素值?

对于 2D 绘图,您通常使用 world->view->projection 将经典 'pixel space' 转换为剪辑 space (-1..1)。

float xScale = 2.0f / ViewPortWidth;
float yScale = 2.0f / ViewPortHeight;

[ xScale, 0        0, 0, ]
[ 0,      -yScale, 0, 0, ]
[ 0,      0,       1, 0, ]
[ -1,     1,       0, 1  ]

The -1 and -yScale values are negated so that 0,0 is at the upper-left.

顶点着色器会对剪辑进行变换 space:

void SpriteVertexShader(inout float4 color    : COLOR0,
                        inout float2 texCoord : TEXCOORD0,
                        inout float4 position : SV_Position)
{
    position = mul(position, MatrixTransform);
}

然后对四边形的点进行光栅化,然后调用像素着色器:

Texture2D<float4> Texture : register(t0);
sampler TextureSampler : register(s0);

float4 SpritePixelShader(float4 color    : COLOR0,
                         float2 texCoord : TEXCOORD0) : SV_Target0
{
    return Texture.Sample(TextureSampler, texCoord) * color;
}

See SpriteBatch in the DirectX Tool Kit.