In the third semester I had two electives which were quite easy to combine: Shader development and Particle Design. I combined the electives by creating a tornado spell.
Here is the shader code:
Shader "ShaderCourse/TornadoOuter"
{
Properties
{
_MainTex ("Glow Texture", 2D) = "white" {}
_InnerTex("Inner Texture", 2D) = "black" {}
_DisplacementTex ("Displacement Texture", 2D) = "black" {}
_DisplacementTex2 ("Displacement Texture 2", 2D) = "black" {}
_Direction("Direction", Vector) = (2,5,-2,-9)
_DisplacementSpeed("Displacement Speed", float) = 1
_Displacement("Displacement", float) = 1.0
_Color("Color Tint", Color) = (1, 1, 1, 1)
_InnerColor("Inner Color Tint", Color) = (1, 1, 1, 1)
_InnerAnimationSpeed ("Glow Animation Speed", float) = 0.1
_OuterTex("Outer Texture", 2D) = "black" {}
_OuterColor("Outer Color Tint", Color) = (0, 0, 0, 0)
_OuterDisplacementOffset("Outer Displacement Offset", float) = 1.0
_OuterAnimationSpeed("Outer Rotation Speed", float) = 1
_Threshold("Threshold", Range(0,1)) = 0.1
_OutlineIntensity("Outline Intensity", Range(0,5)) = 0.1
_OutlineThickness("Outline Thickness", Range(0,0.1)) = 0.01
}
SubShader
{
Tags{ "RenderType" = "Opaque" }
Cull Off // for some reason, when in Particle system, the mesh is turned inside out
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 position : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 position : SV_POSITION;
};
sampler2D _InnerTex;
float4 _InnerTex_ST;
sampler2D _DisplacementTex;
sampler2D _DisplacementTex2;
float _Displacement;
float _DisplacementSpeed;
float4 _MainTex_ST;
float4 _DisplacementTex_ST;
float4 _DisplacementTex2_ST;
float4 _Direction;
float4 _InnerColor;
v2f vert(appdata v)
{
v2f o;
float2 displacevar = v.uv * _DisplacementTex_ST;
displacevar += _DisplacementTex_ST.zw;
displacevar += _Direction.xy * _Time.x * _DisplacementSpeed;
v.position.xyz += v.normal.xyz * tex2Dlod(_DisplacementTex, float4(displacevar.x, displacevar.y, 0, 3)).r * _Displacement;
float2 displacevar2 = v.uv * _DisplacementTex2_ST;
displacevar2 += _DisplacementTex2_ST.zw;
displacevar2 += _Direction.zw * _Time.x * _DisplacementSpeed;
v.position.xyz += v.normal.xyz * tex2Dlod(_DisplacementTex2, float4(displacevar2.x, displacevar2.y, 0, 3)).r * _Displacement;
o.position = UnityObjectToClipPos(v.position);
o.uv = v.uv;
return o;
}
float4 frag(v2f i) : SV_Target
{
float4 col = tex2D(_InnerTex, i.uv);
col = col * _InnerColor;
return col;
}
ENDCG
}
Tags{ "RenderType" = "Transparent" "Queue" = "AlphaTest" }
Blend One One
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 position : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 position : SV_POSITION;
};
sampler2D _MainTex;
sampler2D _DisplacementTex;
sampler2D _DisplacementTex2;
float _Displacement;
float4 _MainTex_ST;
float4 _Color;
float4 _DisplacementTex_ST;
float4 _DisplacementTex2_ST;
float4 _Direction;
float _DisplacementSpeed;
float _InnerAnimationSpeed;
v2f vert(appdata v)
{
v2f o;
float2 displacevar = v.uv * _DisplacementTex_ST;
displacevar += _DisplacementTex_ST.zw;
displacevar += _Direction.xy * _Time.x * _DisplacementSpeed;
v.position.xyz += v.normal.xyz * tex2Dlod(_DisplacementTex, float4(displacevar.x, displacevar.y, 0, 3)).r * _Displacement;
float2 displacevar2 = v.uv * _DisplacementTex2_ST;
displacevar2 += _DisplacementTex2_ST.zw;
displacevar2 += _Direction.zw * _Time.x * _DisplacementSpeed;
v.position.xyz += v.normal.xyz * tex2Dlod(_DisplacementTex2, float4(displacevar2.x, displacevar2.y, 0, 3)).r * _Displacement;
o.position = UnityObjectToClipPos(v.position);
o.uv = v.uv;
return o;
}
float4 frag(v2f i) : SV_Target
{
i.uv.x = i.uv.x + (_Time * _InnerAnimationSpeed);
i.uv *= _MainTex_ST;
i.uv += _MainTex_ST.zw;
float4 col = tex2D(_MainTex, i.uv);
col = col * _Color;
return col;
}
ENDCG
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 position : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 position : SV_POSITION;
};
sampler2D _OuterTex;
sampler2D _DisplacementTex;
sampler2D _DisplacementTex2;
float4 _OuterTex_ST;
float4 _MainTex_ST;
float4 _OuterColor;
float4 _DisplacementTex_ST;
float4 _DisplacementTex2_ST;
float4 _Direction;
float _Displacement;
float _OuterDisplacementOffset;
float _DisplacementSpeed;
float _OuterAnimationSpeed;
float _Threshold;
v2f vert(appdata v)
{
v2f o;
float2 displacevar = v.uv * _DisplacementTex_ST;
displacevar += _Direction.xy;
v.position.xyz += v.normal.xyz * (tex2Dlod(_DisplacementTex, float4(displacevar.x, displacevar.y, 0, -3)).r * _Displacement + _OuterDisplacementOffset + 0.001);
float2 displacevar2 = v.uv * _DisplacementTex2_ST;
displacevar2 += _Direction.zw;
v.position.xyz += v.normal.xyz * (tex2Dlod(_DisplacementTex2, float4(displacevar2.x, displacevar2.y, 0, -3)).r * _Displacement + _OuterDisplacementOffset + 0.001);
o.position = UnityObjectToClipPos(v.position);
o.uv = v.uv;
return o;
}
float4 frag(v2f i) : SV_Target
{
i.uv.x = i.uv.x + (_Time * _OuterAnimationSpeed);
float4 col = tex2D(_OuterTex, i.uv);
clip(col.a - _Threshold);
col *= _OuterColor;
return col;
}
ENDCG
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 position : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 position : SV_POSITION;
};
sampler2D _OuterTex;
sampler2D _DisplacementTex;
sampler2D _DisplacementTex2;
float4 _OuterTex_ST;
float4 _MainTex_ST;
float4 _OuterColor;
float4 _DisplacementTex_ST;
float4 _DisplacementTex2_ST;
float4 _Direction;
float _Displacement;
float _OuterDisplacementOffset;
float _DisplacementSpeed;
float _OuterAnimationSpeed;
float _Threshold;
float _OutlineIntensity;
float _OutlineThickness;
v2f vert(appdata v)
{
v2f o;
float2 displacevar = v.uv * _DisplacementTex_ST;
displacevar += _Direction.xy;
v.position.xyz += v.normal.xyz * (tex2Dlod(_DisplacementTex, float4(displacevar.x, displacevar.y, 0, -3)).r * _Displacement + _OuterDisplacementOffset);
float2 displacevar2 = v.uv * _DisplacementTex2_ST;
displacevar2 += _Direction.zw;
v.position.xyz += v.normal.xyz * (tex2Dlod(_DisplacementTex2, float4(displacevar2.x, displacevar2.y, 0, -3)).r * _Displacement + _OuterDisplacementOffset);
o.position = UnityObjectToClipPos(v.position);
o.uv = v.uv;
return o;
}
float4 frag(v2f i) : SV_Target
{
i.uv.x = i.uv.x + (_Time * _OuterAnimationSpeed);
float4 col = tex2D(_OuterTex, i.uv);
clip(col.a - _Threshold + _OutlineThickness);
col *= _OuterColor * _OutlineIntensity;
return col;
}
ENDCG
}
}
}