Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

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

Discussion in 'Shaders' started by JohnEvelyn, Apr 20, 2018.

  1. JohnEvelyn

    JohnEvelyn

    Joined:
    Oct 28, 2016
    Posts:
    9
    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:

    paintablesurface01.png
    paintablesurface02.png

    my shader:

    Code (CSharp):
    1.  
    2.  
    3. Shader "CA/Paint Surface" {
    4.  
    5.     Properties{
    6.         _MainTex("Main Texture", 2D) = "white" {}
    7.     _PaintMap("PaintMap", 2D) = "white" {} // texture to paint on
    8.     }
    9.  
    10.         SubShader{
    11.         Tags{ "RenderType" = "Opaque" "LightMode" = "ForwardBase" }
    12.  
    13.         Pass{
    14.         Lighting Off
    15.  
    16.         CGPROGRAM
    17.  
    18. #pragma vertex vert
    19. #pragma fragment frag
    20.  
    21.  
    22. #include "UnityCG.cginc"
    23. #include "AutoLight.cginc"
    24.  
    25.     struct v2f {
    26.         float4 pos : SV_POSITION;
    27.         float2 uv0 : TEXCOORD0;
    28.         float2 uv1 : TEXCOORD1;
    29.  
    30.     };
    31.  
    32.     struct appdata {
    33.         float4 vertex : POSITION;
    34.         float2 texcoord : TEXCOORD0;
    35.         float2 texcoord1 : TEXCOORD1;
    36.  
    37.     };
    38.  
    39.     sampler2D _PaintMap;
    40.     sampler2D _MainTex;
    41.     float4 _MainTex_ST;
    42.     v2f vert(appdata v) {
    43.         v2f o;
    44.  
    45.         o.pos = UnityObjectToClipPos(v.vertex);
    46.         o.uv0 = TRANSFORM_TEX(v.texcoord, _MainTex);
    47.  
    48.         o.uv1 = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;// lightmap uvs
    49.  
    50.         return o;
    51.     }
    52.  
    53.     half4 frag(v2f o) : COLOR{
    54.         half4 main_color = tex2D(_MainTex, o.uv0); // main texture
    55.         half4 paint = (tex2D(_PaintMap, o.uv1)); // painted on texture
    56.         main_color *= paint;
    57.  
    58.         return main_color;
    59.     }
    60.         ENDCG
    61.     }
    62.     }
    63. }
     
  2. Remy_Unity

    Remy_Unity

    Unity Technologies

    Joined:
    Oct 3, 2017
    Posts:
    635
    You need a way to store the opacity of your painted texture : probably use the alpha channel.
    Then you have 2 solutions :
    1. Alpha clip : In the fragment shader, use http://developer.download.nvidia.com/cg/clip.html to not render the pixels where the alpha of the paint texture is < a certain threshold.
    2. Alpha blend : set the proper render queue and blending value for your object to make the plane semi-transparent
    Both are nicely explained here : https://docs.unity3d.com/Manual/SL-Blend.html
     
  3. JohnEvelyn

    JohnEvelyn

    Joined:
    Oct 28, 2016
    Posts:
    9
    Thank you for the pointers @Remy_Unity I've got it all fixed up now!
     
  4. dmarfurt

    dmarfurt

    Joined:
    Apr 28, 2013
    Posts:
    9
    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!
     
  5. JohnEvelyn

    JohnEvelyn

    Joined:
    Oct 28, 2016
    Posts:
    9
  6. dmarfurt

    dmarfurt

    Joined:
    Apr 28, 2013
    Posts:
    9