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
				}
				}
	}
loading
×