使用GL畫線非常簡(jiǎn)單捶枢,原理就是給定畫線的起始位置听盖。代碼如下:
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();
}
效果:
進(jìn)階1:畫有寬度的線捷沸,實(shí)際上是畫矩形塊,需給定矩形的四角的坐標(biāo)值蔓榄,代碼如下:
//進(jìn)階1:屏幕畫有寬度的線(實(shí)際為畫矩形塊)
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 dir_v = Vector3.Cross(Vector3.forward, dir).normalized;
GL.Begin(GL.QUADS);
GL.LoadPixelMatrix();
GL.Vertex(startPos + dir_v * 0.5f*width);
GL.Vertex(endPos + dir_v * 0.5f*width);
GL.Vertex(endPos - dir_v * 0.5f*width);
GL.Vertex(startPos - dir_v * 0.5f*width);
GL.End();
GL.PopMatrix();
}
效果圖:
使用上面的方式畫出來的線在邊緣處很銳利呵恢、鋸齒感很嚴(yán)重房午,分辨率越低越明顯方淤,可以通過為線條添加一張?jiān)谶吘壧帩u變透明的貼圖改善鋸齒效果侣监。
進(jìn)階2:為線條添加貼圖和顏色
先準(zhǔn)備一張貼圖:
寫一個(gè)支持透明貼圖和可修改顏色的shader(該shader只會(huì)使用貼圖的透明通道),如下:
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
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
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);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
return fixed4(_MainColor.rgb,col.a);
}
ENDCG
}
}
}
畫線代碼如下:
//進(jìn)階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));//矩形左上角對(duì)應(yīng)的uv坐標(biāo)
GL.Vertex(startPos + dir_v2 * 0.5f * width);
GL.TexCoord(new Vector2(1, 1));//矩形右上角對(duì)應(yīng)的uv坐標(biāo)
GL.Vertex(endPos + dir_v2 * 0.5f * width);
GL.TexCoord(new Vector2(1, 0));//矩形右下角對(duì)應(yīng)的uv坐標(biāo)
GL.Vertex(endPos - dir_v2 * 0.5f * width);
GL.TexCoord(new Vector2(0, 0));//矩形左下角對(duì)應(yīng)的uv坐標(biāo)
GL.Vertex(startPos - dir_v2 * 0.5f * width);
GL.End();
GL.PopMatrix();
}
效果圖: