Trying to change a shader to use additive blending (SOLVED).

Hi, everyone. I have a shader here that basically takes 2 sprites, and creates a cutout effect afterwards.

However, the problem is that this shader just seems to use diffuse for the moment and I want it to use additive blending instead so that it will make the player glow when it is placed over him (similar to how flame effects would).

I have attached a package below that has the shader setup in it. Any help would be appreciated. :slight_smile:

2735731–194758–overlayShader.unitypackage (456 KB)

You need to set the shader’s blend mode:

1 Like

Sending me a link to a help file that read like stereo instructions in the 80’s doesn’t really help. :stuck_out_tongue:

I actually already tried throwing in Blend SrcAlpha One which should set it to additive, but it did nothing. I was also reading up and it seems that I am supposed to put that under a pass statement, but when I put that in along with the required brackets in my code, I kept getting a parsing error for some reason.

Can you post the shader code here directly rather than as a package?

Sure. This is before I added in the pass and Blend bits that broke it:

Shader "Custom/Red Alpha Gradient FX"
{
Properties {
     _Color ("Main Color", Color) = (1,1,1,1)
     _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
     _AlphaMap ("Gradient Transparency Map", 2D) = "white" {}
        _GlowColor ("Glow Color", Color ) = ( 1.0, 1.0, 1.0, 1.0 )
        _ScrollXSpeed("X Scroll Speed", Float) = 2
        _ScrollYSpeed("Y Scroll Speed", Float) = 2
       
           
}
 
SubShader {
     Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
     LOD 200

   
 
CGPROGRAM
#pragma surface surf Lambert alpha
 
sampler2D _MainTex;
sampler2D _AlphaMap;
float4 _Color;
fixed4    _GlowColor;
fixed _ScrollXSpeed;
fixed _ScrollYSpeed;
 
struct Input {
     float2 uv_MainTex;
     float2 uv_AlphaMap;
};
 
void surf (Input IN, inout SurfaceOutput o) {

     fixed2 scrolledUV = IN.uv_AlphaMap;
     fixed xScrollValue = _ScrollXSpeed*_Time;
     fixed yScrollValue = _ScrollYSpeed*_Time;
    
     scrolledUV += fixed2(xScrollValue,yScrollValue);
    
     half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
     half4 a = tex2D(_AlphaMap,IN.uv_AlphaMap);
     c.rgb = _GlowColor;
     o.Albedo = c.rgb;
     o.Alpha = c.a * tex2D(_AlphaMap, scrolledUV).r;
    
}
ENDCG
}
 

}

Ah, yeah, that’s a surface shader, which more accurately a vertex / fragment shader generator. If you want a shader that works with lighting they’re great at abstracting away a lot of the complexity of the shader system for supporting lighting in different rendering paths. If you select the shader in the editor and click on “show generated code” you can see what the “real” shader looks like.

If you just want something that has a color (or in this case a bit of scrolling color) it’s way overkill. You really want to start with an unlit shader and build up from that.

If you just “want it to work” try replacing alpha in the #pragma surface line with alpha:premul or maybe decal:add
(That’s alpha : premul with out the spaces on either side of the colin hiding under that emoji)

1 Like

Thanks for the links. Someone else wrote this shader for me initially and I am trying to make changes to it now myself so sorry if my questions seem basic.

I tried alpha : premul (no spaces) and it did nothing. decal:add did make it additive but also totally broke the shader and turned into an additive one color square without even the scrolling gradient on it.

Ok, so after 2 days of studying CG/HLSL I easily figured it out. I just needed keepalpha on the pragma line where I define the name of the surface method and lighting type. Along with Blend SrcAlpha One directly under tags in the subshader block.

BTW, there is no overkill in using a surface shader in this case instead of a standard vertex/frag one. That’s just nonsense. Unity by default uses them in quite a few of their base shaders.

Thanks to the one person who tried to at least help me a little. I’m amazed at how people on these forums wouldn’t take 10 seconds to help fix something so simple and never seem to want to help anyone unless money is involved. It’s disgusting how low the level of comradery is here.

EDIT: for the next person who comes along and has this issue, since I’m not a selfish SOB and a person who actually likes sharing, here is the code. I hope someone else finds this to be of use. :slight_smile:

Shader "Custom/Red Alpha Gradient FX"
{
Properties {
     _Color ("Main Color", Color) = (1,1,1,1)
     _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
     _AlphaMap ("Gradient Transparency Map", 2D) = "white" {}
        _GlowColor ("Glow Color", Color ) = ( 1.0, 1.0, 1.0, 1.0 )
        _ScrollXSpeed("X Scroll Speed", Float) = 2
        _ScrollYSpeed("Y Scroll Speed", Float) = 2
    
        
}
SubShader {
     Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
     Blend SrcAlpha One              //1st change here
     LOD 200
CGPROGRAM
#pragma surface surf Lambert keepalpha             //and the only other change needed
sampler2D _MainTex;
sampler2D _AlphaMap;
float4 _Color;
fixed4    _GlowColor;
fixed _ScrollXSpeed;
fixed _ScrollYSpeed;
struct Input {
     float2 uv_MainTex;
     float2 uv_AlphaMap;
};
void surf (Input IN, inout SurfaceOutput o) {

    fixed2 scrolledUV = IN.uv_AlphaMap;
    fixed xScrollValue = _ScrollXSpeed*_Time;
    fixed yScrollValue = _ScrollYSpeed*_Time;

    scrolledUV += fixed2(xScrollValue,yScrollValue);
  
     half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
     half4 a = tex2D(_AlphaMap,IN.uv_AlphaMap);
     c.rgb = _GlowColor;
     o.Albedo = c.rgb;
     o.Alpha = c.a * tex2D(_AlphaMap, scrolledUV).r;
  
}
ENDCG
}
Fallback "Transparent/VertexLit"
}
4 Likes

Surface shaders are shader generators, which is why that shader is way overkill. Here’s what the generated shader really looks like:
Hidden because it’s a lot of code

Shader "Custom/Red Alpha Gradient FX"
{
Properties {
     _Color ("Main Color", Color) = (1,1,1,1)
     _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
     _AlphaMap ("Gradient Transparency Map", 2D) = "white" {}
        _GlowColor ("Glow Color", Color ) = ( 1.0, 1.0, 1.0, 1.0 )
        _ScrollXSpeed("X Scroll Speed", Float) = 2
        _ScrollYSpeed("Y Scroll Speed", Float) = 2

    
}
SubShader {
     Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
     Blend SrcAlpha One              //1st change here
     LOD 200

    // ------------------------------------------------------------
    // Surface shader code generated out of a CGPROGRAM block:
 

    // ---- forward rendering base pass:
    Pass {
        Name "FORWARD"
        Tags { "LightMode" = "ForwardBase" }

CGPROGRAM
// compile directives
#pragma vertex vert_surf
#pragma fragment frag_surf
#pragma multi_compile_fog
#pragma multi_compile_fwdbase
#include "HLSLSupport.cginc"
#include "UnityShaderVariables.cginc"
// Surface shader code generated based on:
// writes to per-pixel normal: no
// writes to emission: no
// writes to occlusion: no
// needs world space reflection vector: no
// needs world space normal vector: no
// needs screen space position: no
// needs world space position: no
// needs view direction: no
// needs world space view direction: no
// needs world space position for lighting: YES
// needs world space view direction for lighting: no
// needs world space view direction for lightmaps: no
// needs vertex color: no
// needs VFACE: no
// passes tangent-to-world matrix to pixel shader: no
// reads from normal: no
// 2 texcoords actually used
//   float2 _MainTex
//   float2 _AlphaMap
#define UNITY_PASS_FORWARDBASE
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"

#define INTERNAL_DATA
#define WorldReflectionVector(data,normal) data.worldRefl
#define WorldNormalVector(data,normal) normal

// Original surface shader snippet:
#line 15 ""
#ifdef DUMMY_PREPROCESSOR_TO_WORK_AROUND_HLSL_COMPILER_LINE_HANDLING
#endif

//#pragma surface surf Lambert keepalpha             //and the only other change needed
sampler2D _MainTex;
sampler2D _AlphaMap;
float4 _Color;
fixed4    _GlowColor;
fixed _ScrollXSpeed;
fixed _ScrollYSpeed;
struct Input {
     float2 uv_MainTex;
     float2 uv_AlphaMap;
};
void surf (Input IN, inout SurfaceOutput o) {
    fixed2 scrolledUV = IN.uv_AlphaMap;
    fixed xScrollValue = _ScrollXSpeed*_Time;
    fixed yScrollValue = _ScrollYSpeed*_Time;
    scrolledUV += fixed2(xScrollValue,yScrollValue);
     half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
     half4 a = tex2D(_AlphaMap,IN.uv_AlphaMap);
     c.rgb = _GlowColor;
     o.Albedo = c.rgb;
     o.Alpha = c.a * tex2D(_AlphaMap, scrolledUV).r;
}


// vertex-to-fragment interpolation data
// no lightmaps:
#ifdef LIGHTMAP_OFF
struct v2f_surf {
  float4 pos : SV_POSITION;
  float4 pack0 : TEXCOORD0; // _MainTex _AlphaMap
  half3 worldNormal : TEXCOORD1;
  float3 worldPos : TEXCOORD2;
  #if UNITY_SHOULD_SAMPLE_SH
  half3 sh : TEXCOORD3; // SH
  #endif
  SHADOW_COORDS(4)
  UNITY_FOG_COORDS(5)
  #if SHADER_TARGET >= 30
  float4 lmap : TEXCOORD6;
  #endif
  UNITY_INSTANCE_ID
};
#endif
// with lightmaps:
#ifndef LIGHTMAP_OFF
struct v2f_surf {
  float4 pos : SV_POSITION;
  float4 pack0 : TEXCOORD0; // _MainTex _AlphaMap
  half3 worldNormal : TEXCOORD1;
  float3 worldPos : TEXCOORD2;
  float4 lmap : TEXCOORD3;
  SHADOW_COORDS(4)
  UNITY_FOG_COORDS(5)
  #ifdef DIRLIGHTMAP_COMBINED
  fixed3 tSpace0 : TEXCOORD6;
  fixed3 tSpace1 : TEXCOORD7;
  fixed3 tSpace2 : TEXCOORD8;
  #endif
  UNITY_INSTANCE_ID
};
#endif
float4 _MainTex_ST;
float4 _AlphaMap_ST;

// vertex shader
v2f_surf vert_surf (appdata_full v) {
  UNITY_SETUP_INSTANCE_ID(v);
  v2f_surf o;
  UNITY_INITIALIZE_OUTPUT(v2f_surf,o);
  UNITY_TRANSFER_INSTANCE_ID(v,o);
  o.pos = UnityObjectToClipPos(v.vertex);
  o.pack0.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
  o.pack0.zw = TRANSFORM_TEX(v.texcoord, _AlphaMap);
  float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
  fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
  #if !defined(LIGHTMAP_OFF) && defined(DIRLIGHTMAP_COMBINED)
  fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
  fixed tangentSign = v.tangent.w * unity_WorldTransformParams.w;
  fixed3 worldBinormal = cross(worldNormal, worldTangent) * tangentSign;
  #endif
  #if !defined(LIGHTMAP_OFF) && defined(DIRLIGHTMAP_COMBINED)
  o.tSpace0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x);
  o.tSpace1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y);
  o.tSpace2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z);
  #endif
  o.worldPos = worldPos;
  o.worldNormal = worldNormal;
  #ifndef DYNAMICLIGHTMAP_OFF
  o.lmap.zw = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
  #endif
  #ifndef LIGHTMAP_OFF
  o.lmap.xy = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
  #endif

  // SH/ambient and vertex lights
  #ifdef LIGHTMAP_OFF
    #if UNITY_SHOULD_SAMPLE_SH
      o.sh = 0;
      // Approximated illumination from non-important point lights
      #ifdef VERTEXLIGHT_ON
        o.sh += Shade4PointLights (
          unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
          unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb,
          unity_4LightAtten0, worldPos, worldNormal);
      #endif
      o.sh = ShadeSHPerVertex (worldNormal, o.sh);
    #endif
  #endif // LIGHTMAP_OFF

  TRANSFER_SHADOW(o); // pass shadow coordinates to pixel shader
  UNITY_TRANSFER_FOG(o,o.pos); // pass fog coordinates to pixel shader
  return o;
}

// fragment shader
fixed4 frag_surf (v2f_surf IN) : SV_Target {
  UNITY_SETUP_INSTANCE_ID(IN);
  // prepare and unpack data
  Input surfIN;
  UNITY_INITIALIZE_OUTPUT(Input,surfIN);
  surfIN.uv_MainTex.x = 1.0;
  surfIN.uv_AlphaMap.x = 1.0;
  surfIN.uv_MainTex = IN.pack0.xy;
  surfIN.uv_AlphaMap = IN.pack0.zw;
  float3 worldPos = IN.worldPos;
  #ifndef USING_DIRECTIONAL_LIGHT
    fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos));
  #else
    fixed3 lightDir = _WorldSpaceLightPos0.xyz;
  #endif
  #ifdef UNITY_COMPILER_HLSL
  SurfaceOutput o = (SurfaceOutput)0;
  #else
  SurfaceOutput o;
  #endif
  o.Albedo = 0.0;
  o.Emission = 0.0;
  o.Specular = 0.0;
  o.Alpha = 0.0;
  o.Gloss = 0.0;
  fixed3 normalWorldVertex = fixed3(0,0,1);
  o.Normal = IN.worldNormal;
  normalWorldVertex = IN.worldNormal;

  // call surface function
  surf (surfIN, o);

  // compute lighting & shadowing factor
  UNITY_LIGHT_ATTENUATION(atten, IN, worldPos)
  fixed4 c = 0;

  // Setup lighting environment
  UnityGI gi;
  UNITY_INITIALIZE_OUTPUT(UnityGI, gi);
  gi.indirect.diffuse = 0;
  gi.indirect.specular = 0;
  #if !defined(LIGHTMAP_ON)
      gi.light.color = _LightColor0.rgb;
      gi.light.dir = lightDir;
      gi.light.ndotl = LambertTerm (o.Normal, gi.light.dir);
  #endif
  // Call GI (lightmaps/SH/reflections) lighting function
  UnityGIInput giInput;
  UNITY_INITIALIZE_OUTPUT(UnityGIInput, giInput);
  giInput.light = gi.light;
  giInput.worldPos = worldPos;
  giInput.atten = atten;
  #if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
    giInput.lightmapUV = IN.lmap;
  #else
    giInput.lightmapUV = 0.0;
  #endif
  #if UNITY_SHOULD_SAMPLE_SH
    giInput.ambient = IN.sh;
  #else
    giInput.ambient.rgb = 0.0;
  #endif
  giInput.probeHDR[0] = unity_SpecCube0_HDR;
  giInput.probeHDR[1] = unity_SpecCube1_HDR;
  #if UNITY_SPECCUBE_BLENDING || UNITY_SPECCUBE_BOX_PROJECTION
    giInput.boxMin[0] = unity_SpecCube0_BoxMin; // .w holds lerp value for blending
  #endif
  #if UNITY_SPECCUBE_BOX_PROJECTION
    giInput.boxMax[0] = unity_SpecCube0_BoxMax;
    giInput.probePosition[0] = unity_SpecCube0_ProbePosition;
    giInput.boxMax[1] = unity_SpecCube1_BoxMax;
    giInput.boxMin[1] = unity_SpecCube1_BoxMin;
    giInput.probePosition[1] = unity_SpecCube1_ProbePosition;
  #endif
  LightingLambert_GI(o, giInput, gi);

  // realtime lighting: call lighting function
  c += LightingLambert (o, gi);
  UNITY_APPLY_FOG(IN.fogCoord, c); // apply fog
  return c;
}

ENDCG

}

    // ---- forward rendering additive lights pass:
    Pass {
        Name "FORWARD"
        Tags { "LightMode" = "ForwardAdd" }
        ZWrite Off Blend One One

CGPROGRAM
// compile directives
#pragma vertex vert_surf
#pragma fragment frag_surf
#pragma multi_compile_fog
#pragma multi_compile_fwdadd
#pragma skip_variants INSTANCING_ON
#include "HLSLSupport.cginc"
#include "UnityShaderVariables.cginc"
// Surface shader code generated based on:
// writes to per-pixel normal: no
// writes to emission: no
// writes to occlusion: no
// needs world space reflection vector: no
// needs world space normal vector: no
// needs screen space position: no
// needs world space position: no
// needs view direction: no
// needs world space view direction: no
// needs world space position for lighting: YES
// needs world space view direction for lighting: no
// needs world space view direction for lightmaps: no
// needs vertex color: no
// needs VFACE: no
// passes tangent-to-world matrix to pixel shader: no
// reads from normal: no
// 0 texcoords actually used
#define UNITY_PASS_FORWARDADD
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"

#define INTERNAL_DATA
#define WorldReflectionVector(data,normal) data.worldRefl
#define WorldNormalVector(data,normal) normal

// Original surface shader snippet:
#line 15 ""
#ifdef DUMMY_PREPROCESSOR_TO_WORK_AROUND_HLSL_COMPILER_LINE_HANDLING
#endif

//#pragma surface surf Lambert keepalpha             //and the only other change needed
sampler2D _MainTex;
sampler2D _AlphaMap;
float4 _Color;
fixed4    _GlowColor;
fixed _ScrollXSpeed;
fixed _ScrollYSpeed;
struct Input {
     float2 uv_MainTex;
     float2 uv_AlphaMap;
};
void surf (Input IN, inout SurfaceOutput o) {
    fixed2 scrolledUV = IN.uv_AlphaMap;
    fixed xScrollValue = _ScrollXSpeed*_Time;
    fixed yScrollValue = _ScrollYSpeed*_Time;
    scrolledUV += fixed2(xScrollValue,yScrollValue);
     half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
     half4 a = tex2D(_AlphaMap,IN.uv_AlphaMap);
     c.rgb = _GlowColor;
     o.Albedo = c.rgb;
     o.Alpha = c.a * tex2D(_AlphaMap, scrolledUV).r;
}


// vertex-to-fragment interpolation data
struct v2f_surf {
  float4 pos : SV_POSITION;
  half3 worldNormal : TEXCOORD0;
  float3 worldPos : TEXCOORD1;
  SHADOW_COORDS(2)
  UNITY_FOG_COORDS(3)
};

// vertex shader
v2f_surf vert_surf (appdata_full v) {
  v2f_surf o;
  UNITY_INITIALIZE_OUTPUT(v2f_surf,o);
  o.pos = UnityObjectToClipPos(v.vertex);
  float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
  fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
  o.worldPos = worldPos;
  o.worldNormal = worldNormal;

  TRANSFER_SHADOW(o); // pass shadow coordinates to pixel shader
  UNITY_TRANSFER_FOG(o,o.pos); // pass fog coordinates to pixel shader
  return o;
}

// fragment shader
fixed4 frag_surf (v2f_surf IN) : SV_Target {
  // prepare and unpack data
  Input surfIN;
  UNITY_INITIALIZE_OUTPUT(Input,surfIN);
  surfIN.uv_MainTex.x = 1.0;
  surfIN.uv_AlphaMap.x = 1.0;
  float3 worldPos = IN.worldPos;
  #ifndef USING_DIRECTIONAL_LIGHT
    fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos));
  #else
    fixed3 lightDir = _WorldSpaceLightPos0.xyz;
  #endif
  #ifdef UNITY_COMPILER_HLSL
  SurfaceOutput o = (SurfaceOutput)0;
  #else
  SurfaceOutput o;
  #endif
  o.Albedo = 0.0;
  o.Emission = 0.0;
  o.Specular = 0.0;
  o.Alpha = 0.0;
  o.Gloss = 0.0;
  fixed3 normalWorldVertex = fixed3(0,0,1);
  o.Normal = IN.worldNormal;
  normalWorldVertex = IN.worldNormal;

  // call surface function
  surf (surfIN, o);
  UNITY_LIGHT_ATTENUATION(atten, IN, worldPos)
  fixed4 c = 0;

  // Setup lighting environment
  UnityGI gi;
  UNITY_INITIALIZE_OUTPUT(UnityGI, gi);
  gi.indirect.diffuse = 0;
  gi.indirect.specular = 0;
  #if !defined(LIGHTMAP_ON)
      gi.light.color = _LightColor0.rgb;
      gi.light.dir = lightDir;
      gi.light.ndotl = LambertTerm (o.Normal, gi.light.dir);
  #endif
  gi.light.color *= atten;
  c += LightingLambert (o, gi);
  UNITY_APPLY_FOG(IN.fogCoord, c); // apply fog
  return c;
}

ENDCG

}

    // ---- deferred lighting base geometry pass:
    Pass {
        Name "PREPASS"
        Tags { "LightMode" = "PrePassBase" }

CGPROGRAM
// compile directives
#pragma vertex vert_surf
#pragma fragment frag_surf
#pragma skip_variants FOG_LINEAR FOG_EXP FOG_EXP2
#include "HLSLSupport.cginc"
#include "UnityShaderVariables.cginc"
// Surface shader code generated based on:
// writes to per-pixel normal: no
// writes to emission: no
// writes to occlusion: no
// needs world space reflection vector: no
// needs world space normal vector: no
// needs screen space position: no
// needs world space position: no
// needs view direction: no
// needs world space view direction: no
// needs world space position for lighting: YES
// needs world space view direction for lighting: no
// needs world space view direction for lightmaps: no
// needs vertex color: no
// needs VFACE: no
// passes tangent-to-world matrix to pixel shader: no
// reads from normal: YES
// 0 texcoords actually used
#define UNITY_PASS_PREPASSBASE
#include "UnityCG.cginc"
#include "Lighting.cginc"

#define INTERNAL_DATA
#define WorldReflectionVector(data,normal) data.worldRefl
#define WorldNormalVector(data,normal) normal

// Original surface shader snippet:
#line 15 ""
#ifdef DUMMY_PREPROCESSOR_TO_WORK_AROUND_HLSL_COMPILER_LINE_HANDLING
#endif

//#pragma surface surf Lambert keepalpha             //and the only other change needed
sampler2D _MainTex;
sampler2D _AlphaMap;
float4 _Color;
fixed4    _GlowColor;
fixed _ScrollXSpeed;
fixed _ScrollYSpeed;
struct Input {
     float2 uv_MainTex;
     float2 uv_AlphaMap;
};
void surf (Input IN, inout SurfaceOutput o) {
    fixed2 scrolledUV = IN.uv_AlphaMap;
    fixed xScrollValue = _ScrollXSpeed*_Time;
    fixed yScrollValue = _ScrollYSpeed*_Time;
    scrolledUV += fixed2(xScrollValue,yScrollValue);
     half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
     half4 a = tex2D(_AlphaMap,IN.uv_AlphaMap);
     c.rgb = _GlowColor;
     o.Albedo = c.rgb;
     o.Alpha = c.a * tex2D(_AlphaMap, scrolledUV).r;
}


// vertex-to-fragment interpolation data
struct v2f_surf {
  float4 pos : SV_POSITION;
  half3 worldNormal : TEXCOORD0;
  float3 worldPos : TEXCOORD1;
  UNITY_INSTANCE_ID
};

// vertex shader
v2f_surf vert_surf (appdata_full v) {
  UNITY_SETUP_INSTANCE_ID(v);
  v2f_surf o;
  UNITY_INITIALIZE_OUTPUT(v2f_surf,o);
  UNITY_TRANSFER_INSTANCE_ID(v,o);
  o.pos = UnityObjectToClipPos(v.vertex);
  float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
  fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
  o.worldPos = worldPos;
  o.worldNormal = worldNormal;
  return o;
}

// fragment shader
fixed4 frag_surf (v2f_surf IN) : SV_Target {
  UNITY_SETUP_INSTANCE_ID(IN);
  // prepare and unpack data
  Input surfIN;
  UNITY_INITIALIZE_OUTPUT(Input,surfIN);
  surfIN.uv_MainTex.x = 1.0;
  surfIN.uv_AlphaMap.x = 1.0;
  float3 worldPos = IN.worldPos;
  #ifndef USING_DIRECTIONAL_LIGHT
    fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos));
  #else
    fixed3 lightDir = _WorldSpaceLightPos0.xyz;
  #endif
  #ifdef UNITY_COMPILER_HLSL
  SurfaceOutput o = (SurfaceOutput)0;
  #else
  SurfaceOutput o;
  #endif
  o.Albedo = 0.0;
  o.Emission = 0.0;
  o.Specular = 0.0;
  o.Alpha = 0.0;
  o.Gloss = 0.0;
  fixed3 normalWorldVertex = fixed3(0,0,1);
  o.Normal = IN.worldNormal;
  normalWorldVertex = IN.worldNormal;

  // call surface function
  surf (surfIN, o);

  // output normal and specular
  fixed4 res;
  res.rgb = o.Normal * 0.5 + 0.5;
  res.a = o.Specular;
  return res;
}

ENDCG

}

    // ---- deferred lighting final pass:
    Pass {
        Name "PREPASS"
        Tags { "LightMode" = "PrePassFinal" }
        ZWrite Off

CGPROGRAM
// compile directives
#pragma vertex vert_surf
#pragma fragment frag_surf
#pragma multi_compile_fog
#pragma multi_compile_prepassfinal
#include "HLSLSupport.cginc"
#include "UnityShaderVariables.cginc"
// Surface shader code generated based on:
// writes to per-pixel normal: no
// writes to emission: no
// writes to occlusion: no
// needs world space reflection vector: no
// needs world space normal vector: no
// needs screen space position: no
// needs world space position: no
// needs view direction: no
// needs world space view direction: no
// needs world space position for lighting: YES
// needs world space view direction for lighting: no
// needs world space view direction for lightmaps: no
// needs vertex color: no
// needs VFACE: no
// passes tangent-to-world matrix to pixel shader: no
// reads from normal: no
// 2 texcoords actually used
//   float2 _MainTex
//   float2 _AlphaMap
#define UNITY_PASS_PREPASSFINAL
#include "UnityCG.cginc"
#include "Lighting.cginc"

#define INTERNAL_DATA
#define WorldReflectionVector(data,normal) data.worldRefl
#define WorldNormalVector(data,normal) normal

// Original surface shader snippet:
#line 15 ""
#ifdef DUMMY_PREPROCESSOR_TO_WORK_AROUND_HLSL_COMPILER_LINE_HANDLING
#endif

//#pragma surface surf Lambert keepalpha             //and the only other change needed
sampler2D _MainTex;
sampler2D _AlphaMap;
float4 _Color;
fixed4    _GlowColor;
fixed _ScrollXSpeed;
fixed _ScrollYSpeed;
struct Input {
     float2 uv_MainTex;
     float2 uv_AlphaMap;
};
void surf (Input IN, inout SurfaceOutput o) {
    fixed2 scrolledUV = IN.uv_AlphaMap;
    fixed xScrollValue = _ScrollXSpeed*_Time;
    fixed yScrollValue = _ScrollYSpeed*_Time;
    scrolledUV += fixed2(xScrollValue,yScrollValue);
     half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
     half4 a = tex2D(_AlphaMap,IN.uv_AlphaMap);
     c.rgb = _GlowColor;
     o.Albedo = c.rgb;
     o.Alpha = c.a * tex2D(_AlphaMap, scrolledUV).r;
}


// vertex-to-fragment interpolation data
struct v2f_surf {
  float4 pos : SV_POSITION;
  float4 pack0 : TEXCOORD0; // _MainTex _AlphaMap
  float3 worldPos : TEXCOORD1;
  float4 screen : TEXCOORD2;
  float4 lmap : TEXCOORD3;
#ifdef LIGHTMAP_OFF
  float3 vlight : TEXCOORD4;
#else
#ifdef DIRLIGHTMAP_OFF
  float4 lmapFadePos : TEXCOORD4;
#endif
#endif
  UNITY_FOG_COORDS(5)
  #if !defined(LIGHTMAP_OFF) && defined(DIRLIGHTMAP_COMBINED)
  fixed3 tSpace0 : TEXCOORD6;
  fixed3 tSpace1 : TEXCOORD7;
  fixed3 tSpace2 : TEXCOORD8;
  #endif
  UNITY_INSTANCE_ID
};
float4 _MainTex_ST;
float4 _AlphaMap_ST;

// vertex shader
v2f_surf vert_surf (appdata_full v) {
  UNITY_SETUP_INSTANCE_ID(v);
  v2f_surf o;
  UNITY_INITIALIZE_OUTPUT(v2f_surf,o);
  UNITY_TRANSFER_INSTANCE_ID(v,o);
  o.pos = UnityObjectToClipPos(v.vertex);
  o.pack0.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
  o.pack0.zw = TRANSFORM_TEX(v.texcoord, _AlphaMap);
  float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
  fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
  #if !defined(LIGHTMAP_OFF) && defined(DIRLIGHTMAP_COMBINED)
  fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
  fixed tangentSign = v.tangent.w * unity_WorldTransformParams.w;
  fixed3 worldBinormal = cross(worldNormal, worldTangent) * tangentSign;
  #endif
  #if !defined(LIGHTMAP_OFF) && defined(DIRLIGHTMAP_COMBINED)
  o.tSpace0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x);
  o.tSpace1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y);
  o.tSpace2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z);
  #endif
  o.worldPos = worldPos;
  o.screen = ComputeScreenPos (o.pos);
#ifndef DYNAMICLIGHTMAP_OFF
  o.lmap.zw = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
#else
  o.lmap.zw = 0;
#endif
#ifndef LIGHTMAP_OFF
  o.lmap.xy = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
  #ifdef DIRLIGHTMAP_OFF
    o.lmapFadePos.xyz = (mul(unity_ObjectToWorld, v.vertex).xyz - unity_ShadowFadeCenterAndType.xyz) * unity_ShadowFadeCenterAndType.w;
    o.lmapFadePos.w = (-UnityObjectToViewPos(v.vertex).z) * (1.0 - unity_ShadowFadeCenterAndType.w);
  #endif
#else
  o.lmap.xy = 0;
  float3 worldN = UnityObjectToWorldNormal(v.normal);
  o.vlight = ShadeSH9 (float4(worldN,1.0));
#endif
  UNITY_TRANSFER_FOG(o,o.pos); // pass fog coordinates to pixel shader
  return o;
}
sampler2D _LightBuffer;
#if defined (SHADER_API_XBOX360) && defined (UNITY_HDR_ON)
sampler2D _LightSpecBuffer;
#endif
#ifdef LIGHTMAP_ON
float4 unity_LightmapFade;
#endif
fixed4 unity_Ambient;

// fragment shader
fixed4 frag_surf (v2f_surf IN) : SV_Target {
  UNITY_SETUP_INSTANCE_ID(IN);
  // prepare and unpack data
  Input surfIN;
  UNITY_INITIALIZE_OUTPUT(Input,surfIN);
  surfIN.uv_MainTex.x = 1.0;
  surfIN.uv_AlphaMap.x = 1.0;
  surfIN.uv_MainTex = IN.pack0.xy;
  surfIN.uv_AlphaMap = IN.pack0.zw;
  float3 worldPos = IN.worldPos;
  #ifndef USING_DIRECTIONAL_LIGHT
    fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos));
  #else
    fixed3 lightDir = _WorldSpaceLightPos0.xyz;
  #endif
  #ifdef UNITY_COMPILER_HLSL
  SurfaceOutput o = (SurfaceOutput)0;
  #else
  SurfaceOutput o;
  #endif
  o.Albedo = 0.0;
  o.Emission = 0.0;
  o.Specular = 0.0;
  o.Alpha = 0.0;
  o.Gloss = 0.0;
  fixed3 normalWorldVertex = fixed3(0,0,1);

  // call surface function
  surf (surfIN, o);
  half4 light = tex2Dproj (_LightBuffer, UNITY_PROJ_COORD(IN.screen));
#if defined (SHADER_API_MOBILE)
  light = max(light, half4(0.001, 0.001, 0.001, 0.001));
#endif
#ifndef UNITY_HDR_ON
  light = -log2(light);
#endif
#if defined (SHADER_API_XBOX360) && defined (UNITY_HDR_ON)
  light.w = tex2Dproj (_LightSpecBuffer, UNITY_PROJ_COORD(IN.screen)).r;
#endif
  #ifndef LIGHTMAP_OFF
    #ifdef DIRLIGHTMAP_OFF
      // single lightmap
      fixed4 lmtex = UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.lmap.xy);
      fixed3 lm = DecodeLightmap (lmtex);
      light.rgb += lm;
    #elif DIRLIGHTMAP_COMBINED
      // directional lightmaps
      fixed4 lmtex = UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.lmap.xy);
      half4 lm = half4(DecodeLightmap(lmtex), 0);
      light += lm;
    #elif DIRLIGHTMAP_SEPARATE
      // directional with specular - no support
    #endif // DIRLIGHTMAP_OFF
  #else
    light.rgb += IN.vlight;
  #endif // !LIGHTMAP_OFF

  #ifndef DYNAMICLIGHTMAP_OFF
  fixed4 dynlmtex = UNITY_SAMPLE_TEX2D(unity_DynamicLightmap, IN.lmap.zw);
  light.rgb += DecodeRealtimeLightmap (dynlmtex);
  #endif

  half4 c = LightingLambert_PrePass (o, light);
  UNITY_APPLY_FOG(IN.fogCoord, c); // apply fog
  return c;
}

ENDCG

}

    // ---- deferred shading pass:
    Pass {
        Name "DEFERRED"
        Tags { "LightMode" = "Deferred" }

CGPROGRAM
// compile directives
#pragma vertex vert_surf
#pragma fragment frag_surf
#pragma exclude_renderers nomrt
#pragma multi_compile_prepassfinal
#pragma skip_variants FOG_LINEAR FOG_EXP FOG_EXP2
#include "HLSLSupport.cginc"
#include "UnityShaderVariables.cginc"
// Surface shader code generated based on:
// writes to per-pixel normal: no
// writes to emission: no
// writes to occlusion: no
// needs world space reflection vector: no
// needs world space normal vector: no
// needs screen space position: no
// needs world space position: no
// needs view direction: no
// needs world space view direction: no
// needs world space position for lighting: YES
// needs world space view direction for lighting: no
// needs world space view direction for lightmaps: no
// needs vertex color: no
// needs VFACE: no
// passes tangent-to-world matrix to pixel shader: no
// reads from normal: YES
// 0 texcoords actually used
#define UNITY_PASS_DEFERRED
#include "UnityCG.cginc"
#include "Lighting.cginc"

#define INTERNAL_DATA
#define WorldReflectionVector(data,normal) data.worldRefl
#define WorldNormalVector(data,normal) normal

// Original surface shader snippet:
#line 15 ""
#ifdef DUMMY_PREPROCESSOR_TO_WORK_AROUND_HLSL_COMPILER_LINE_HANDLING
#endif

//#pragma surface surf Lambert keepalpha             //and the only other change needed
sampler2D _MainTex;
sampler2D _AlphaMap;
float4 _Color;
fixed4    _GlowColor;
fixed _ScrollXSpeed;
fixed _ScrollYSpeed;
struct Input {
     float2 uv_MainTex;
     float2 uv_AlphaMap;
};
void surf (Input IN, inout SurfaceOutput o) {
    fixed2 scrolledUV = IN.uv_AlphaMap;
    fixed xScrollValue = _ScrollXSpeed*_Time;
    fixed yScrollValue = _ScrollYSpeed*_Time;
    scrolledUV += fixed2(xScrollValue,yScrollValue);
     half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
     half4 a = tex2D(_AlphaMap,IN.uv_AlphaMap);
     c.rgb = _GlowColor;
     o.Albedo = c.rgb;
     o.Alpha = c.a * tex2D(_AlphaMap, scrolledUV).r;
}


// vertex-to-fragment interpolation data
struct v2f_surf {
  float4 pos : SV_POSITION;
  half3 worldNormal : TEXCOORD0;
  float3 worldPos : TEXCOORD1;
  float4 lmap : TEXCOORD2;
#ifdef LIGHTMAP_OFF
  #if UNITY_SHOULD_SAMPLE_SH
    half3 sh : TEXCOORD3; // SH
  #endif
#else
  #ifdef DIRLIGHTMAP_OFF
    float4 lmapFadePos : TEXCOORD3;
  #endif
#endif
  UNITY_INSTANCE_ID
};

// vertex shader
v2f_surf vert_surf (appdata_full v) {
  UNITY_SETUP_INSTANCE_ID(v);
  v2f_surf o;
  UNITY_INITIALIZE_OUTPUT(v2f_surf,o);
  UNITY_TRANSFER_INSTANCE_ID(v,o);
  o.pos = UnityObjectToClipPos(v.vertex);
  float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
  fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
  o.worldPos = worldPos;
  o.worldNormal = worldNormal;
#ifndef DYNAMICLIGHTMAP_OFF
  o.lmap.zw = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
#else
  o.lmap.zw = 0;
#endif
#ifndef LIGHTMAP_OFF
  o.lmap.xy = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
  #ifdef DIRLIGHTMAP_OFF
    o.lmapFadePos.xyz = (mul(unity_ObjectToWorld, v.vertex).xyz - unity_ShadowFadeCenterAndType.xyz) * unity_ShadowFadeCenterAndType.w;
    o.lmapFadePos.w = (-UnityObjectToViewPos(v.vertex).z) * (1.0 - unity_ShadowFadeCenterAndType.w);
  #endif
#else
  o.lmap.xy = 0;
    #if UNITY_SHOULD_SAMPLE_SH
      o.sh = 0;
      o.sh = ShadeSHPerVertex (worldNormal, o.sh);
    #endif
#endif
  return o;
}
#ifdef LIGHTMAP_ON
float4 unity_LightmapFade;
#endif
fixed4 unity_Ambient;

// fragment shader
void frag_surf (v2f_surf IN,
    out half4 outDiffuse : SV_Target0,
    out half4 outSpecSmoothness : SV_Target1,
    out half4 outNormal : SV_Target2,
    out half4 outEmission : SV_Target3) {
  UNITY_SETUP_INSTANCE_ID(IN);
  // prepare and unpack data
  Input surfIN;
  UNITY_INITIALIZE_OUTPUT(Input,surfIN);
  surfIN.uv_MainTex.x = 1.0;
  surfIN.uv_AlphaMap.x = 1.0;
  float3 worldPos = IN.worldPos;
  #ifndef USING_DIRECTIONAL_LIGHT
    fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos));
  #else
    fixed3 lightDir = _WorldSpaceLightPos0.xyz;
  #endif
  #ifdef UNITY_COMPILER_HLSL
  SurfaceOutput o = (SurfaceOutput)0;
  #else
  SurfaceOutput o;
  #endif
  o.Albedo = 0.0;
  o.Emission = 0.0;
  o.Specular = 0.0;
  o.Alpha = 0.0;
  o.Gloss = 0.0;
  fixed3 normalWorldVertex = fixed3(0,0,1);
  o.Normal = IN.worldNormal;
  normalWorldVertex = IN.worldNormal;

  // call surface function
  surf (surfIN, o);
fixed3 originalNormal = o.Normal;
  half atten = 1;

  // Setup lighting environment
  UnityGI gi;
  UNITY_INITIALIZE_OUTPUT(UnityGI, gi);
  gi.indirect.diffuse = 0;
  gi.indirect.specular = 0;
  gi.light.color = 0;
  gi.light.dir = half3(0,1,0);
  gi.light.ndotl = LambertTerm (o.Normal, gi.light.dir);
  // Call GI (lightmaps/SH/reflections) lighting function
  UnityGIInput giInput;
  UNITY_INITIALIZE_OUTPUT(UnityGIInput, giInput);
  giInput.light = gi.light;
  giInput.worldPos = worldPos;
  giInput.atten = atten;
  #if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
    giInput.lightmapUV = IN.lmap;
  #else
    giInput.lightmapUV = 0.0;
  #endif
  #if UNITY_SHOULD_SAMPLE_SH
    giInput.ambient = IN.sh;
  #else
    giInput.ambient.rgb = 0.0;
  #endif
  giInput.probeHDR[0] = unity_SpecCube0_HDR;
  giInput.probeHDR[1] = unity_SpecCube1_HDR;
  #if UNITY_SPECCUBE_BLENDING || UNITY_SPECCUBE_BOX_PROJECTION
    giInput.boxMin[0] = unity_SpecCube0_BoxMin; // .w holds lerp value for blending
  #endif
  #if UNITY_SPECCUBE_BOX_PROJECTION
    giInput.boxMax[0] = unity_SpecCube0_BoxMax;
    giInput.probePosition[0] = unity_SpecCube0_ProbePosition;
    giInput.boxMax[1] = unity_SpecCube1_BoxMax;
    giInput.boxMin[1] = unity_SpecCube1_BoxMin;
    giInput.probePosition[1] = unity_SpecCube1_ProbePosition;
  #endif
  LightingLambert_GI(o, giInput, gi);

  // call lighting function to output g-buffer
  outEmission = LightingLambert_Deferred (o, gi, outDiffuse, outSpecSmoothness, outNormal);
  #ifndef UNITY_HDR_ON
  outEmission.rgb = exp2(-outEmission.rgb);
  #endif
}

ENDCG

}

    // ---- meta information extraction pass:
    Pass {
        Name "Meta"
        Tags { "LightMode" = "Meta" }
        Cull Off

CGPROGRAM
// compile directives
#pragma vertex vert_surf
#pragma fragment frag_surf
#pragma skip_variants FOG_LINEAR FOG_EXP FOG_EXP2
#pragma skip_variants INSTANCING_ON
#include "HLSLSupport.cginc"
#include "UnityShaderVariables.cginc"
// Surface shader code generated based on:
// writes to per-pixel normal: no
// writes to emission: no
// writes to occlusion: no
// needs world space reflection vector: no
// needs world space normal vector: no
// needs screen space position: no
// needs world space position: no
// needs view direction: no
// needs world space view direction: no
// needs world space position for lighting: YES
// needs world space view direction for lighting: no
// needs world space view direction for lightmaps: no
// needs vertex color: no
// needs VFACE: no
// passes tangent-to-world matrix to pixel shader: no
// reads from normal: no
// 0 texcoords actually used
#define UNITY_PASS_META
#include "UnityCG.cginc"
#include "Lighting.cginc"

#define INTERNAL_DATA
#define WorldReflectionVector(data,normal) data.worldRefl
#define WorldNormalVector(data,normal) normal

// Original surface shader snippet:
#line 15 ""
#ifdef DUMMY_PREPROCESSOR_TO_WORK_AROUND_HLSL_COMPILER_LINE_HANDLING
#endif

//#pragma surface surf Lambert keepalpha             //and the only other change needed
sampler2D _MainTex;
sampler2D _AlphaMap;
float4 _Color;
fixed4    _GlowColor;
fixed _ScrollXSpeed;
fixed _ScrollYSpeed;
struct Input {
     float2 uv_MainTex;
     float2 uv_AlphaMap;
};
void surf (Input IN, inout SurfaceOutput o) {
    fixed2 scrolledUV = IN.uv_AlphaMap;
    fixed xScrollValue = _ScrollXSpeed*_Time;
    fixed yScrollValue = _ScrollYSpeed*_Time;
    scrolledUV += fixed2(xScrollValue,yScrollValue);
     half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
     half4 a = tex2D(_AlphaMap,IN.uv_AlphaMap);
     c.rgb = _GlowColor;
     o.Albedo = c.rgb;
     o.Alpha = c.a * tex2D(_AlphaMap, scrolledUV).r;
}

#include "UnityMetaPass.cginc"

// vertex-to-fragment interpolation data
struct v2f_surf {
  float4 pos : SV_POSITION;
  float3 worldPos : TEXCOORD0;
};

// vertex shader
v2f_surf vert_surf (appdata_full v) {
  v2f_surf o;
  UNITY_INITIALIZE_OUTPUT(v2f_surf,o);
  o.pos = UnityMetaVertexPosition(v.vertex, v.texcoord1.xy, v.texcoord2.xy, unity_LightmapST, unity_DynamicLightmapST);
  float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
  fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
  o.worldPos = worldPos;
  return o;
}

// fragment shader
fixed4 frag_surf (v2f_surf IN) : SV_Target {
  // prepare and unpack data
  Input surfIN;
  UNITY_INITIALIZE_OUTPUT(Input,surfIN);
  surfIN.uv_MainTex.x = 1.0;
  surfIN.uv_AlphaMap.x = 1.0;
  float3 worldPos = IN.worldPos;
  #ifndef USING_DIRECTIONAL_LIGHT
    fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos));
  #else
    fixed3 lightDir = _WorldSpaceLightPos0.xyz;
  #endif
  #ifdef UNITY_COMPILER_HLSL
  SurfaceOutput o = (SurfaceOutput)0;
  #else
  SurfaceOutput o;
  #endif
  o.Albedo = 0.0;
  o.Emission = 0.0;
  o.Specular = 0.0;
  o.Alpha = 0.0;
  o.Gloss = 0.0;
  fixed3 normalWorldVertex = fixed3(0,0,1);

  // call surface function
  surf (surfIN, o);
  UnityMetaInput metaIN;
  UNITY_INITIALIZE_OUTPUT(UnityMetaInput, metaIN);
  metaIN.Albedo = o.Albedo;
  metaIN.Emission = o.Emission;
  return UnityMetaFragment(metaIN);
}

ENDCG

}

    // ---- end of surface shader generated code

#LINE 44

}
Fallback "Transparent/VertexLit"
}

That’s over 1100 lines of shader code. And that’s not including the additional passes that get included with the fallback, and the 20 variants that get generated. The final result is this “basic” shadic shader becomes a third of a megabyte of code by itself with each pass being roughly 200 lines of code.

And here’s the shader as a vertex / fragment shader working the way I expect you actually want it to work.

Shader "Custom/Red Alpha Gradient FX" {
Properties {
    _Color ("Main Color", Color) = (1,1,1,1)
    _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    _AlphaMap ("Gradient Transparency Map (R)", 2D) = "white" {}
    _GlowColor ("Glow Color", Color ) = ( 1.0, 1.0, 1.0, 1.0 )
    _ScrollXSpeed("X Scroll Speed", Float) = 2
    _ScrollYSpeed("Y Scroll Speed", Float) = 2
}
SubShader {
    Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
 
    ZWrite Off
    Blend SrcAlpha One

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

        sampler2D _MainTex;
        sampler2D _AlphaMap;
        float4 _MainTex_ST;
        float4 _AlphaMap_ST;

        fixed4 _Color;
        fixed4 _GlowColor;
        float _ScrollXSpeed;
        float _ScrollYSpeed;

        struct v2f {
            float4 pos : SV_POSITION;
            float4 texcoord : TEXCOORD0;
        };

        v2f vert(appdata_img v)
        {
            v2f o;
            o.pos = UnityObjectToClipPos(v.vertex);
            o.texcoord.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
            o.texcoord.zw = TRANSFORM_TEX(v.texcoord, _AlphaMap) + frac(float2(_ScrollXSpeed, _ScrollYSpeed) * _Time.xx);
            return o;
        }

        fixed4 frag (v2f i) : SV_Target
        {
            fixed main_mask = tex2D(_MainTex, i.texcoord.xy).a * _Color.a;
            fixed alpha_mask = tex2D(_AlphaMap, i.texcoord.zw).r;

            return fixed4(_GlowColor.rgb, main_mask * alpha_mask);
        }
        ENDCG
    }
}
}

And that’s it. It doesn’t expand out to anything, and it’ll run about 10x faster.

4 Likes

Wow, well thanks for taking the time to write that. That was really generous of you. I figured it out yesterday in the surf version, but this will be an EXCELLENT learning tool to teach me how to compare the surface version to a vertex one and will teach me a lot. I actually spent 20 hours in the last 3 days learning everything I could about CG/HLSL, so I’m finally starting to understand the basics.

I tried your code, but for some reason, it had an error where it said UnityObjectToClip was not declared. I have no idea why because it’s a function and I can see that the CGINC file is included. So I just took the o.pos = UnityObjectToClipPos(v.vertex); line out and replaced it with o.pos = mul(UNITY_MATRIX_MVP, v.vertex); and it works fine. If you know why that error was coming up, please feel free to educate me on it.

I also took out everything related to _Color in the originals and this one. I have no idea why the creator of it chose to use it too. Only it’s alpha was being used, while NOT using the alpha in _GlowColor, it was redundant. BTW, using 1 texcoord var as a float4 to hold 2 sets of coordinates actually threw me for a loop at first until I realized what you had done there. VERY slick move! :smile:

About it being a surface shader: considering the fact that I need lighting, it’s not that serious at all. I stress tested the effect, and with 6 different types on screen and over 1000 objects (half of which used the effect) and 2 lights, my framerate was STILL way above 60. In fact, I had to shoot my batch count to near 10K to see it drop below 60 FPS.

…but I do see the point in what you are saying: better to learn to do it the RIGHT and most EFFICIENT way from the start. :slight_smile:

Yeah, this one effect isn’t likely to be an issue for frame rate by itself, Unity’s Standard shader is roughly 3 times as complex as your original surface shader before even turning on some of the extra features, but there’s no reason to do the expensive version if you don’t need it.

If you do need lighting on it there’s still cheaper ways to do it than using a surface shader, especially for a 2d game like this.

1 Like

Yeah, you’re right of course. Thanks for the info. :slight_smile: I’m still trying to get a better handhold on the basics of shaders, but I’ve already started looking up a few articles on vertex lighting to see how I can code it myself.

BTW that article you wrote on rotating a texture (it provided one texture examples, 2 texture examples and a surf and vertex shader example) was very informative. I’m going to mess around with it some over the next day or two and TRY to find a way to change it so that I can rotate just the secondary texture over an unrotated primary texture, while still being able to keep the additive cutout effect I have going above working with it.

…the keyword being TRY! :smile:

This shader really helped me thanks!