4

I'm trying to create small paint app that uses RenderTexture for painting. My goal is to paint "Brush" texture with the color and alpha on the "Draw" RenderTexture (whole texture has the color (1, 1, 1, 0). I have written a shader for that, but it blends brush quads with black borders:

example

I'm using next shader for painting:

Shader "MyPaint/BrushShader"
{
    Properties
    {
        _BrushTex ("Brush", 2D) = "white" {}
        _DrawTex ("Draw Tex", 2D) = "white" {}
        _Color ("Main Color", Color) = (1, 1, 1, 1)
    }

    SubShader
    {
        Tags {
            "Queue"="Transparent"
            "IgnoreProjector"="True"
             "RenderType"="Transparent"
            }
        Cull Off
        Lighting Off
        ZWrite Off
        ZTest Always
        Pass
        {
            CGPROGRAM

            #include "UnityCG.cginc"
            #pragma vertex vert
            #pragma fragment frag
              
            sampler2D _BrushTex;
            half4 _BrushTex_ST;
            sampler2D _DrawTex;
            half4 _DrawTex_ST;
            float4 _Color;

            struct appdata
            {
                float4 vertex : POSITION;
                float4 color : COLOR;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float4 color : COLOR;
                float2 uv : TEXCOORD0;
                float4 screenPos : TEXCOORD1;
            };

            v2f vert(appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.screenPos = o.vertex;
                o.uv = v.uv;
                o.color = v.color;
                return o;
            }
      
            float4 frag (v2f i) : SV_Target
            {
                float4 brush = tex2D(_BrushTex, i.uv) * _Color;
                float2 grabTexcoord = i.screenPos.xy / i.screenPos.w;
                grabTexcoord.x = (grabTexcoord.x + 1.0) * 0.5;
                grabTexcoord.y = (grabTexcoord.y + 1.0) * 0.5;

            #if UNITY_UV_STARTS_AT_TOP
                grabTexcoord.y = 1.0 - grabTexcoord.y;
            #endif
              
                float4 draw = tex2D(_DrawTex, grabTexcoord);
                float4 color = draw * (1.0f - brush.a) + brush * brush.a;
                return color;
            }
            ENDCG
        }
    }
}

I create a Mesh and render it into "Draw" RenderTexture using CommandBuffer with RenderTargetIdentifier and Material.

I don't understand how to avoid that black borders of the brush. I'm using ARGB32 RenderTextures without depth and mip-maps, brush texture:

brush

My goal is to paint like in Photoshop, with constant color, that even works with alpha:

photoshop

If anyone can give me an advice on how to properly blend a RenderTexture I would greatly appreciate it!

  • Is the border really black or is it only transparent meaning you see the background texture there? – derHugo Jul 24 '21 at 22:31

0 Answers0