光线行进时的 GLSL 伪影

Posted

技术标签:

【中文标题】光线行进时的 GLSL 伪影【英文标题】:GLSL artefacts when ray marching 【发布时间】:2021-11-15 14:35:00 【问题描述】:

在下面的shadertoy中,我展示了一个在raymarching时出现的伪影

https://www.shadertoy.com/view/stdGDl

这是我的“场景”(见下面的代码片段)。它渲染一个原始的“tunnel_fragment”,它是一个 SDF(有符号距离函数),并使用坐标上的模来计算这些片段的“无限”重复。然后它还会计算我们所在的磁盘(奇数/偶数)来替换它们。

我真的不明白为什么在 x 方向的交替移动变大时磁盘(或环 -> 参见 tunnel_fragment,如果您删除评论它们变成环而不是磁盘)呈现这些伪影时会出现这些伪影。

当磁盘结构整体向右移动时不会出现这些伪影,仅当磁盘交替并且整个结构变得更加复杂时才会出现。

我做错了什么?真让我吃惊。

vec2 scene(in vec3 p)

    float thick = 0.1;
    vec3 cp = p;

    // Use modulo to simulate inf disks
    vec3 c = vec3(0,0,6.0*thick);
    vec3 q = mod(cp+0.5*c,c)-0.5*c;
    
    // Find index of the disk
    vec3 disk = (cp+0.5*c) / (c);
    float idx = floor(disk.z);
    
    // Do something simple with odd/even disks
    // Note: changing this shows the artefacts are always there
    if(mod(idx,2.0) == 0.0) 
        q.x += sin(disk.z*t)*t*t;
     else 
        q.x -= sin(disk.z*t)*t*t;
    

    float d = tunnel_fragment(q, vec3(0.0), vec3(0.0, 0.0, 1.0), 2.0, thick, 0.2);
    return vec2(d, idx);

【问题讨论】:

【参考方案1】:

下图说明了问题:

当当前磁盘的偏移量(基于模数)大于磁盘之间的间距时,您计算的距离大于到下一个磁盘的距离。因此,您可能会超过下一个磁盘。

要解决这个问题,您需要限制偏移量(如前所述——不超过磁盘之间的间距),或者分别对奇数/偶数磁盘进行采样,并在它们之间使用min()

【讨论】:

我应该明白这一点,感谢您展示了启蒙之路。

以上是关于光线行进时的 GLSL 伪影的主要内容,如果未能解决你的问题,请参考以下文章

GLSL:如何使用投影矩阵计算光线方向?

GLSL 像素化着色器中的边框伪影

使用 pow() 时的 GLSL 问题

超过一个字符指针时的GLSL编译错误(glShaderSource)

GLSL PBS 实现,奇怪的着色器行为

运行时的 glsl 着色器编译问题