顶点着色器和像素着色器如何相关?
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.
我知道这个问题已经被问过一百万次了,但我就是不了解一些细节。
举个例子,假设我创建了一个交换链和一个分段 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.