Vertex and fragment shader 3 - 2D過場淡入淡出(Fade in/out) - 方塊陣列(方形縮放)

  這次是方塊陣列的切除,並且使用材質貼圖,切除的方式是方形的縮放。

呈現的效果大概是這樣





同樣設定基本屬性,材質、顏色
_MainTex ("Base (RGB)", 2D) = "white" {}
_Color ("Color", Color) = (1,1,1,1)

接著設定切分的數量(分別為X跟Y軸,因為這只有2D顯示這樣就夠了)
_DensityX ("Density X", Float) = 15.0
_DensityY ("Density Y", Float) = 15.0 

最後是切除的量
_Amount ("Amount", Range (0,1)) = 0


從X軸來看,在輸出的時候先切分需要的等分,接著只要X座標的值減去 _Amount 的值,如果小於0就不顯示,以及X座標的鏡像位置減去 _Amount 也小於0就不顯示。然後Y軸也使用相同的方法,最後再加成上自訂的顏色遮罩即可。
float4 color = tex2D(_MainTex, input.uv);
if (frac(input.screenPos.x * _DensityX) - _Amount < 0 || frac(1-input.screenPos.x * _DensityX) - _Amount < 0)
    discard;
if (frac(input.screenPos.y * _DensityY) - _Amount < 0 || frac(1-input.screenPos.y * _DensityY) - _Amount < 0)
    discard;
return color * _Color;


  最後在Unity當中使用的時候,調整 _Amount 調整切除的量,調整 _DensityX 跟 _DensityY 來決定陣列的切分數量,然後調整 _Color 給材質加成顏色。


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


完整Shader Code
Shader "Custom/Fading" 
{
   Properties
   {
      _MainTex ("Base (RGB)", 2D) = "white" {}
      _Color ("Color", Color) = (1,1,1,1)
      _DensityX ("Density X", Float) = 15.0
      _DensityY ("Density Y", Float) = 15.0
      _Amount ("Amount", 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 float4 _Color;
         uniform float _DensityX;
         uniform float _DensityY;
         uniform float _Amount;

         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 color = tex2D(_MainTex, input.uv);
            if (frac(input.screenPos.x * _DensityX) - _Amount < 0 || frac(1-input.screenPos.x * _DensityX) - _Amount < 0)
                discard;
            if (frac(input.screenPos.y * _DensityY) - _Amount < 0 || frac(1-input.screenPos.y * _DensityY) - _Amount < 0)
                discard;
            return color * _Color;
         }
         ENDCG
      }
   }
   Fallback "Diffuse"
} 

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

3 comments:

Kin said...

想請問一下這個Shader的使用方式?
是可以直接放在3D物件上嗎?
剛剛用Unity內建的Plane測試似乎沒有效果...

IVerv said...

直接放在3D物件上是可以的,不管是Plane還是其他內建物體
不知道你所說沒有效果是如何,有調整Amount值看看嗎?

Kin said...

已經成功了!!
看來應該是我個人的操作問題orz
感謝大大提供這麼棒的Shader!

Post a Comment