# 【极坐标UV】

Polarcoordinates.shader

Shader "Tests/Polarcoordinates"
{
    Properties
    {
        _MainTex ("主贴图", 2D) = "white" {}
    }
    SubShader {
        Tags {
            "RenderType"="Opaque"
        }
        Pass {
            Name "FORWARD"
            Tags {
                "LightMode"="ForwardBase"
            }
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #pragma multi_compile_fwdbase_fullshadows
            #pragma target 3.0

            uniform sampler2D _MainTex;

            struct VertexInput {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };
            struct VertexOutput {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
            };
            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;
                o.pos = UnityObjectToClipPos( v.vertex );
                o.uv = v.uv;
                return o;
            }
            float4 frag(VertexOutput i) : COLOR
            {
                // 极坐标的核心代码
                float pi = 3.1415926;
                float2 uv2 = (i.uv*pi*2-pi).rg;
                // 0.1591596 这个值的来由  -3.14159 ~ 3.14159 先转换成 -1~1  值 * (1/3.14159) 再 转换成 0~1 需要 * 0.5 + 0.5
                float uv_y = atan2(uv2.g,uv2.r)*0.1591596+0.5; // atan2 后的值是 -3.14159 ~ 3.14159 之间,映射成0~1之间的值需要 *0.1591596+0.5    1/3.1415926 *0.5 + 0.5
                float uv_x = 1-distance(i.uv,float2(0.5,0.5));
                //return float4(uv_x,uv_y,0,1);
                float4 var_MainTex = tex2D(_MainTex,float2(uv_y,uv_x));
                return var_MainTex;
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

测试使用纹理

Markdown 图片

计算出来的极坐标uv是这样的

Markdown 图片

最终的效果是这样的

Markdown 图片

假如需要对极坐标加上旋转功能,则可以这样

Shader "Tests/Polarcoordinates"
{
    Properties
    {
        _MainTex ("主贴图", 2D) = "white" {}
    }
    SubShader {
        Tags {
            "RenderType"="Opaque"
        }
        Pass {
            Name "FORWARD"
            Tags {
                "LightMode"="ForwardBase"
            }
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #pragma multi_compile_fwdbase_fullshadows
            #pragma target 3.0


            uniform sampler2D _MainTex;


            struct VertexInput {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };
            struct VertexOutput {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
            };
            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;
                o.pos = UnityObjectToClipPos( v.vertex );
                o.uv = v.uv;
                return o;
            }
            float4 frag(VertexOutput i) : COLOR
            {
                float pi = 3.1415926;


                // 对极坐标uv进行一个随时间进行旋转
                // 0~1 之间的值循环 * pi*2 - pi 可以映射成 -3.14~3.14
                float ang = frac(_Time.y*0.2) * pi*2 - pi;
                float2 piv = float2(0.5,0.5);// 中心点
                float co = cos(ang);
                float si = sin(ang);
                float2 polarUV_rotation = (mul(i.uv-piv,float2x2( co, -si, si, co))+piv);


                // 极坐标的核心代码
                float2 uv2 = (polarUV_rotation*pi*2-pi).rg;
                // 0.1591596 这个值的来由  -3.14159 ~ 3.14159 先转换成 -1~1  值 * (1/3.14159) 再 转换成 0~1 需要 * 0.5 + 0.5
                float uv_y = atan2(uv2.g,uv2.r)*0.1591596+0.5; // atan2 后的值是 -3.14159 ~ 3.14159 之间,映射成0~1之间的值需要 *0.1591596+0.5    1/3.1415926 *0.5 + 0.5
                float uv_x = 1-distance(polarUV_rotation,float2(0.5,0.5));


                float2 polarUV = float2(uv_y,uv_x);
                float4 var_MainTex = tex2D(_MainTex,polarUV);
                return var_MainTex;
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

【Shader练习-恶魔猎手】