【发布时间】: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);
}
【问题讨论】:
-
可能是浮动舍入错误问题,如果工件消失或减少情况,请务必尝试使用
double和dvec而不是float和vec。在这种情况下,您必须保持精度,因此数学运算的顺序很重要……另请参阅 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