Vertex and fragment shader 10 - 2D過場淡入淡出(Fade in/out) - 自訂圖案陣列(切除)

  覺得一般方形或圓形陣列的效果不太滿意,想要使用自己設定的花紋來做為切除的圖案,因此就使用第二個材質來做為花紋,並且只使用它的Alpha值來做為切除的依據,就簡單地可以達到這樣的需求。

呈現的效果大概是這樣



這次使用的星星花紋圖,不過這個圖案的Alpha沒有很好,姑且使用。

  注意,花紋圖案在Unity當中匯入成Texture的時候,Wrap Mode要使用Clamp,不然就無法達到上面的效果,因為Repeat的話每個分隔就無法只切除單一個圖案了。


同樣設定基本屬性,主要材質、花紋材質、顏色、切除的量、XY的數量,這邊多一個Alpha參數用於花紋上,調整花紋的Alpha深淺,可以調整某些Alpha較淺部分不要切除。
_MainTex ("Base (RGB)", 2D) = "white" {}
_Pattern ("Pattern", 2D) = "white" {}
_Color ("Color", Color) = (1,1,1,1)
_DensityX ("Density X", Float) = 5
_DensityY ("Density Y", Float) = 5
_Amount ("Amount", Range (0,1)) = 0
_Alpha ("Alpha Cut", Range (0,1)) = 0


  在輸出的時候,概念就是讓每個原始材質切分的小方塊,其座標去比對花紋圖案的座標,如果花紋圖案座標的Alpha比設定值小,那麼原始材質的該座標就不顯示顏色,這樣就造成花紋的切割了。。
float4 textureColor = tex2D(_MainTex, input.uv);
float2 coord = input.screenPos.xy;
float2 patternCoord = frac(float2(_DensityX*coord.x,_DensityY*coord.y))*_Amount*5;
float4 patternColor = tex2D(_Pattern, patternCoord-0.5*(_Amount*5-1));

float4 color = textureColor;
if (patternColor.a > _Alpha) {
   color = float4(textureColor.rgb, _Amount*_Amount);
} 
return color * _Color;


  最後在Unity當中使用的時候,調整 _Amount 調整切除的量,調整 _DensityX _DensityY 來決定XY軸的數量,調整 _Alpha 可以調整花紋的Alpha深淺,可以減少花紋圖片當中太淺的Alpha同樣也會切除的狀況產生。


注意,因為使用的是螢幕座標,所以會是以遊戲顯示畫面的高寬去等分。


完整Shader Code
Shader "Custom/Fading" 
{
   Properties
   {
      _MainTex ("Base (RGB)", 2D) = "white" {}
      _Pattern ("Pattern", 2D) = "white" {}
      _Color ("Color", Color) = (1,1,1,1)
      _DensityX ("Density X", Float) = 5
      _DensityY ("Density Y", Float) = 5
      _Amount ("Amount", Range (0,1)) = 0
      _Alpha ("Alpha Cut", Range (0,1)) = 0
   }

   SubShader {
      Pass {
         Cull Off
         Lighting Off
         ZWrite Off
         Blend SrcAlpha OneMinusSrcAlpha

         CGPROGRAM

         #pragma vertex vert
         #pragma fragment frag

         uniform sampler2D _MainTex;
         uniform sampler2D _Pattern;
         uniform float4 _Color;
         uniform float _DensityX;
         uniform float _DensityY;
         uniform float _Amount;
         uniform float _Alpha;

         struct vertexInput {
            float4 vertex : POSITION;
            float4 texcoord : TEXCOORD0;
         };
         struct vertexOutput {
            float4 pos : SV_POSITION;
            float2 uv : TEXCOORD0;
            float4 screenPos : TEXCOORD5;
         };

         vertexOutput vert(vertexInput input)
         {
            vertexOutput output;

            output.uv = input.texcoord;
            output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
            output.screenPos = output.pos * 0.5 + 0.5;
            return output;
         }

         half4 frag(vertexOutput input) : COLOR
         {
            float4 textureColor = tex2D(_MainTex, input.uv);
            float2 coord = input.screenPos.xy;
            float2 patternCoord = frac(float2(_DensityX*coord.x,_DensityY*coord.y))*_Amount*5;
            float4 patternColor = tex2D(_Pattern, patternCoord-0.5*(_Amount*5-1));

            float4 color = textureColor;
            if (patternColor.a > _Alpha) {
               color = float4(textureColor.rgb, _Amount*_Amount);
            } 
            return color * _Color;
         }
         ENDCG
      }
   }
   Fallback "Diffuse"
} 

如果有任何想法歡迎提出。

No comments:

Post a Comment