光线行进时的 GLSL 人工制品
GLSL artefacts when ray marching
在下面的 shadertoy 中,我说明了光线行进时出现的人工制品
https://www.shadertoy.com/view/stdGDl
这是我的“场景”(见下面的代码片段)。它呈现一个原始的“tunnel_fragment”,它是一个 SDF(有符号距离函数),并在坐标上使用模数来计算这些片段的“无限”重复。然后它还会计算我们在哪个磁盘 (odd/even) 中以取代它们。
我真的不明白为什么当圆盘(或环 -> 参见 tunnel_fragment,如果你删除评论它们变成圆环而不是圆盘)在交替运动时出现这些假象时会出现这些假象x方向变大
当磁盘结构整体向右移动时,这些伪像不会出现,只有当磁盘交替并且整个结构变得更加复杂时才会出现。
我做错了什么?真让我费解。
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);
}
下图说明了问题:
当当前磁盘(基于模数)偏移大于磁盘之间的间距时,则您计算的距离大于到下一个磁盘的距离。因此,您可能会踩到下一个磁盘。
要解决这个问题,您需要限制偏移量(如前所述——不超过磁盘之间的间距),或者分别对 odd/even 个磁盘进行采样,并在它们之间 min()
。
在下面的 shadertoy 中,我说明了光线行进时出现的人工制品
https://www.shadertoy.com/view/stdGDl
这是我的“场景”(见下面的代码片段)。它呈现一个原始的“tunnel_fragment”,它是一个 SDF(有符号距离函数),并在坐标上使用模数来计算这些片段的“无限”重复。然后它还会计算我们在哪个磁盘 (odd/even) 中以取代它们。
我真的不明白为什么当圆盘(或环 -> 参见 tunnel_fragment,如果你删除评论它们变成圆环而不是圆盘)在交替运动时出现这些假象时会出现这些假象x方向变大
当磁盘结构整体向右移动时,这些伪像不会出现,只有当磁盘交替并且整个结构变得更加复杂时才会出现。
我做错了什么?真让我费解。
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);
}
下图说明了问题:
当当前磁盘(基于模数)偏移大于磁盘之间的间距时,则您计算的距离大于到下一个磁盘的距离。因此,您可能会踩到下一个磁盘。
要解决这个问题,您需要限制偏移量(如前所述——不超过磁盘之间的间距),或者分别对 odd/even 个磁盘进行采样,并在它们之间 min()
。