Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ D3D11/C++;像素着色器中的uv插值不准确。如何避免?_C++_Direct3d11_Uv Mapping - Fatal编程技术网

C++ D3D11/C++;像素着色器中的uv插值不准确。如何避免?

C++ D3D11/C++;像素着色器中的uv插值不准确。如何避免?,c++,direct3d11,uv-mapping,C++,Direct3d11,Uv Mapping,我正试图在屏幕上绘制一个具有纹理的四边形,以便纹理和像素完全对齐。听起来很简单。我使用这些着色器绘制了2个三角形(作为三角形列表,因此有6个顶点): struct VSOutput { float4 position : SV_POSITION; float2 uv : TEXCOORD0; }; VSOutput VS_Draw(uint index : SV_VertexId) { uint vertexIndex = index % 6

我正试图在屏幕上绘制一个具有纹理的四边形,以便纹理和像素完全对齐。听起来很简单。我使用这些着色器绘制了2个三角形(作为三角形列表,因此有6个顶点):

struct VSOutput
{
    float4 position     : SV_POSITION;
    float2 uv           : TEXCOORD0;
};

VSOutput VS_Draw(uint index : SV_VertexId)
{
    uint vertexIndex = index % 6;
    // compute face in [0,0]-[1,1] space
    float2 vertex = 0;
    switch (vertexIndex)
    {
        case 0: vertex = float2(0, 0);  break;
        case 1: vertex = float2(1, 0);  break;
        case 2: vertex = float2(0, 1);  break;
        case 3: vertex = float2(0, 1);  break;
        case 4: vertex = float2(1, 0);  break;
        case 5: vertex = float2(1, 1);  break;
    }
    // compute uv
    float2 uv = vertex;
    // scale to size
    vertex = vertex * (float2)outputSize;
    vertex = vertex + topLeftPos;
    // convert to screen space
    VSOutput output;
    output.position = float4(vertex / (float2)outputSize * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0, 1);
    output.uv = uv;
    return output;
}

float4 PS_Draw(VSOutput input) : SV_TARGET
{
    uint2 pixelPos = (uint2)(input.uv * (float2)outputSize);
    // output checker of 4x4
    return (((pixelPos.x >> 2) & 1) ^ ((pixelPos.y >> 2) & 1) != 0) ? float4(0, 1, 1, 0) : float4(1, 1, 0, 0);
}
其中outputSize和topLeftPos是常量,以像素单位表示

现在,对于outputSize=(102,12)和topLeftPos=(0,0),我得到了(我所期望的):

但是对于outputSize=(102,12)和topLeftPos=(0,0.5),我得到:x=0,y=0.5的输出

如您所见,两个三角形连接处存在uv不连续性,uv插值不准确)。这基本上(在x和y方向)只发生在.5附近的位置(实际上在.49以下,它正确地捕捉到纹理0和以上。51它正确地捕捉到纹理1,但在这两者之间,我得到了这个工件)


现在,为了达到这个目的,我需要它,因为它是必不可少的像素完美的映射。有人能启发我为什么会发生这种情况吗?

< P>有两件事你需要考虑去理解正在发生的事情:

  • 窗口空间中的像素角点具有整数坐标,窗口空间中的像素中心具有半整数坐标
  • 当三角形光栅化时,D3D11将所有属性插值到像素中心
因此,当
topLeftPos=(0,0)
时,
input.uv*(float2)outputSize
的值始终为半整数,并且始终向下舍入到最接近的整数。但是,当
topLeftPos=(0,0.5)
时,
(input.uv*(float2)outputSize).y
应始终为整数。然而,由于不可预测的浮点精度问题,它有时比精确整数小一些,在这种情况下,它被舍入得太多。这是你看到你伸展的方块的地方


因此,如果您想要完美的映射,您的源正方形应该与像素边界对齐,而不是与像素中心对齐。

您使用的是什么硬件功能级别?