使用GL实现屏幕画线

使用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(); }

【使用GL实现屏幕画线】效果:

使用GL实现屏幕画线
文章图片
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(); }

效果图:

使用GL实现屏幕画线
文章图片
01.PNG 使用上面的方式画出来的线在边缘处很锐利、锯齿感很严重,分辨率越低越明显,可以通过为线条添加一张在边缘处渐变透明的贴图改善锯齿效果。
进阶2:为线条添加贴图和颜色
先准备一张贴图:

使用GL实现屏幕画线
文章图片
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 100zwrite off blend srcalpha oneminussrcalphaPass { 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(); }



效果图: 使用GL实现屏幕画线
文章图片
02.PNG

    推荐阅读