【百练shader】极坐标简单示例

223 阅读2分钟

[百练shader] 极坐标简单示例

Image.png

您们的点赞、评论是我不断向前的动力

更多基础里内容参考往期文章 [百练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.);
}
希望这个示例能帮助你理解在着色器中使用极坐标的原理和实现方式。