【问题标题】:Vertex to Pixel Shader TEXCOORD interpolation precision issuesVertex to Pixel Shader TEXCOORD 插值精度问题
【发布时间】:2015-09-15 16:07:16
【问题描述】:

我认为我在读取从顶点着色器插值的 texcoords 时遇到了像素着色器的精度问题。

我的场景由一些非常大的三角形组成(边长可达 5000 个单位,texcoords 范围从 0 到 5000 个单位,因此纹理平铺了大约 5000 次),并且我有一个看起来非常接近的相机在其中一个三角形上(相机可能非常靠近,以至于它的视口只覆盖了几米的大三角形)。当我沿三角形平面平移相机时,纹理滞后且跳跃。我的想法是,我在插值的 texcoords 上遇到了精度不足的问题。

有没有办法提高texcoords插值的精度?

我的第一个想法是让 texcoord u 以双精度存储在 xy 组件中,而 texcoord v 存储在 zw 组件中。但我想这不会起作用,因为着色器插值假设有 4 个单独的单精度分量,而不是 2 个双精度分量?

如果在着色器方面没有解决方案,我想我只需要将三角形镶嵌成更细的部分?不过,我不想只为这个问题这样做.. 有什么想法吗?

编辑:当在屏幕上打印 texcoords 作为颜色时,这个问题也很明显,根本没有任何实际的纹理采样。

【问题讨论】:

  • 您是否验证过 texcoords 的浮点精度实际上是问题所在?我不确定是不是这样,但请允许我猜测一下:在对纹理进行采样时,纹理坐标会转换为 固定点,通常具有 8 位小数精度。这意味着只有 256 个离散,两个纹素之间的等距位置可供您进行采样。或者,换一种说法:如果您将纹理放大 256 倍以上,您将得到条带伪影。
  • 前几天我也遇到过类似的问题。我通过使纹理更大来停止条带(但是是的,这是一个非常愚蠢的解决方案)。关于如何避免@derhass 问题的任何建议?
  • 问题不在于纹理采样。我尝试将 uv 坐标输出到返回的像素着色器 COLOR,没有任何纹理采样,但仍然遇到同样的问题。
  • 我没有放大纹理。由于纹理坐标的范围为 0-5000 作为顶点位置,因此纹理平铺了 5000 次,这意味着从我的近摄相机来看,纹理与视口大小非常一致。
  • 我遇到的视觉问题并不是真正的条带。这更像是纹理坐标相对于相机运动滞后。例如,如果我将相机平移 5 厘米超过 100 帧,每个像素的纹理坐标(或采样的纹理颜色)似乎不会改变每一帧,而是像每 20 帧一样,即每 1 厘米的相机移动。 (这些数字只是示例,并非实际测量值)。

标签: opengl shader hlsl fragment-shader cg


【解决方案1】:

你是对的,它看起来像一个精度问题。如果您的卡支持它,您确实可以使用双精度浮点数进行插值。只需将变量声明为 dvec2 即可。

着色器插值不假设有 4 个独立的 8 位组件。在最近的卡片中,每个标量(即 vec 中的组件)都作为浮点数(或双精度数)单独插值。只能插入 vec4 的旧卡也可以使用全浮点数(但这些可能不支持双精度)。

【讨论】:

  • 好的。那是 GLSL 语法吗?我用的是cg。从 float2 更改为 double2 编译但会导致相同的问题。经过一些测试,我发现 cg 可能将 double 视为 float,在此确认:“Cg 允许配置文件省略对 int 和其他整数类型的运行时支持。Cg 允许配置文件将 double 视为 float。” link。我可能太低调了(ps_3_0),但似乎在 cg api 中的任何地方都没有重载。无论如何,我尝试对网格进行细分,现在可以了。感谢您的回复。
  • 我对你的最后一段有点困惑。只是为了说清楚;如果我使用的是不支持 dvec2 的旧卡/配置文件,我可以解决插值精度问题吗?
  • 我的意思是所有卡(新旧)都使用 32(或 24)位浮点数进行插值(而且永远不会更少)。但显然,在您的情况下,32 位浮点数是不够的,所以镶嵌是唯一的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-24
  • 2021-09-18
  • 1970-01-01
  • 2013-03-05
相关资源
最近更新 更多