将每顶点数据渲染到纹理(Direct3D 11)

时间:2014-02-01 16:22:41

标签: directx textures rendering hlsl direct3d11

我生成简单的2D网格,其中三角形条带代表水面。第一个生成的顶点具有位置[0,0],最后一个具有[1,1]。对于我的水模拟,我需要将顶点的当前位置存储到纹理中,然后从下一帧中的纹理中采样这些值以获得水面的先前状态。

所以,我创建了一个顶点大小的纹理。例如,如果我将有一个10x10顶点网格,我使用一个10x10像素的纹理(一个顶点数据一个像素)。并将此纹理设置为渲染目标,以将所有顶点数据渲染到其中。

根据这个:MSDN Coordinate Systems,如果我将使用网格中顶点的当前位置(左下角为[0; 0],右上角为[1; 1]),渲染纹理看起来像这样:

enter image description here

所以我需要转换到NDC。我在这样的顶点着色器中转换它:

  

[vertex.x * 2 - 1; vertex.y * 2 - 1]

考虑这个3x3网格:

enter image description here

现在,网格被拉伸到整个纹理大小。纹理坐标与NDC不同,显然我可以使用网格的原始坐标(转换前)从纹理中采样值并获取顶点的先前值(位置)。

以下是我的顶点/像素着色器代码示例:

此顶点着色器转换坐标并将其发送到具有SV_POSITION语义的像素着色器(描述像素位置)。

struct VertexInput 
{
    float4 pos : POSITION;
    float2 tex : TEXCOORD;
};

struct VertexOutput 
{
    float4 pos : SV_POSITION;
    float2 tex : TEXCOORD;
};

// convertes coordinates from 0,0 origin to -1,-1, etc.
float2 toNDC(float2 px)
{
    return float2(px.x * 2 - 1, px.y * 2 - 1);
}

VertexOutput main( VertexInput input )
{
    VertexOutput output;

    float2 ndc = toNDC(float2(input.pos.x, input.pos.z));

    output.pos = float4(ndc, 1, 1);
    output.tex = float2(input.pos.x, input.pos.z);

    return output;
}

这里的像素着色器在定义的像素位置(SV_POSITION)保存顶点着色器的值。

struct PixelInput
{
    float4 pos : SV_POSITION;
    float2 tex : TEXCOORD;
};

float4 main(PixelInput input) : SV_TARGET
{
    return float4(input.tex.x, input.tex.y, 0, 1);
}

我们终于解决了我的问题!我在Visual Studio 2012中使用图形调试器,它允许我查看渲染的纹理及其值。我希望在像素位置[0,1](在纹素坐标系中)应该是值[0,0](或者[0,0,0,1]对于RGBA格式来说是精确的)但似乎最终像素的值在3个顶点之间进行插值,并且对于给定的顶点我有一个错误的值。

VS图形调试器的屏幕截图:

渲染3x3纹理(纹素坐标系中的[0; 1]位置):

enter image description here

顶点和像素着色器的值:

enter image description here

如何将顶点着色器的精确值渲染到给定像素的纹理? 我对计算机图形学和Direct3D 11都很陌生,所以请原谅我的不足之处。

0 个答案:

没有答案