/Unity-GpuSplines

A faster spline/line renderer using the GPU + Jobs + Burst, focusing mainly on the performance of modifying control points, i.e. it is quite useful as a 2D Rope renderer.

Primary LanguageC#MIT LicenseMIT

Unity-GpuSplines

A faster spline/line renderer for Unity using the GPU, Job Systems + Burst Compiler, focusing mainly on the performance of modifying control points.

This project is inspired by the simonboily/gpuspline.

Features

  • Fast spline/line rendering using the GPU.
  • Extremely low cost of modifying the control points.
    • Provide Jobified APIs to modify points.
    • Useful for 2D Rope rendering, which is why I created this project:)
  • Support automatically batching of multiple splines/lines with the same properties. (line type, color, etc.)
  • Support for the following spline types:
    • Linear
    • Catmull-Rom
  • Support for the following drawing modes:
    • Graphics.DrawMesh
    • Graphics.DrawProcedural
      • DrawProcedural is faster than DrawMesh since it does not need to prepare the mesh vertices in the CPU, but it is only available on platforms that support compute buffers.

Demo

Jobified modifying points

2024-03-01.15-06-38.mp4

Non-jobified adding points, changing color, modifying points

2024-03-01.15-07-16.mp4

Rope simulation (Jobified)

  • Control points: ~21890
  • Splines: ~2189
  • ~470 fps in Bionic Bay
2024-03-01.17-05-28.mp4

Installation

  • Package Manager -> Add package from git URL https://github.com/qwe321qwe321qwe321/Unity-GpuSplines.git?path=Assets/GpuSplines.
  • Or download the repository and copy the Assets/GpuSplines folder to your project.

Dependencies

Getting Started

Nah... I will write it later. You can refer to the Assets/GpuSplines.Sample/Samples.unity scene for now.

Environment

  • Unity 2019.4.40f1
  • .NET 4.x
  • Burst 1.6.6
  • Jobs 0.2.10-preview.13

I did not test on other versions, but it should work on the versions that support Burst and Jobs.

How I achieved the low cost of modifying control points?

For the typical implement of line renderers, they need to update the mesh vertices on the CPU when the control points are modified. This is a high cost operation, especially when the number of control points is large.

I learned a trick from simonboily/gpuspline, which is to keep the mesh itself unchanged and only update the control points in the shader by maintaining a vector array(the maximum size is 1000). Then the shader will calculate the correct position of the vertices of the spline based on that vector array. This is much much cheaper than the original method, and it is the key to the low cost of modifying control points. (This is very likely how the SkinnedMeshRenderer does -- a fixed mesh with changing bones)

After that, I improved the performance of modifying control points by:

  • Constructing the Job-friendly structures for the whole Gpu spline system and provided the Jobified APIs to modify the control points to maximize the benefit from the Unity Job System and Burst Compiler.
  • Optimizing the vertices data and giving an Graphics.DrawProcedural way to draw.
  • Using the SharedArray to reduce the cost of converting between NativeArray and managed array.