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.
And that’s it. It doesn’t expand out to anything, and it’ll run about 10x faster.