微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

HLSL:如何像光栅化器一样将顶点转换为屏幕空间,但具有亚像素精度?

如何解决HLSL:如何像光栅化器一样将顶点转换为屏幕空间,但具有亚像素精度?

我想使用顶点和像素着色器绘制一个点列表。每个点的渲染颜色应代表其亚像素精确的屏幕空间坐标(输出到 R32G32_FLOAT 纹理)。 我在我的 VS 中执行以下操作:

struct VSOutput
{
    float4 position : SV_Position;
    float2 screenSpacePosition : COLOR;
};

VSOutput VS(uint index : SV_VertexID)
{
    float3 pointPos = inPointPositions[index];
    VSOutput output;
    output.position = mul(transform,float4(pointPos,1));
    output.screenSpacePosition = (float2(+1,-1) * output.position.xy / output.position.w * 0.5f + 0.5f) * float2(width,height);
    return output;
}

在我的 PS 中,我通常只使用 screenSpacePosition 字段作为我的最终目标颜色,但是由于我遇到了一些问题,我对其进行了更改以验证计算出的 screenSpacePosition 与用于光栅化的实际像素位置一致(以调试问题)。如果计算的 screenSpacePosition 与光栅化位置匹配,它将输出白色,否则输出红色。

float4 PS(VSOutput input) : SV_Target
{
    return all(floor(output.screenSpacePosition) == floor(input.position.xy)) ? float4(1,1,1) : float4(1,1);
}

现在几乎所有像素都是白色的,正如预期的那样,但顶部偶尔会出现红色噪声。我强烈假设这样做的原因是光栅化器使用内部 16.8 定点格式映射到实际像素,因此该定点格式和我的浮点转换之间的映射不会 100% 一致。 有什么办法可以解决这个问题吗?

解决方法

使用 ceil() 而不是 floor()

考虑点光栅化规则, Point Rasterization Rules

假设 VS 输出的屏幕空间 pos 恰好位于整数像素坐标 (n,m),则以 (n - 0.5,m - .5) 为中心的像素将被光栅化并在 PS 中接收 SV_POSITION (n - 0.5,m - 0.5),而传给PS的手工计算的pos还是(n,m),应用floor()

后会返回不同的值

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。