Dynamically Paint A Texture - I'm halfway but stuck!

Hi Everyone,

I’m working on a thing where I have an object that paints surfaces.
The problem is I’m clueless with shaders - my code currently has a base texture and a paint texture.

  • That configuration works fine.

But(!)
I would like to have a totally transparent object (ie no initial/base texture), that only shows the dynamic painted texture.

any ideas? (my shader code is below)

Thank you so much!

Images to better explain:


my shader:

Shader "CA/Paint Surface" {

    Properties{
        _MainTex("Main Texture", 2D) = "white" {}
    _PaintMap("PaintMap", 2D) = "white" {} // texture to paint on
    }

        SubShader{
        Tags{ "RenderType" = "Opaque" "LightMode" = "ForwardBase" }

        Pass{
        Lighting Off

        CGPROGRAM

#pragma vertex vert
#pragma fragment frag


#include "UnityCG.cginc"
#include "AutoLight.cginc"

    struct v2f {
        float4 pos : SV_POSITION;
        float2 uv0 : TEXCOORD0;
        float2 uv1 : TEXCOORD1;

    };

    struct appdata {
        float4 vertex : POSITION;
        float2 texcoord : TEXCOORD0;
        float2 texcoord1 : TEXCOORD1;

    };

    sampler2D _PaintMap;
    sampler2D _MainTex;
    float4 _MainTex_ST;
    v2f vert(appdata v) {
        v2f o;

        o.pos = UnityObjectToClipPos(v.vertex);
        o.uv0 = TRANSFORM_TEX(v.texcoord, _MainTex);

        o.uv1 = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;// lightmap uvs

        return o;
    }

    half4 frag(v2f o) : COLOR{
        half4 main_color = tex2D(_MainTex, o.uv0); // main texture
        half4 paint = (tex2D(_PaintMap, o.uv1)); // painted on texture
        main_color *= paint;

        return main_color;
    }
        ENDCG
    }
    }
}

You need a way to store the opacity of your painted texture : probably use the alpha channel.
Then you have 2 solutions :

  • Alpha clip : In the fragment shader, use clip to not render the pixels where the alpha of the paint texture is < a certain threshold.
  • Alpha blend : set the proper render queue and blending value for your object to make the plane semi-transparent

Both are nicely explained here : Unity - Manual: ShaderLab command: Blend

Thank you for the pointers @Remy_Unity I’ve got it all fixed up now!

Hi John, I’m just getting started on a project with a similar use case. I’m also a shader newbie, would you mind expanding on the solution you used a little bit? Specifically, how did you tie the position (I assume) of the paintbrush object to the paintmap coordinates? Many thanks!

Hi!
My starting point was this excellent post:

This is excellent, thank you! And thanks for the quick reply.