-
-
Save xiangyuan/3c30df5e1dc64b9a39745217d45f4659 to your computer and use it in GitHub Desktop.
A shader for rendering circles arranged in a circle. Written in CG for use in the Unity engine
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Shader "Custom/Circular Circles" { | |
Properties { | |
_CircleCount ("Circle Count", Float ) = 8 | |
_CircleRadius ("Circle Radius", Range(0, 1)) = 0.18 | |
_CircleSharpness ("Circle Sharpness", Range(0, 0.999)) = 0.95 | |
_GroupRadius("Group Radius", Range(0, 1)) = 0.6 | |
} | |
SubShader { | |
Pass { | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
#include "UnityCG.cginc" | |
// Two pi | |
static float TAU = 6.28318530718; | |
// Properties | |
uniform float _CircleCount; | |
uniform float _CircleRadius; | |
uniform float _CircleSharpness; | |
uniform float _GroupRadius; | |
struct VertexInput { | |
float4 vertex : POSITION; | |
float2 texcoord0 : TEXCOORD0; | |
}; | |
struct VertexOutput { | |
float4 pos : SV_POSITION; | |
float2 coords : TEXCOORD0; | |
}; | |
VertexOutput vert (VertexInput v) { | |
VertexOutput o; | |
o.coords = v.texcoord0 * 2 - 1; // Fragment Coordinates | |
o.pos = UnityObjectToClipPos( v.vertex ); | |
return o; | |
} | |
float4 frag( VertexOutput i ) : COLOR { | |
// Find closest circle center for each fragment | |
float angRad = atan2( i.coords.g, i.coords.r ); | |
float snapVal = _CircleCount / TAU; | |
float angRadSnapped = round( angRad * snapVal) / snapVal; | |
float2 dirSnapped = float2( cos(angRadSnapped), sin(angRadSnapped) ); | |
float2 nearestCircleCenter = dirSnapped * _GroupRadius; | |
// Distance to nearest circle center | |
float dist = distance( i.coords, nearestCircleCenter ); | |
// Remap it into looking solid instead of having a circular soft gradient | |
float remappedDist = (dist - _CircleRadius) / (_CircleRadius * (_CircleSharpness - 1.0)); | |
float finalCircleMask = saturate( remappedDist ); // Ensure 0 to 1 range | |
return float4( finalCircleMask.xxx, 1 ); | |
} | |
ENDCG | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment