Vertex and fragment shader 2 - 2D過場淡入淡出(Fade in/out) - 百葉窗型(材質貼圖)

  這同樣是柵欄型的切除,不過這次使用材質貼圖來取代單純的色塊,讓在切換場景的時候不會太過呆版。


呈現的效果大概是這樣





這次新增一個材質來做為顯示
_MainTex ("Base (RGB)", 2D) = "white" {}

保留顏色的Property,讓我們可以給材質加成顏色
_Color ("Color", Color) = (1,1,1,1)

接著設定柵欄在畫面中的數量(可以看到上圖就是切成15份)
_Density ("Fence Amount", Float) = 15.0

最後是切除的量以及方向(左到右或右到左)
_Amount ("Amount", Range (0,1)) = 0
_Direction ("Direction", Range(0,1)) = 1

接著同樣要做的事情類似色塊的方法,只是這次把材質的座標顏色計算進來,在輸出的時候只要X座標的值取小數減去 _Amount 的值,如果小於0就不顯示,如果大於0就顯示自訂的顏色 _Color。
float4 color = tex2D(_MainTex, input.uv);
if(abs(int(_Direction)-frac(input.screenPos.x * _Density)) - _Amount < 0) {
    discard;
}
return color;


  最後在Unity當中使用的時候,調整 _Amount 調整切除的量,調整 _Direction 來調整切的方向,然後調整 _Color 可以給材質加成顏色


注意,同樣這邊因為是使用X座標判斷因此會是水平的切除,如果想要垂直的切除只要換成用Y座標,把input.screenPos.x改成input.screenPos.y即可,同時因為使用的是螢幕座標,所以會是以遊戲畫面的寬去等分。


完整Shader Code
Shader "Custom/Fading" 
{
   Properties
   {
      _MainTex ("Base (RGB)", 2D) = "white" {}
      _Color ("Color", Color) = (1,1,1,1)
      _Density ("Fence Amount", Float) = 15.0
      _Amount ("Amount", Range (0,1)) = 0
      _Direction ("Direction", Range(0,1)) = 1
   }

   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 _Density;
         uniform float _Amount;
         uniform float _Direction;

         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(abs(int(_Direction)-frac(input.screenPos.x * _Density)) - _Amount < 0) {
               discard;
            }
            return color;
         }
         ENDCG
      }
   }
   Fallback "Diffuse"
} 

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

No comments:

Post a Comment