【问题标题】:Why am I getting these jagged edges in my shader?为什么我的着色器中出现这些锯齿状边缘?
【发布时间】:2019-05-28 08:58:42
【问题描述】:

我写了一个简单的shadertoy example 的光线平面相交。我在飞机上使用棋盘格图案,我注意到奇怪的伪影。我知道这缺乏抗锯齿,所以我完全期待锯齿线。但是,沿边缘的随机像素似乎是不正确的。我尽力在 Blender 中使用 Cycles 渲染器重新创建相同的东西,每像素 1 个样本,它产生的结果更接近我的预期。谁能解释一下?

float intersect(in vec3 ro, in vec3 rd)
{
    return -ro.y / rd.y;
}

void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
    vec2 uv = ((fragCoord + vec2(0.5)) / iResolution.xy * 2.0 - 1.0) * vec2(16.0 / 9.0, 1.0);
    vec3 ro = vec3(0.0, 1.0, 0.0);
    vec3 rd = normalize(vec3(uv, 2.0));

    float t = intersect(ro, rd);

    vec3 col = vec3(0.0, 0.0, 0.0);

    if (t >= 0.0)
    { 
        vec3 pos = ro + t * rd;
        vec2 tex = floor(pos.xz);
        col = vec3(mod(tex.x + tex.y, 2.0));
    }

    fragColor = vec4(col, 1.0);
}

【问题讨论】:

  • 可能是浮动舍入错误问题,如果工件消失或减少情况,请务必尝试使用doubledvec 而不是floatvec。在这种情况下,您必须保持精度,因此数学运算的顺序很重要……另请参阅 ray and ellipsoid intersection accuracy improvement 了解更多想法。
  • 一些可能正确也可能不正确的疯狂猜测:使用网格重现 Cycles 中的场景可能是其出色结果的解释。如果两个相邻 BVH 节点中的多边形共享一条射线命中的边(在数值误差范围内),则遍历算法将总是选择最接近射线源的节点,从而产生“一致fill rule" 即使只有 1 spp。
  • 更新:结果证明使用与上述类似的方法(如果光线击中边缘,总是对最近的瓦片进行采样)效果很好。本来打算发布答案,但我找不到任何破坏 Alex 的软糖因素补救措施的案例......想知道你的想法是什么。
  • 在这里很难看到任何错误或意外行为,我敢肯定,如果您用笔和纸对每个像素进行数学运算,您将获得与着色器结果相同的输出。 shadertoy.com/view/wtBGDD bleder osl 着色器。是的,无需 iResolution 计算,您的代码就可以正常工作pasteall.org/blend/index.php?id=51880
  • @nabr Alex 是正确的,问题是由于浮点舍入错误造成的。如果你手工计算,你不会得到相同的结果。最大误差似乎约为~1e-5。在这一点上,我只是在研究解决这个问题的最佳方法。

标签: 3d floating-point glsl shader raytracing


【解决方案1】:

如果网格线直接落在采样点上,则浮点误差将决定为该像素选择哪个网格正方形。 Cycles 使用随机采样点,而您使用整数 (fragCoord + vec2(0.5))。将您的采样点更改为 fragCoord + vec2(0.001234, 0.004321) 会删除工件。

【讨论】:

  • 不幸的是,我不能将这个作为答案。将着色器代码转换为 C++ 会产生与 32 位和 64 位浮点数相似的结果。 GLSL 实现中缺乏精度不是问题。其次,没有解释为什么将随机常数(如 16.0 到 16.0001)捏造出来以解决问题是“正确的”。
  • @Chris_F 我改变了答案。
  • 如果 Cycles 使用随机样本点,那么图像会很嘈杂,但事实并非如此。我修改了我的着色器以使用 [0, 1) 之间的随机采样点,因为我怀疑情况更糟,而不是更好。关于 0.001234 和 0.004321 没有什么随机的,除了它们可能是你随机选择的。
  • @Chris_F docs.blender.org/manual/en/dev/render/cycles/settings/scene/… 表示循环使用随机采样模式。我认为它对于每个像素都是恒定的(随机模式选择一次,然后用于所有像素)或至少仅用于一个示例案例。
  • 所以我用 Blender 做了一些经验测试,因为我不希望在文档中找到任何有用的信息。我的测试是在 SPP 设置为 1 并使用两个不同的种子值(因为不同的种子会产生不同的随机值)的情况下两次渲染场景。结果是两个图像都是 100% 相同的。然后我将 SPP 设置为 2 重复测试,结果是不同的图像。显然,对于 Cycles 1,SPP 是一种特殊情况,样本点没有随机化。或者也许只是第一个样本永远不是随机的。
猜你喜欢
  • 2019-11-27
  • 1970-01-01
  • 1970-01-01
  • 2016-10-30
  • 1970-01-01
  • 1970-01-01
  • 2010-09-14
  • 2019-04-30
  • 2019-07-22
相关资源
最近更新 更多