O efeito de apagamento por pintura requer uma textura intermdeiária como máscara e dois shaders para processsamento.
Shader de Máscara:
Shader "Unlit/ShaderMascara"
{
Properties
{
_TexPrincipal ("Textura", 2D) = "branco" {}
_TexDecalque("Textura Decalque", 2D) = "branco" {}
_Deslocamento("Deslocamento", vector) = (0,0,0,0)
}
SubShader
{
Tags { "RenderType"="Opaque" }
Pass
{
CGPROGRAM
#pragma vertex vertice
#pragma fragment fragmento
#include "UnityCG.cginc"
struct DadosVert
{
float4 vertice : POSITION;
float2 uv : TEXCOORD0;
};
struct SaidaVert
{
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
};
sampler2D _TexPrincipal;
sampler2D _TexDecalque;
float4 _Deslocamento;
SaidaVert vertice (DadosVert v)
{
SaidaVert o;
o.pos = UnityObjectToClipPos(v.vertice);
o.uv = v.uv;
return o;
}
fixed4 fragmento (SaidaVert i) : SV_Target
{
fixed4 base = tex2D(_TexPrincipal, i.uv);
float sinal = (_ProjectionParams.x > 0) ? 1 : -1;
half2 novoUV = float2(1, sinal) * (i.uv - 0.5) / _Deslocamento.ww + 0.5;
fixed4 mascara = tex2D(_TexDecalque, novoUV + _Deslocamento.xy);
return base + mascara;
}
ENDCG
}
}
}
Shader de Meslcagem:
Shader "Unlit/ShaderCombinacao"
{
Properties
{
_TexFundo ("Textura Fundo", 2D) = "branco" {}
_TexFrente("Textura Frente", 2D) = "branco" {}
_TexMascara("Máscara", 2D) = "branco" {}
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vertice
#pragma fragment fragmento
#include "UnityCG.cginc"
struct DadosVert
{
float4 vertice : POSITION;
float2 uv : TEXCOORD0;
};
struct SaidaVert
{
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
};
sampler2D _TexFundo;
sampler2D _TexFrente;
sampler2D _TexMascara;
SaidaVert vertice (DadosVert v)
{
SaidaVert o;
o.pos = UnityObjectToClipPos(v.vertice);
o.uv = v.uv;
return o;
}
fixed4 fragmento (SaidaVert i) : SV_Target
{
fixed4 fundo = tex2D(_TexFundo, i.uv);
fixed4 frente = tex2D(_TexFrente, i.uv);
float sinal = (_ProjectionParams.x > 0) ? 1 : -1;
half2 novoUV = float2(1, sinal) * (i.uv - 0.5) + 0.5;
fixed4 mascara = tex2D(_TexMascara, novoUV);
return lerp(fundo, frente, mascara.a);
}
ENDCG
}
}
}
Código Principal (C#):
Vector4 pontoVisao = Camera.main.WorldToViewportPoint(pontoMapeamento.position);
pontoVisao -= new Vector4(0.5f, 0.5f, 0, 0);
pontoVisao.w = pontoMapeamento.localScale.x;
if (texturaMascara == null)
{
texturaMascara = new Texture2D(origem.width, origem.height, TextureFormat.RGBA32, false);
for (int x = 0; x < texturaMascara.width; x++)
for (int y = 0; y < texturaMascara.height; y++)
texturaMascara.SetPixel(x, y, Color.clear);
texturaMascara.Apply();
}
materialMascara.SetTexture("_TexPrincipal", texturaMascara);
materialMascara.SetVector("_Deslocamento", pontoVisao);
Graphics.Blit(texturaMascara, renderTemp, materialMascara);
materialCombinacao.SetTexture("_TexFundo", origem);
materialCombinacao.SetTexture("_TexFrente", tempRT);
materialCombinacao.SetTexture("_TexMascara", renderTemp);
Graphics.Blit(origem, destino, materialCombinacao);
RenderTexture ativoAnterior = RenderTexture.active;
RenderTexture.active = renderTemp;
texturaMascara.ReadPixels(new Rect(0, 0, texturaMascara.width, texturaMascara.height), 0, 0);
texturaMascara.Apply();
RenderTexture.active = ativoAnterior;