Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Compute Shader for line drawing

Discussion in 'Shaders' started by LazyOnion, Dec 18, 2018.

  1. LazyOnion

    LazyOnion

    Joined:
    Mar 6, 2018
    Posts:
    15
    So I am trying to learn compute shaders and I started creating some simple ones that came to mind, one of them being using bresenham's algorithm to draw a line between two points, however I m stuck to how you face these problems.

    Do you segment the problem depending on the part of the line? or check if each pixel is under the line?
     
  2. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    171
    For what purpose do you want to use Bresenham's algorithm ?
    To make a custom rasterizer, or just to draw a single line in render texture ?
     
  3. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    171
    To start learn compute shaders you can study following example.
    Texture coordinates are in range [0-1].
    Line is drawn from first point (0.3,0.1) to second point (0.8,0.5).
    Attach script to quad and press Play.

    upload_2018-12-18_20-59-21.png

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class Line : MonoBehaviour
    4. {
    5.     public ComputeShader CS;
    6.  
    7.     void Start()
    8.     {
    9.         RenderTexture RT = new RenderTexture(1024, 1024, 0);
    10.         RT.enableRandomWrite = true;
    11.         RT.Create();
    12.         CS.SetTexture(0, "surface", RT);  
    13.         CS.Dispatch(0, RT.width / 8, RT.height / 8, 1);
    14.         GetComponent<Renderer>().material.mainTexture = RT;      
    15.     }
    16. }
    Code (CSharp):
    1. #pragma kernel CSMain
    2. RWTexture2D<float4> surface;
    3.  
    4. float Line( float2 p, float2 a, float2 b )
    5. {
    6.     float2 pa = p-a, ba = b-a;
    7.     float h = saturate( dot(pa,ba)/dot(ba,ba) );
    8.     float2 d = pa - ba * h;
    9.     return dot(d,d);
    10. }
    11.  
    12. [numthreads(8,8,1)]
    13. void CSMain (uint2 id : SV_DispatchThreadID)
    14. {
    15.     float2 uv = float2 ((float)id.x/1024, (float)id.y/1024);
    16.     float k = Line(uv,float2(0.3,0.1),float2(0.8,0.5));  
    17.     float thickness = 0.00001;
    18.     surface[id.xy] = lerp( float4(1,1,1,1), float4(0,0,0,1), smoothstep(0.0, thickness, k) );
    19. }
    20.  
    upload_2018-12-18_20-59-43.png
     
    Popiolek and LazyOnion like this.
  4. LazyOnion

    LazyOnion

    Joined:
    Mar 6, 2018
    Posts:
    15
    Thanks a lot, I am trying to linedraw a single line (or bezier eventually) in render texture, and I wasn't sure from where to start.

    I have a draw texture shader but it is using too many drawcalls and I wanted to reduce that by passing em to a compute shader to batch calculate the shape.