使用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实现屏幕画线】效果:
文章图片
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 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();
}
效果图:
文章图片
02.PNG
推荐阅读
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询
- python学习之|python学习之 实现QQ自动发送消息
- 孩子不是实现父母欲望的工具——林哈夫
- opencv|opencv C++模板匹配的简单实现
- Node.js中readline模块实现终端输入