2

考虑下面的简单着色器(前往shadertoy.com/new并粘贴代码进行试用)。

基本上,我试图弄清楚是否可以调整dot()版本以获得这两个函数调用完全相同的结果:

smoothstep( 0.0, r * r, dot(d, d) )
smoothstep( 0.0, r,     length(d) )

使用两种众所周知的方法绘制两个圆。看了网上的教程,了解到可以用length()函数画圆。您还了解到它非常昂贵,因此提供了一个更优化的版本,dot()而不是使用该函数。(在我的世界里,某事物的优化版本应该产生相同的结果。)

伟大的。但我找不到两者之间的关系的解释。有时,由于dot()某种原因,结果乘以4.0(参见着色器之书),得到相似但不相同的输出。

如您所见,会step()产生相同的圆圈,而smoothstep()不会。

典型的 GLSL 圈子:)

smoothstep()是否有可能通过使用一些数学来获得完全相同的输出?

着色器示例

float circle_using_length(vec2 position, float radius) {
    vec2 d = position - vec2(0.5);
    return 1.0 - step(radius, length(d));
}

float circle_using_dot(in vec2 position, in float radius) {
    vec2 d = position - vec2(0.5);
    return 1.0 - step(radius * radius, dot(d, d));
}

float smooth_circle_using_length(vec2 position, float radius) {
    vec2 d = position - vec2(0.5);
    return 1.0 - smoothstep(0.0, radius, length(d));
}

float smooth_circle_using_dot(in vec2 position, in float radius) {
    vec2 d = position - vec2(0.5);
    return 1.0 - smoothstep(0.0, radius * radius, dot(d, d) /* magic needed here */);
}

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = fragCoord/iResolution.x;
    
    vec3 col = vec3(0.0);
    col += circle_using_length(uv + vec2(0.4, 0.05), 0.05);
    col += smooth_circle_using_length(uv + vec2(0.4, 0.2), 0.1);
    
    col += circle_using_dot(uv + vec2(0.2, 0.05), 0.05);
    col += smooth_circle_using_dot(uv + vec2(0.2, 0.2), 0.1);
    
    fragColor = vec4(col,1.0);
}
4

2 回答 2

3
smoothstep(0.0, radius, length(d));

返回与

smoothstep(0.0, radius, sqrt(dot(d, d)));

然而并不相等

smoothstep(0.0, radius * radius, dot(d, d));

也就是说,因为 smoothstep 不是线性函数,因此smoothstep(0, a, b)不等于smoothstep(0, a*a, b*b)

smoothstep

t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
return t * t * (3.0 - 2.0 * t);

(a*a - 0) / (b*b - 0)不相等(a - 0) / (b - 0)

于 2021-12-31T08:28:59.507 回答
1

它们是不同的,因为 x 2关于 x 不是线性的。

假设这x是圆的半径。(x/2) 在圆的中间。嗯,(x/2) 2是(x 2 )/4。这意味着当距离是从中心到边缘的一半时,dot(d, d)版本只会像从中心到边缘的四分之一一样。

dot仅当您尝试测试点是否在圆内而不是圆内的位置时,使用距离的平方(您得到的)才有效。

于 2021-12-31T00:04:49.470 回答