我尝试创建一个有圆弧旋转的着色器,你可以在这里看到一个例子:
https://www.shadertoy.com/view/MljGDK
#define center vec2(0.5)
#define pi 3.1415926535897932384626433832795
#define resolution 250.0
#define arcColor vec4(0.1, 0.2, 0.9, 1.0)
vec4 arc(vec2 uv, vec2 pos, float radius, float angle, vec4 color) {
vec2 b = (pos * resolution - uv * resolution);
float d = 1.0 - clamp(length(b) - radius * resolution, 0.0, 1.0);
float a1 = atan(-b.x, -b.y);
float a2 = atan(b.x, b.y);
//return color * smoothstep(0.0, d, angle - a);
return color * (a2 >= radians(angle) - pi / 8.0 && a2 <= radians(angle) + pi / 8.0 ? d : 0.0);
}
vec4 circle(vec2 uv, vec2 pos, float radius, vec4 color) {
float d = length(pos * resolution - uv * resolution) - radius * resolution;
float t = clamp(d, 0.0, 1.0);
return color * (1.0 - t);
}
void mainImage ( out vec4 fragColor, in vec2 fragCoord ) {
vec2 uv = fragCoord.xy / iResolution.xy;
vec4 arcSection = arc(uv, center, 0.5, mod(iGlobalTime*100.0, 360.0), arcColor);
vec4 hole = circle(uv, center, 0.45, vec4(1.0));
fragColor = arcSection - hole;
}
然而,我不知道为什么atan会返回切断圆极处弧线的值。我的印象是glsl中的atan(x,y)实现为atan2。
非常感谢任何改进圆弧旋转或使算法更清洁的帮助。
答案 0 :(得分:1)
您的问题是未能允许结果的循环性质。在摘要中:距角度359.0的角度有多远?根据你的代码,它距离359度而不是1度。
建议的替代方案:
float a2Diff = mod(radians(angle) - a2, pi * 2.0);
return color * ((a2Diff >= pi * 15.0 / 8.0 || a2Diff <= pi / 8.0) ? d : 0.0);
因此,您需要计算两个角度之间的差异,创建一个固定的中心,然后使用mod
进行潜在的回绕。
答案 1 :(得分:1)
你需要小心环绕,以便将接近2 * pi的角度视为接近于0.这是一个有效的代码示例:
#define center vec2(0.5, 0.5)
#define pi 3.1415926535897932384626433832795
#define resolution 250.0
#define arcColor vec4(0.1, 0.2, 0.9, 1.0)
vec4 arc(vec2 uv, vec2 pos, float radius1, float radius2, float angle, vec4 color) {
vec2 b = (pos * resolution - uv * resolution);
float angdist = mod(atan(b.x, b.y) - angle, 2.0*pi);
return color * ((angdist < pi/8.0)
&& (length(b) >= radius1 * resolution)
&& (length(b) <= radius2 * resolution) ? 1.0 : 0.0);
}
void mainImage ( out vec4 fragColor, in vec2 fragCoord ) {
vec2 uv = fragCoord.xy / iResolution.xy;
vec4 arcSection = arc(uv, center, 0.45, 0.5, radians(mod(iGlobalTime*100.0, 360.0)), arcColor);
fragColor = arcSection;
}