先上shader代码:
Shader "Toturial/Circle"
{
Properties
{
_R("_R",Range(0,1000)) = 6
_X("_X",Range(0,1000)) =100
_Y("_Y",Range(0,1000)) =100
}
SubShader
{
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
float _R;
float _X;
float _Y;
struct a2v
{
float4 vertex : POSITION;
};
struct v2f
{
float4 pos : SV_POSITION;
};
v2f vert(a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag(v2f i) : SV_TARGET
{
float r2 = (i.pos.x - _X) * (i.pos.x - _X)+ (i.pos.y - _Y) * (i.pos.y - _Y);
if (r2 <= _R *_R)return fixed4(1, 1, 1, 1);
else return fixed4(0, 0, 1, 1);
}
ENDCG
}
}
}
注意:要将材质附着在的平面填满相机的视锥体。
*.总结
其实也不是很难,但是需要理解顶点着色中传入的是模型空间坐标, 输出的是裁剪空间坐标,而片元着色中的输入是屏幕空间坐标,输出的是像素点的颜色。
其中屏幕空间坐标:
- x[0, ScreenPixelWidth]:屏幕x轴坐标。
- y[0, ScreenPixelWidth]:屏幕y轴坐标。
可参考:Unity Shader 各个空间坐标的获取方式及xyzw含义 - 知乎
容易混淆的Clip Space vs NDC,透视除法 - 知乎
最后的运行效果(可通过_R、_X、_Y调整圆的半径和位置):