DirectX Clip空间纹理坐标

时间:2012-02-23 22:14:02

标签: c++ directx textures hlsl quad

好的,首先我正在使用:

  • DirectX 10
  • C ++

对我来说这对我来说有点奇怪,我通常不会问这个问题,但我已经被环境所迫。我有两个三角形(不是四边形,原因我不会进入!)全屏,通过它们未被转换的事实对齐屏幕。

在DirectX顶点声明中,我传递了一个3分量浮点数(Pos x,y,z)和2个组件浮点数(Texcoord x,y)。 Texcoord z保留给texture2d数组,我目前在像素着色器中默认为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;
}

在我的Vertex和Pixel着色器中,对于此特定绘制调用并没有发生太多事情,像素着色器使用指定的UV坐标从纹理中进行大部分工作。但是,这并没有像预期的那样有效,看起来我的只有1个像素的采样纹理。

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

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 个答案:

答案 0 :(得分:1)

您为顶点类型指定了哪些语义?它们是否与您的顶点以及着色器正确对齐?如果您使用D3DXVECTOR4,D3DXVECTOR3设置(如VS代码中所示),如果您的CreateVertex()返回D3DXVECTOR3,D3DXVECTOR2结构,则可能会出现问题。 看到你的像素着色器代码也会令人放心。

答案 1 :(得分:1)

好吧,首先,0..1范围之外的纹理坐标会被钳制。我犯了一个错误,假设通过去剪裁空间-1到+1,纹理坐标也是如此。情况并非如此,它们仍然从0.0到1.0。

像素着色器中的代码工作的原因是因为它使用剪辑空间x,y,z坐标来自动覆盖这些纹理坐标;我的疏忽。但是,像素着色器代码会在全屏“四边形”上产生纹理拉伸,因此对某些人来说可能会有用;)