使用GL画线非常简单,原理就是给定画线的起始位置。代码如下:
public Material _mat;
private void OnGUI()
{
DrawLine(new Vector2(0, 0), new Vector2(Screen.width, Screen.height));
}
//屏幕画线(宽度为1像素,无法修改)
void DrawLine(Vector2 startPos, Vector2 endPos)
{
GL.PushMatrix();
if (!_mat)
{
_mat = new Material(Shader.Find("Unlit/Color"));
}
_mat.SetPass(0);
GL.LoadPixelMatrix();//按照像素画线
GL.Begin(GL.LINES);
GL.Vertex(startPos);
GL.Vertex(endPos);
GL.End();
GL.PopMatrix();
}
效果:
03.PNG
进阶1:画有宽度的线,实际上是画矩形块,需给定矩形的四角的坐标值,代码如下:
//进阶1:屏幕画有宽度的线(实际为画矩形块)
void DrawLineWidth(Vector2 startPos, Vector2 endPos, float width)
{
GL.PushMatrix();
if (!_mat)
{
_mat = new Material(Shader.Find("Unlit/Color"));
}
_mat.SetPass(0);
Vector2 dir = endPos - startPos;
Vector3 dir3 = new Vector3(dir.x, dir.y, 0);
Vector3 dir_v = Vector3.Cross(Vector3.forward, dir3);
Vector2 dir_v2 = new Vector2(dir_v.x, dir_v.y).normalized;
GL.Begin(GL.QUADS);
GL.LoadPixelMatrix();
GL.Vertex(startPos + dir_v2 * 0.5f*width);
GL.Vertex(endPos + dir_v2 * 0.5f*width);
GL.Vertex(endPos - dir_v2 * 0.5f*width);
GL.Vertex(startPos - dir_v2 * 0.5f*width);
GL.End();
GL.PopMatrix();
}
效果图:
01.PNG
使用上面的方式画出来的线在边缘处很锐利、锯齿感很严重,分辨率越低越明显,可以通过为线条添加一张在边缘处渐变透明的贴图改善锯齿效果。
进阶2:为线条添加贴图和颜色
先准备一张贴图:
Line.png
写一个支持透明贴图和可修改颜色的shader(该shader只会使用贴图的透明通道),如下:
Shader "Unlit/Line"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_MainColor("MainColor",color)=(1,1,1,1)
}
SubShader
{
Tags { "RenderType"="Transparent" "Queue"="Transparent"}
LOD 100
zwrite off
blend srcalpha oneminussrcalpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _MainColor;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return fixed4(_MainColor.rgb,col.a);
}
ENDCG
}
}
}
画线代码如下:
//进阶2:画有宽度的线并为其赋予颜色和贴图
void DrawLineWidthTex(Vector2 startPos, Vector2 endPos, float width, Color color)
{
GL.PushMatrix();
if (!_mat)
{
_mat = new Material(Shader.Find("Unlit/Line"));
}
_mat.SetPass(0);
_mat.SetColor("_MainColor", color);
Vector2 dir = endPos - startPos;
Vector3 dir3 = new Vector3(dir.x, dir.y, 0);
Vector3 dir_v = Vector3.Cross(Vector3.forward, dir3);
Vector2 dir_v2 = new Vector2(dir_v.x, dir_v.y).normalized;
GL.Begin(GL.QUADS);
GL.LoadPixelMatrix();
GL.TexCoord(new Vector2(0, 1));//矩形左上角对应的uv坐标
GL.Vertex(startPos + dir_v2 * 0.5f * width);
GL.TexCoord(new Vector2(1, 1));//矩形右上角对应的uv坐标
GL.Vertex(endPos + dir_v2 * 0.5f * width);
GL.TexCoord(new Vector2(1, 0));//矩形右下角对应的uv坐标
GL.Vertex(endPos - dir_v2 * 0.5f * width);
GL.TexCoord(new Vector2(0, 0));//矩形左下角对应的uv坐标
GL.Vertex(startPos - dir_v2 * 0.5f * width);
GL.End();
GL.PopMatrix();
}
效果图:
02.PNG
网友评论