c++ - 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, 1) : float4(1, 0, 0, 1);
}
现在几乎所有像素都是白色的,正如预期的那样,但顶部偶尔会出现红噪声。我强烈认为这是因为光栅化器使用内部 16.8 定点格式映射到实际像素,因此该定点格式和我的浮点转换之间的映射不能 100% 达成一致。有没有办法解决这个问题?
解决方案
使用ceil()
而不是floor()
.
考虑点光栅化规则, 点光栅化规则
假设 VS 输出的屏幕空间 pos 恰好在整数像素坐标处,则以(n, m)
为中心的像素(n - 0.5, m - .5)
将被光栅化并接收(n - 0.5, m - 0.5)
PS 中的 SV_POSITION,而手动计算的传递给 PS 的 pos 仍然是(n, m)
,这将在之后返回不同的值申请floor()
推荐阅读
- java - 尝试从返回 null 的哈希映射值数组中创建哈希映射键数组
- php - 我无法转换到编辑页面
- c - 在 main() 中调用的 C 函数不返回值
- ignite - 我们可以使用 apache ignite Data streamer 执行 CRUD 操作吗?
- jquery - autocomplete.js 无法正常工作且未填充其他字段
- email - 如何在 Go 中验证电子邮件地址
- node.js - Nodejs + Reactjs + passportjs google登录两个callbackURL作为子站点
- wordpress - 如何在 WordPress 网站中将 URL 从 www.example.com/2020/70 删除到 www.example.com?
- django - 未找到“”的反向。'' 不是有效的视图函数或模式名称 - django 修复
- dotnetnuke - 2sxc cms.run 预填充编辑