Implementação de Efeito de Apagamento por Pintura

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;

Tags: Unity3D Shader texturas ProcessamentoImagem RenderTexture

Publicado em 6-16 17:39 por Thomas