考虑下面的简单着色器(前往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()
不会。
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);
}