Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Shader "Custom/swirl"
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
Tags { "RenderType"="Opaque" }
LOD 200
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows vertex:vert
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input
float2 uv_MainTex;
half _Glossiness;
half _Metallic;
fixed4 _Color;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See for more information about instancing.
// #pragma instancing_options assumeuniformscaling
// put more per-instance properties here
// to see this function graphed out go to:
float3 cosPalette( float t , float3 brightness, float3 contrast, float3 osc, float3 phase)
return brightness + contrast*cos( 6.28318*(osc*t+phase) );
float3 swirl(float2 pos){
float angle = atan(pos.y/abs(pos.x+0.01));
// we take the absolute value of x and add a small number to avoid
// dividing by zero which is undefined behavior
float r = sin(angle+ _Time.y);
// sin returns a number from -1 to 1, and colors are from 0 to 1, so thats
// why you only see red on the screen half the time. the angle goes around
// the screen, adding time moves it clockwise
float ringFrequency = 5.; // making this number bigger will increase frequency
float g = cos(length(pos*ringFrequency) );
// the distance (aka length) from the center put in a cos, time moves the
// circles in.
float b = cos(angle+ cos(length(pos*15.)) );
// this combines what we learned in the red and green channels
// angle is going through a cos and so is the length, so we see the
// blue channel oscillating in both dimensions the polar coordinates give us
float3 brightness = float3(0.5,0.5,0.5);
float3 contrast = float3(0.3,0.13,0.19);
// the numbers that divide time are pretty arbitrary, as long as they are not the same and are
// somewhere between 10-100 id say it gives the desired effect
float3 osc = float3(r,cos(_Time.y/20.),cos(_Time.y/31.));
float3 phase = float3(b,0.5,0.1);
float3 color = cosPalette(g, brightness, contrast, osc, phase);
return color;
void vert (inout appdata_full v) {
// Do whatever you want with the "vertex" property of v here
float3 worldPos = mul (unity_ObjectToWorld, v.vertex);
fixed3 swl = swirl(v.texcoord.xy);
v.vertex.y = length(worldPos.xy)*2. + swl.x*3.;
void surf (Input IN, inout SurfaceOutputStandard o)
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
fixed2 pos = ((IN.uv_MainTex.xy) - 0.5)*2.0; // origin is in center
o.Albedo = swirl(pos);
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
FallBack "Diffuse"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment