[百练shader] 极坐标简单示例
您们的点赞、评论是我不断向前的动力
更多基础里内容参考往期文章 [百练shader] 常见基础方法效果 - 掘金 (juejin.cn)
一、简介 极坐标是一种常见的技术,通常用于实现一些特定的图形效果,如在笛卡尔坐标系中,一个点的位置通常用(x, y)表示,其中x表示点到原点的水平距离,y表示点到原点的垂直距离。而在极坐标系中,一个点的位置用(r, θ)表示,其中:
- r是点到原点的距离,也称为极径或半径。
- θ是点到x轴的角度,也称为极角。
在极坐标系中,点的位置可以通过极径和极角来精确描述,而不需要使用直角坐标系中的x和y坐标。这种描述方式特别适合于描述圆形、环形或径向对称、径向模糊、环形渐变等图案和效果
二、在着色器中使用极坐标
void main(){
vec2 uv=gl_FragCoord.xy/u_resolution.xy;
// uv.x*=u_resolution.x/u_resolution.y;
uv-=.5;
float r = length(uv); // 极径
float a = atan(uv.x,uv.y); // 极角
vec2 puv=vec2(a,r); // 转换为极坐标 puv.x 范围是 -pi ~ pi
puv=vec2(puv.x/6.2831+.5,puv.y); // puv.x 范围是 0 ~ 1
vec3 color=vec3(puv.x);
gl_FragColor=vec4(color,1.);
}
利用极径绘制圆环
void main(){
vec2 uv=gl_FragCoord.xy/u_resolution.xy;
// uv.x*=u_resolution.x/u_resolution.y;
uv-=.5;
float r = length(uv); // 极径
float a = atan(uv.x,uv.y); // 极角
vec2 puv=vec2(a,r); // 转换为极坐标 puv.x 范围是 -pi ~ pi
puv=vec2(puv.x/6.2831+.5,puv.y); // puv.x 范围是 0 ~ 1
vec3 color=vec3(.0);
if(puv.y > .1 && puv.y < .12){
color=vec3(1.,.0,.0);
}
if(puv.y > .31 && puv.y < .32){
color=vec3(1.,.0,.0);
}
if(puv.y > .5 && puv.y < .51){
color=vec3(1.,.0,.0);
}
gl_FragColor=vec4(color,1.);
}
利用极角绘制图形和旋转
void main(){
vec2 uv=gl_FragCoord.xy/u_resolution.xy;
// uv.x*=u_resolution.x/u_resolution.y;
uv-=.5;
float r = length(uv); // 极径
float a = atan(uv.x,uv.y); // 极角
// a += u_time; // 旋转
vec2 puv=vec2(a,r); // 转换为极坐标 puv.x 范围是 -pi ~ pi
puv=vec2(puv.x/6.2831+.5,puv.y); // puv.x 范围是 0 ~ 1
vec3 color=vec3(.0);
color = step(mod(puv.x,.2),0.1)*vec3(0.08, 0.93, 0.11);
gl_FragColor=vec4(color,1.);
}
通过极径 制作径向缩放效果
#ifdef GL_ES
precision mediump float;
#endif
// 调整极径创建径向缩放效果
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
uniform sampler2D u_texture_1;
void main(){
vec2 uv=gl_FragCoord.xy/u_resolution.xy;
// uv.x*=u_resolution.x/u_resolution.y;
uv-=.5;
float r = length(uv); // 极径
float a = atan(uv.x,uv.y); // 极角
vec2 puv=vec2(a,r); // puv 的 x 范围是 -pi ~ pi
puv=vec2(puv.x/6.2831+.5,puv.y); // puv 的 x 范围是 0 ~ 1
float scaledRadius = r;
scaledRadius+= 0.2;
// scaledRadius+= sin(u_time); // 这里加入了时间变化以创建动画效果
// 将笛卡尔坐标转换回纹理坐标
vec2 newPosition = vec2(cos(a) * scaledRadius, sin(a) * scaledRadius);
vec2 newUV = newPosition -0.5;
vec4 texColor1 = texture2D(u_texture_1, newUV);
vec3 color=texColor1.xyz;
gl_FragColor=vec4(color,1.);
}