Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Screen Space GPU Painter

Discussion in 'Shaders' started by Przemyslaw_Zaworski, Sep 8, 2017.

  1. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    327
    For educational purposes, I prepared minimal example of texture painter. Main calculations are processing in pixel shader, so this solution is faster than my previous painter based on method Texture2D.SetPixel.

    Source:
    https://github.com/przemyslawzaworski/Unity3D-CG-programming/blob/master/paint.shader
    https://github.com/przemyslawzaworski/Unity3D-CG-programming/blob/master/paint.cs

    Code (CSharp):
    1. //Assign paint script to Main Camera. Then set material with paint.shader
    2. using UnityEngine;
    3.  
    4. [ExecuteInEditMode]
    5. public class paint : MonoBehaviour
    6. {
    7.     public Material material;
    8.     Vector4 iMouse;
    9.  
    10.     void Update ()
    11.     {
    12.         if (Input.GetMouseButton(0))
    13.         {
    14.             iMouse = new Vector4 (Input.mousePosition.x/Screen.width,1.0f-Input.mousePosition.y/Screen.height,-1.0f,-1.0f) ;
    15.             material.SetVector("iMouse",iMouse);
    16.         }
    17.     }
    18.    
    19.     void OnRenderImage (RenderTexture source, RenderTexture destination)
    20.     {
    21.         Graphics.Blit (source, destination, material);
    22.     }
    23. }
    Code (CSharp):
    1. Shader "Paint"
    2. {
    3.     Properties
    4.     {
    5.         [HideInInspector]
    6.         iMouse("iMouse",Vector) = (-1.0,-1.0,0.0,0.0)
    7.         brush("Brush Color",Color) = (1,1,1,1)
    8.         size("Brush Size",Range(0.001,0.050)) = 0.005
    9.         [KeywordEnum(Circle,Circle2,Rect)] shapes("Brush shapes", Float) = 0
    10.        
    11.     }
    12.     Subshader
    13.     {
    14.         Pass
    15.         {
    16.             CGPROGRAM
    17.             #pragma vertex vertex_shader
    18.             #pragma fragment pixel_shader
    19.             #pragma target 4.0
    20.            
    21.             float4 iMouse;
    22.             float4 brush;
    23.             float size;
    24.             float shapes;
    25.            
    26.             float4 vertex_shader (float4 vertex:POSITION):SV_POSITION
    27.             {
    28.                 return UnityObjectToClipPos (vertex);
    29.             }
    30.  
    31.             float4 pixel_shader (float4 vertex:SV_POSITION):SV_TARGET
    32.             {
    33.                 float2 uv=vertex.xy/_ScreenParams.xy;
    34.                 switch(shapes)
    35.                 {
    36.                     case 0:
    37.                         {
    38.                             float circle=length(iMouse.xy-uv.xy);
    39.                             if (circle>size) discard;
    40.                             return brush;
    41.                         }
    42.                     case 1:
    43.                         {
    44.                             float circle=length(iMouse.xy-uv.xy);
    45.                             circle = smoothstep(circle,size-0.002,size);
    46.                             if (circle>size) discard;
    47.                             return brush;
    48.                         }
    49.                     case 2:
    50.                         {
    51.                             float2 rect = abs(iMouse.xy-uv.xy);
    52.                             if (any(rect>size)) discard;
    53.                             return brush;
    54.                         }                      
    55.                     default:
    56.                             return float4(0,0,0,1);
    57.                 }
    58.  
    59.             }
    60.             ENDCG
    61.         }
    62.     }
    63. }