DirectX剪裁空间纹理坐标

5

首先,我正在使用:

  • DirectX 10
  • C ++

这是一个对我来说有点奇怪的问题,我通常不会问这个问题,但是由于情况所迫,我不得不这样做。我有两个三角形(不是四边形,因为某些原因),它们在全屏幕上对齐,因为它们没有经过变换。

在DirectX顶点声明中,我传递了一个3组分浮点数(Pos x,y,z)和2组分浮点数(Texcoord x,y)。Texcoord z保留用于纹理二维数组,在像素着色器中我将其默认值设为0。

我编写了以下内容以完成简单任务:

float fStartX = -1.0f;
float fEndX = 1.0f;
float fStartY = 1.0f;
float fEndY = -1.0f;
float fStartU = 0.0f;
float fEndU = 1.0f;
float fStartV = 0.0f;
float fEndV = 1.0f;
vmvUIVerts.push_back(CreateVertex(fStartX, fStartY, 0, fStartU, fStartV));
vmvUIVerts.push_back(CreateVertex(fEndX, fStartY, 0, fEndU, fStartV));
vmvUIVerts.push_back(CreateVertex(fEndX, fEndY, 0, fEndU, fEndV));
vmvUIVerts.push_back(CreateVertex(fStartX, fStartY, 0, fStartU, fStartV));
vmvUIVerts.push_back(CreateVertex(fEndX, fEndY, 0, fEndU, fEndV));
vmvUIVerts.push_back(CreateVertex(fStartX, fEndY, 0, fStartU, fEndV));

IA布局:(更新)

D3D10_INPUT_ELEMENT_DESC ieDesc[2] = {
    { "POSITION",   0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
    { "TEXCOORD",   0, DXGI_FORMAT_R32G32B32_FLOAT, 0,12, D3D10_INPUT_PER_VERTEX_DATA, 0 }
};

数据以以下格式到达顶点着色器:(更新)
struct VS_INPUT
{ 
    float3 fPos          :POSITION;
    float3 fTexcoord     :TEXCOORD0;
}

在这个特定的绘制调用中,我的顶点着色器和像素着色器中没有太多发生的事情,像素着色器使用指定的UV坐标从纹理中取样完成大部分工作。然而,这并没有按照预期工作,似乎我只得到了一个像素的采样纹理。

解决方法是在像素着色器中执行以下操作:(更新)

sampler s0                      : register(s0);
Texture2DArray<float4> meshTex  : register(t0);
float4 psMain(in VS_OUTPUT vOut) : SV_TARGET
{
    float4 Color;
    vOut.fTexcoord.z = 0;
    vOut.fTexcoord.x = vOut.fPosObj.x * 0.5f;
    vOut.fTexcoord.y = vOut.fPosObj.y * 0.5f;
    vOut.fTexcoord.x += 0.5f;
    vOut.fTexcoord.y += 0.5f;
    Color = quadTex.Sample(s0, vOut.fTexcoord);
    Color.a = 1.0f;
    return Color;
}

值得注意的是,这适用于着色器中定义的以下VS out结构:
struct VS_OUTPUT
{
    float4 fPos          :POSITION0; // SV_POSITION wont work in this case
    float3 fTexcoord    :TEXCOORD0;
}

现在我有一个纹理,它被拉伸以适应整个屏幕,两个三角形已经覆盖了它,但是为什么纹理UV坐标没有按预期使用呢?

澄清一下,我正在使用一个点采样器,并尝试过夹紧和包裹UV。

我有点好奇,找到了上面提到的解决方案/解决方法,然而如果有人知道为什么会发生这种情况,我更愿意不必这样做。

2个回答

1

首先,纹理坐标超出0..1范围会被夹紧。我犯了一个错误,认为通过将剪辑空间从-1到+1,纹理坐标也会这样。但事实并非如此,它们仍然从0.0到1.0。

像素着色器中的代码之所以有效,是因为它使用剪辑空间x、y、z坐标自动覆盖这些纹理坐标;这是我的疏忽。然而,像素着色器代码在全屏“四边形”上导致纹理拉伸,因此它可能对某个人有用;)


1
你为顶点类型指定了什么语义?它们是否与你的顶点和着色器正确对齐?如果你正在使用 D3DXVECTOR4、D3DXVECTOR3 设置(如你的 VS 代码所示),那么如果 CreateVertex() 返回一个 D3DXVECTOR3、D3DXVECTOR2 结构体,这可能会成为一个问题。看到你的像素着色器代码也会让人放心。

更新的问题,我不太明白它与此相关性如何,就好像我在这个环境中工作了很长时间一样。 - Jay
CreateVertex没有什么特别的,返回我想要的结果。唯一可能不同的是texcoord Z没有被使用,并且留给将来使用纹理数组。 - Jay
对齐方式正确,步幅值为24字节(不是16字节的整数倍,但由于dx自动填充,仍应该可以正常工作)。 - Jay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接