搓牌Shader - URP可用
Shader "Custom/RubCard" {
Properties {
   _Color ("Main Color", Color) = (1,1,1,1)//Tint Color
   _MainTex ("Base (RGB)", 2D) = "white" {}
   _MainTex_2 ("Base (RGB)", 2D) = "white" {}
   ratioY ("ratioY", Float) = 0
   radius ("radius", Float) = 0
   height ("height", Float) = 0
   anchorY ("anchorY", Float) = 0
   rubOffset ("rubOffset", Float) = 0
   maxRubAngle ("maxRubAngle", Float) = 0
   _ZOffsetOne("ZOffsetOne",Float)=0
   _ZOffsetTwo("ZOffsetTwo",Float)=0
   _Move("Move",Float)=0
}
 
SubShader {
   Tags {"Queue"="Geometry"  "RenderType"="Opaque" }
   LOD 100
   
   Pass {
      Name "ONE"
      Tags{"LightMode" = "UniversalForward"}
      Cull Front
      Lighting Off

        CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
            #include "UnityCG.cginc"
            #include "Lighting.cginc"
         
            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed4 _Color;
            float ratioY;
            float radius;
            float height;
            float anchorY;
            float rubOffset;
            float maxRubAngle;
            float _ZOffsetOne;
            float _Move;

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };
            
            v2f vert (appdata v)
            {
                v2f o;
                float4 tmp_pos = v.vertex;
                float tempAngle = 1.0;

        
                tmp_pos.xyz = mul(unity_ObjectToWorld,float4(tmp_pos.xyz,0)).xyz;
                float pi = 3.14159;
                float halfPeri = radius * pi * maxRubAngle; 
                float rubLenght = height * (ratioY - anchorY);
                tmp_pos.y += height*rubOffset;
                float tempPosY = tmp_pos.y;
                if(tmp_pos.y < rubLenght)
                {
                        float dy = (rubLenght - tmp_pos.y);
                    if(rubLenght - halfPeri < tmp_pos.y)
                    {
                        float angle = dy/radius;
                        tmp_pos.y = rubLenght -  sin(angle)*radius;
                        tmp_pos.z = radius * (1.0- cos(angle)); 
                    }
                    else
                    {
                        float tempY = rubLenght  - halfPeri - tmp_pos.y;
                        float tempAngle = pi * (1.0-maxRubAngle);
                        tmp_pos.y = rubLenght - radius*sin(tempAngle) + tempY * cos(tempAngle);
                        tmp_pos.z = radius + radius*cos(tempAngle) + tempY * sin(tempAngle);

                    }

                }
                tmp_pos.x += unity_ObjectToWorld[3][0];
                tmp_pos.y += unity_ObjectToWorld[3][1];
                tmp_pos.z += unity_ObjectToWorld[3][2];

                
                float4 pos = mul(UNITY_MATRIX_VP, tmp_pos);


                float tempOffset = _ZOffsetOne * pos.w;
                if (tempPosY < rubLenght )
                {
                    float dy = (rubLenght - tempPosY);
                    if( dy > pi * radius)
                    {
                        tempOffset = -tempOffset*2.0;
                    }
                }

                pos.z = pos.z + tempOffset;
                pos.x += _Move;

                o.vertex = pos;
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.uv.x = 1 - o.uv.x;//对uv的x取反
                return o;
            }
            
            fixed4 frag (v2f i) : SV_Target
            {

                fixed4 col = tex2D(_MainTex, i.uv);
                clip (col.a - 0.5);
                return col * _Color;
            }
            ENDCG
   }

     Pass
        {
            Name "TWO"
          Cull Back
          Lighting Off

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
            #include "UnityCG.cginc"
            #include "Lighting.cginc"

         

            sampler2D _MainTex_2;
            float4 _MainTex_2_ST;
            fixed4 _Color;
            float ratioY;
            float radius;
            float height;
            float anchorY;
            float rubOffset;
            float maxRubAngle;
            float _ZOffsetTwo;
            float _Move;

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };
            
            v2f vert (appdata v)
            {
                v2f o;
                float4 tmp_pos = v.vertex;
                float tempAngle = 1.0;

        
                tmp_pos.xyz = mul(unity_ObjectToWorld,float4(tmp_pos.xyz,0)).xyz;
                //tmp_pos.xyz = (modelMatrix * vec4(tmp_pos.xyz, 0.0)).xyz;
                float pi = 3.14159;
                float halfPeri = radius * pi * maxRubAngle; 
                float rubLenght = height * (ratioY - anchorY);
                tmp_pos.y += height*rubOffset;
                float tempPosY = tmp_pos.y;
                if(tmp_pos.y < rubLenght)
                {
                        float dy = (rubLenght - tmp_pos.y);
                    if(rubLenght - halfPeri < tmp_pos.y)
                    {
                        float angle = dy/radius;
                        tmp_pos.y = rubLenght -  sin(angle)*radius;
                        tmp_pos.z = radius * (1.0- cos(angle)); 
                    }
                    else
                    {
                        float tempY = rubLenght  - halfPeri - tmp_pos.y;
                        float tempAngle = pi * (1.0-maxRubAngle);
                        tmp_pos.y = rubLenght - radius*sin(tempAngle) + tempY * cos(tempAngle);
                        tmp_pos.z = radius + radius*cos(tempAngle) + tempY * sin(tempAngle);

                    }

                }
                tmp_pos.x += unity_ObjectToWorld[3][0];
                tmp_pos.y += unity_ObjectToWorld[3][1];
                tmp_pos.z += unity_ObjectToWorld[3][2];

                
                float4 pos = mul(UNITY_MATRIX_VP, tmp_pos);


                float tempOffset = _ZOffsetTwo * pos.w;
                if (tempPosY < rubLenght )
                {
                    float dy = (rubLenght - tempPosY);
                    if( dy > pi* radius)
                    {
                        tempOffset = -tempOffset * 2.0;
                    }
                }
                pos.z = pos.z + tempOffset;
                pos.x += _Move;

                o.vertex = pos;
                o.uv = TRANSFORM_TEX(v.uv, _MainTex_2);
                o.uv.x = 1 - o.uv.x;//对uv的x取反
                o.uv.y = 1 - o.uv.y;//对uv的y取反
                return o;
            }
            
            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex_2, i.uv);
                clip (col.a - 0.5);
                return col * _Color;
            }
            ENDCG
        }

    
}
}


注意:URP要渲染多通道的shader,需要确保有个pass打上UniversalForward的tag,其余pass有SRPDefaultUnlit的tag也行,没有也行

shader将模型坐标转换为世界坐标,所以普通的移动不会影响位置,需要调节shader的参数做偏移,调节参数把牌摆好,设置好角度和相机角度。


首页 我的博客
粤ICP备17103704号