使用Unity GL库绘制图像
使用Unity自带的GL函数库在屏幕上绘制一些特殊的图形,如圆、线条、曲线、矩形等一些图形,并可以给绘制的图形指定相应的纹理。但是,使用GL绘制图形的纹理使用的Shader有一些限制,仅支持如下Shader:
Particles->VertexLit Vlended
Unlit->Color
Unlit->Texture
Unlitr->Transparent
Legacy Shader->Transparent->VertexLit
以下代码展示在屏幕上绘制一张带透明通道纹理:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GLTest : MonoBehaviour {
public Material mat_Transparent;
void OnPostRender () {
DrawQuads(new Rect(0,0,300,300),mat_Transparent);
}
///
/// 绘制一个面片,绘制坐标为屏幕坐标,原点位于屏幕的左下角
///
/// rect.x表示绘制图形的X坐标
/// rect.x表示绘制图形的Y坐标
/// rect.x表示绘制图形的宽度
/// rect.x表示绘制图形的高度
/// 指定一个材质
void DrawQuads(Rect rect,Material mat){
GL.PushMatrix ();
mat.SetPass (0);
GL.LoadOrtho ();
GL.Begin (GL.QUADS);
GL.TexCoord2(0,0);
GL.Vertex3(rect.x/Screen.width,rect.y/Screen.height,0);
GL.TexCoord2(0,1);
GL.Vertex3(rect.x/Screen.width,(rect.y+rect.height)/Screen.height,0);
GL.TexCoord2(1,1);
GL.Vertex3((rect.x+rect.width)/Screen.width,(rect.y+rect.height)/Screen.height,0);
GL.TexCoord2(1,0);
GL.Vertex3((rect.x+rect.width)/Screen.width,rect.y/Screen.height,0);
GL.End();
GL.PopMatrix();
}
}
将脚本挂载到摄像机上,赋予相应的材质。
利用这个函数配合RenderTexture和Shader可以实现一些比如橡皮擦、刮刮卡之类的效果
以下分享一个实现橡皮擦效果的Shader,大致原理就是:将两张纹理叠加采样,一张纹理作为主颜色纹理,一张纹理作为遮罩纹理,通过改变遮罩纹理的Alpha值,取主纹理的RGB颜色,用Mask的A值作为主颜色纹理的A值。
Shader "ScratchCard/Mask" {
Properties {
_MainTex ("Main", 2D) = "white" {}
_MaskTex ("Mask", 2D) = "white" {}
}
SubShader {
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
ZWrite Off
ZTest Off
Blend SrcAlpha OneMinusSrcAlpha
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
sampler2D _MaskTex;
float4 _MainTex_ST;
float4 _MaskTex_ST;
struct a2v
{
float4 position: POSITION;
half4 color: COLOR;
float2 texcoord: TEXCOORD0;
};
struct v2f
{
float4 position: POSITION;
half4 color: COLOR;
float2 texcoord: TEXCOORD0;
};
v2f vert(a2v i)
{
v2f o;
o.position = UnityObjectToClipPos(i.position);
o.color = i.color;
o.texcoord = TRANSFORM_TEX(i.texcoord, _MainTex);
return o;
}
fixed4 frag(v2f v) : COLOR
{
fixed4 main_color = tex2D(_MainTex, v.texcoord);
fixed4 mask_color = tex2D(_MaskTex, v.texcoord);
fixed4 value = fixed4(v.color.r * main_color.r, v.color.g * main_color.g,
v.color.b * main_color.b, v.color.a * main_color.a * (1.0f - mask_color.a));
return value;
}
ENDCG
}
}
}