Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Shader "LinearGrad"
- {
- Properties
- {
- _TopColor ("Top Color", Color) = (1, 1, 1, 1)
- _BottomColor ("Bottom Color", Color) = (1, 1, 1, 1)
- _RampTex ("Ramp Texture", 2D) = "white" {}
- _MaskRad("Mask Radius", Range(0.0,1.0)) = 0.5
- _MaskSoft("Mask Softness", Range(0.0,1.0)) = 0.1
- _Border("Border Thickness",Range(0.0,1.0)) = 0.1
- _BorderColor("Border Color", Color) = (0, 0, 0, 1)
- }
- SubShader
- {
- //this forces the preview in the material inspector to show as a flat quad instead of the default shapes
- Tags{ "PreviewType" = "Plane" }
- Blend SrcAlpha OneMinusSrcAlpha
- Fog { Mode Off }
- Lighting Off
- ZWrite On//switched to on to work better with transparency, depends on usage
- Cull Off
- Pass
- {
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- struct vertexIn
- {
- float4 pos : POSITION;
- float2 uv : TEXCOORD0;
- };
- struct v2f
- {
- float4 pos : SV_POSITION;
- float2 uv : TEXCOORD0;
- };
- v2f vert(vertexIn input)
- {
- v2f output;
- output.pos = UnityObjectToClipPos(input.pos);
- output.uv = input.uv;
- return output;
- }
- float4 _TopColor, _BottomColor;
- sampler2D _RampTex;
- float4 _BorderColor;
- float _Border;
- float _MaskSoft;
- float _MaskRad;
- /*
- Distance functions return the implicit distance from a given point and the surface of a shape
- Many distance functions give exact values, meaning negative values represent the interior of the shape
- Excellent 2D distance functions reference by the legendary Inigo Quilez
- http://www.iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm
- */
- //the distance function for a circle centered around point 'p' with radius 'r'
- float dCircle(float2 p, float r) { return length(p) - r; }
- float4 frag(v2f input) : COLOR
- {
- float4 result = 0.0;
- //this value is used with the 'smoothstep' function to produce smooth yet distinct edges from the fields returned by distance functions
- //you can actually calculate what this value needs to be for consistent softness across different resolutions using screen-space derivatives, but here we use predefined constants
- float s = lerp(0.005, 0.1, _MaskSoft);
- //The border is just a slightly bigger circle behind the mask circle
- float borderRadius = lerp(0.1, 0.495, _MaskRad);
- //You can easily achieve relative changes in radius for a distance field by modifying the distance result received from the distance function
- float maskRadius = borderRadius - _Border * 0.1;
- //these are the distance fields returned per-pixel to define the shapes we need
- float dist_mask = dCircle(input.uv - 0.5, maskRadius);
- float dist_border = dCircle(input.uv - 0.5 , borderRadius);
- //uncomment the following line to see a simple representation of the distance field
- //return abs(dist_mask);
- //uncomment the following line to see an exaggerated representation of the distance field
- //return abs(sin(dist_mask*6.0*6.28318));
- //once we smoothstep a distance field, we are left with a [ 0 , 1 ] range result that looks like the shape we wanted
- float mask = smoothstep(s, -s, dist_mask);
- float border = smoothstep( s , -s , dist_border);
- //use the larger border circle to define visible area
- result.a = border;
- //'discard'ing this fragment allows us to use 'ZWrite On' with our Alpha Blending
- //this works better with sharper edges
- if (result.a < 0.0001) discard;
- //the actual color gradient
- float4 grad = lerp(_BottomColor, _TopColor, input.uv.y);
- //here we overwrite the color based on our masks, in a specific order from back to front
- result.rgb = lerp(result.rgb, _BorderColor.rgb, border);
- result.rgb = lerp(result.rgb, grad, mask);
- return result;
- }
- ENDCG
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement