Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/Antoshidza/NSprites

Unity DOTS Sprite Rendering Package
https://github.com/Antoshidza/NSprites

2d dots ecs entities entity-component-system package performance rendering sprites unity unity-ecs unity3d

Last synced: 10 days ago
JSON representation

Unity DOTS Sprite Rendering Package

Lists

README

        

# NSprites - Unity DOTS Sprite Rendering Package
This framework provides sprite rendering system compatible with Entities package (unity ECS). [Changelog](https://github.com/Antoshidza/NSprites/wiki/Changelog)

Basically it sync whatever entity component you want with GPU data to perform instanced rendering. As a result all entities with same Material can be rendered with single drawcall.

## Features
* Using power of :boom:**DOTS**:boom: + instancing to render numerous of sprites
* Using any public to you per-entity blittable component as shader instanced property
* Data update strategies to avoid unnecessary CPU load
* Edit-time rendering (subscene only)

## Basic API
**For more detailed information please read [project's wiki](https://github.com/Antoshidza/NSprites/wiki)** :blue_book:
```csharp
// registrate components as properties at assembly level anywhere in project
[assembly: InstancedPropertyComponent(typeof(WorldPosition2D), "_pos2D")]
[assembly: InstancedPropertyComponent(typeof(SpriteColor), "_color")]
```
```csharp
// registrate render with ID, Material, capacity data and set of properties
if (!SystemAPI.ManagedAPI.TryGetSingleton(out var renderArchetypeStorage))
return;
// don't registrate same renderID
renderArchetypeStorage.RegisterRender
(
renderID,
material, // material with [Enable GPU Instancing] enabled and shader supporting instancing
bounds // bounds in which sprites will be visible. For example new Bounds(Vector3.zero, Vector3.one * float.MaxValue)
null, // override for MaterialPropertyBlock if needed
128, // initial ComputeBuffers capacity
128, // minimal capacity step for ComputeBuffers
"_pos2D", // world 2D position property
"_color" // color property
);
```
```csharp
// initialize sprite entity with all needed components for rendering
entityManager.AddSpriteRenderComponents(spriteEntity, renderID);
// WorldPosition2D and SpriteColor are example client's components
entityManager.AddComponentData(spriteEntity, new WorldPosition2D { Value = /*your value here*/ });
entityManager.AddComponentData(spriteEntity, new SpriteColor { Value = Color.White });

// or from baker
private class Baker : Baker
{
public override void Bake(SpriteAuthoring authoring)
{
AddComponent(new WorldPosition2D { Value = new float2(authoring.transform.position.x, authoring.transform.position.y) });
AddComponent(new SpriteColor { Value = Color.White });
this.AddSpriteComponents(authoring.RenderID); // Render ID is client defined unique per-render archetype int. You can define it manually or for example use Material's instance ID or whatever else.
}
}
```
Also shader you're using should be compatible with instancing. Check my [example shader gist](https://gist.github.com/Antoshidza/387bf4a3a3efd62c8ca4267e800ad3bc). The main idea is to use `StructuredBuffer _propertyName`. Though it is possible to use instanced properties with ShaderGraph, so you may try your option. For local example shader main part can look like:
```hlsl
// ...
#if defined(UNITY_PROCEDURAL_INSTANCING_ENABLED)
StructuredBuffer _propertyPointers;
StructuredBuffer _color;
#endif
// ...
Varyings UnlitVertex(Attributes attributes, uint instanceID : SV_InstanceID)
{
// ...
#if defined(UNITY_PROCEDURAL_INSTANCING_ENABLED)
int propPointer = _propertyPointers[instanceID]; // this is internal package property to point right data during component sync
float4 color = _color[propPointer];
#else
//fallback if somehow instancing failed
float4 color = float4(1,1,1,1);
#endif
// ...
}
```

## How it works
[`SpriteRenderingSystem`](https://github.com/Antoshidza/NSprites/blob/main/Rendering/Systems/SpriteRenderingSystem.cs) sync registered entity components with [ComputeBuffers](https://docs.unity3d.com/ScriptReference/ComputeBuffer.html) to send data to GPU and then renders entities with [`Graphics.DrawMeshInstancedProcedural`](https://docs.unity3d.com/ScriptReference/Graphics.DrawMeshInstancedProcedural.html). System also controls how ComputeBuffers reallocates if capacity exceeds. Sprites are simple entities with no limits of what components you use.

## Check [Foundation](https://github.com/Antoshidza/NSprites-Foundation)
NSprites doesn't provide anything except rendering and managing data for it. Though you can implement anything you want on top of it. Also I want to share some foundation project where you can find examples and maybe even useful tools to work with this package. Foundation provides such things as sorting / culling / animation / 2D transforms / basic data authoring and registration.

## Check sample project - [Age of Sprites](https://github.com/Antoshidza/Age-of-Sprites)
This sample project covers basics of rendering with NSprites. Use it to get a main idea of how stuff can be implemented but not as production-ready solutions.

![RomeGIf](https://user-images.githubusercontent.com/19982288/204523105-7cabb122-954c-4fb0-97bc-becb27d2d2b9.gif)

## Installation
### Requirements
* Unity 2022.2+
* Entities v1.0.0-pre.65+

### [Compatibility](https://github.com/Antoshidza/NSprites/wiki/Compatibility)
There is few things we should care when talking about using NSprites in real projects. Since this package uses **GPU instancing**
and `ComputeBuffer` on CPU side with `StructuredBuffer` on GPU side (in shader) to send sprites data, we need platform and Graphics API support
this two.

| **Graphics API** | **Description** |
|:-------------------------------------|:------------------------------------------------------------|
| Direct3D11 | :warning: partially supported |
| Direct3D12 | :white_check_mark: supported |
| Vulkan | :white_check_mark: supported |
| OpenGLCore | :warning: partially supported |
| OpenGLES3 | :warning: partially supported |

| **Platform** | **Description** |
|:-------------|:------------------------------------------------------------|
| PC | :white_check_mark: supported |
| WebGL | :no_entry: unsupported |
| Android | :grey_question: not fully checked |
| iOS | :question: not checked |

### [Install via Package Manager](https://docs.unity3d.com/2021.3/Documentation/Manual/upm-ui-giturl.html)
* Window -> Package Manager -> + button -> Add package from git url
* Paste `https://github.com/Antoshidza/NSprites.git`
### Install via git submodule
* `cd` to your project's `/Packages` folder
* git submodule https://github.com/Antoshidza/NSprites.git

## Support :+1: Contribute :computer: Contact :speech_balloon:
I wish this project will be helpful for any ECS early adopters! So feel free to send bug reports / pull requests, start discussions / critique, those all are **highly** appreciated!
You can contact with my [discord account](https://www.discordapp.com/users/219868910223228929) / join [discord server](https://discord.gg/rvxrHEFx8n)!
Also there is a [thread](https://forum.unity.com/threads/1-0-3-nsprites-sprite-rendering-package.1367463/) on unity dots forum!

Preferred way to send support: [BOOSTY](https://boosty.to/tonymax/donate)

[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/antoshidzamax)