2013年9月6日 星期五

[Unity] Scroll and Turbulence Shader (流動加擾動效果)

這是我的第二個Fragment Shader,在此作紀錄供參考。
參考文章


此Shader的表現效果:


Inputs
MainTex為一張transparent texture,OffsetTex則是一張noise texture,Shader會以OffsetTex擾動MainTex,擾動的程度由Distortion控制,速度則由TurbulenceSpd控制。另外MainTex本身也會做流動,流動速度由ScrollSpd控制。
Inputs
Fragment Shader (without normals)

 Properties 
 {
  _MainTex("_MainTex", 2D) = "black" {}
  _OffsetTex("_Offset", 2D) = "black" {}
  _Distortion("_Distortion", Float ) = 0.1
  _TurbulenceSpd("_TurbulenceSpd", Float) = -50  
  _ScrollSpd("_ScrollSpd", Float) = 30
 }
 
 SubShader 
 {
  Tags
  {
   "Queue"="Transparent"
   "IgnoreProjector"="True"
   "RenderType"="Transparent"
  }
  
  Cull Off
  ZWrite Off
  Blend SrcAlpha OneMinusSrcAlpha

  Pass {
   CGPROGRAM
   #pragma vertex vert
   #pragma fragment frag
   #include "UnityCG.cginc"
   
   struct appdata {
    fixed4 vertex : POSITION;
    fixed2 texcoord : TEXCOORD0;
   };
   
   struct v2f {
    fixed4 pos : SV_POSITION;
    fixed2 uv : TEXCOORD0;
    fixed2 uv2 : TEXCOORD1;
   };
   
   fixed4 _MainTex_ST;
   fixed4 _OffsetTex_ST;
   fixed _Distortion;
   fixed _TurbulenceSpd;
   fixed _ScrollSpd;
   
   v2f vert (appdata_base v) {
    v2f o;
    
    o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    
    // Offset _MainTex uv
    fixed mainTexOffset = _Time * _ScrollSpd;
    //o.uv.x = v.texcoord.x * _MainTex_ST.x + _MainTex_ST.z;
    //o.uv.y = v.texcoord.y * _MainTex_ST.y + _MainTex_ST.w + mainTexOffset;
    o.uv.x = v.texcoord.x;
    o.uv.y = v.texcoord.y + mainTexOffset;
    
    // Offset _OffsetTex uv
    fixed offsetTexOffset = _Time * _TurbulenceSpd;
    //o.uv2.x = v.texcoord.x * _OffsetTex_ST.x + _OffsetTex_ST.z + offsetTexOffset;
    //o.uv2.y = v.texcoord.y * _OffsetTex_ST.y + _OffsetTex_ST.w;
    o.uv2.x = v.texcoord.x + offsetTexOffset;
    o.uv2.y = v.texcoord.y;
    
    return o;
   }
   
   sampler2D _MainTex;
   sampler2D _OffsetTex;
   
   fixed4 frag(v2f i) : COLOR {
    // convert OffsetTex's color to luminance to distort MainTex's uv
    fixed4 offsetTexColor = tex2D(_OffsetTex, i.uv2);
    fixed lum = Luminance(offsetTexColor);
    fixed2 texCord = ( lum, lum );
    
    fixed4 mainTexColor = tex2D( _MainTex, i.uv + texCord * _Distortion );
    
    return mainTexColor;
   }
   
   ENDCG
  }
 }

  • tex2D返回的是color值(r, g, b, a)


Surface Shader ( Need Normals)

  CGPROGRAM
  #pragma surface surf NoLighting 
  #pragma target 2.0
  
  sampler2D _MainTex;
  sampler2D _OffsetTex;
  float _Distortion;
  float _Speed;
  float _MoveSpeed;

  struct EditorSurfaceOutput {
   half3 Albedo;
   half3 Normal;
   half3 Emission;
   half3 Gloss;
   half Specular;
   half Alpha;
  };
  
  fixed4 LightingNoLighting(EditorSurfaceOutput s, fixed3 lightDir, fixed atten)
     {
         fixed4 c;
         c.rgb = s.Albedo; 
         c.a = s.Alpha;
         return c;
     }
   
  struct Input {
   float2 uv_MainTex;
   float2 uv_OffsetTex;
  };

  void surf (Input IN, inout EditorSurfaceOutput o) {
   
   // pan OffsetTex
   fixed time = _Time * _Speed;
   fixed2 UV_PanY = fixed2( IN.uv_OffsetTex.x + time, IN.uv_OffsetTex.y );
   
   // pan MainTex
   fixed moveTime = _Time * _MoveSpeed;
   fixed2 UV_PanMove = fixed2( IN.uv_OffsetTex.x, IN.uv_OffsetTex.y + moveTime );
   
   fixed2 OffsetTex2D = tex2D( _OffsetTex, UV_PanY.xy );
   fixed2 distorted = OffsetTex2D * _Distortion;
   fixed2 Add1 = UV_PanMove + distorted;
   
   fixed4 MainTex2D = tex2D( _MainTex, Add1.xy );
   
   o.Albedo = MainTex2D;
   o.Alpha = MainTex2D.a;
  }
  ENDCG

沒有留言:

張貼留言