Skip to content

Instantly share code, notes, and snippets.

@spacedogpatrol
Last active August 29, 2015 14:11
Show Gist options
  • Save spacedogpatrol/ecf4b6ce6fe3c0f05aea to your computer and use it in GitHub Desktop.
Save spacedogpatrol/ecf4b6ce6fe3c0f05aea to your computer and use it in GitHub Desktop.
Rounded Rectangle
Shader "Custom/Rounded Rectangle"
{
Properties
{
_MainTex ("Texture", 2D) = ""
_ColorAndBorderRadius ("Color And Border Radius", Vector) = (0.8, 0.752, 0.701, 0.1)
}
SubShader
{
Tags { "Queue" = "Geometry" "RenderType" = "Opaque" "IgnoreProjector" = "True" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
// Юниформ-переменные.
uniform fixed4 _ColorAndBorderRadius;
struct appdata_t
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
half2 texcoord : TEXCOORD0;
};
sampler2D _MainTex;
float4 _MainTex_ST;
//----------------------------------------Вершинный шейдер----------------------------------------//
v2f vert(appdata_t v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
//---------------------------------------Пиксельный шейдер----------------------------------------//
fixed4 frag(v2f input) : SV_Target
{
float border = 1 - _ColorAndBorderRadius.w;
// Вернуть цвет для большей части пикселей прямоугольника.
// Это условие будет ложным только для четырёх квадратов размером _ColorAndBorderRadius.w × _ColorAndBorderRadius.w,
// которые расположены в углах (где будет происходить скругление).
if(input.texcoord.x >= _ColorAndBorderRadius.w && input.texcoord.x <= border ||
input.texcoord.y >= _ColorAndBorderRadius.w && input.texcoord.y <= border)
{
return _ColorAndBorderRadius;
}
fixed2 coords = input.texcoord.xy;
// Пересчитать координаты оставшихся пикселей (которые принадлежат четырём квадратам в углах) так,
// чтобы они лежали в пределах [0; 2 × _ColorAndBorderRadius.w].
// Этот пересчёт эквивалентен тому, что мы взяли четыре квадрата из углов и совместили их в один,
// размером (2 × _ColorAndBorderRadius.w) × (2 × _ColorAndBorderRadius.w).
if(input.texcoord.x > border)
{
coords.x = 2 * _ColorAndBorderRadius.w + input.texcoord.x - 1;
}
if(input.texcoord.y > border)
{
coords.y = 2 * _ColorAndBorderRadius.w + input.texcoord.y - 1;
}
coords -= _ColorAndBorderRadius.w;
// Вернуть цвет пикселей, которые принадлежат области скругления.
if(coords.x * coords.x + coords.y * coords.y < _ColorAndBorderRadius.w * _ColorAndBorderRadius.w)
{
return _ColorAndBorderRadius;
}
// Отбросить пиксели, которые находятся за областью скругления.
discard;
// Эта строчка нужна для того, чтобы шейдер скомпилировался в Windows-редакторе.
// По мнению компилятора, "не все пути возвращают значение"; discard строчкой выше ему не достаточно.
return _ColorAndBorderRadius;
}
ENDCG
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment