gfx2d: complete redesign of Sprite2D #997
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is a complete redesign of Sprite2D, the low-level ECS module for sprite rendering.
Features
Engine
module now manages render passes and frame submission; which means Sprite2D can now be used with other ECS modules that render onto the screen too.Performance
On a Macbook M1, with sprites that are independently CPU animated each frame (single texture/shader), we see gains of +60% in release builds:
Design
GPU memory synchronization
We retain a set of GPU storage buffers per sprite batch (which are used to render multiple sprites per draw call); the goal is to have the buffers ready to go at rendering time with no need to synchronize ECS data -> GPU during rendering a frame
The way Sprite2D becomes aware of the fact that ECS data has changed is.. you tell it your batch of sprites changed:
Pipeline creation
When you wish to render sprites, you're going to want to specify your own texture. Sometimes you might want to specify multiple textures, or your use your own shader program. For this reason, we have an explicit pipeline creation step where you specify the shaders/textures corresponding to a batch of sprites:
In the final implementation, pipeline creation is just an
initPipeline
message that you pass some options to:Rendering a frame
As a result of us doing all the work outside the render API - the GPU storage buffers are already up-to-date with all your sprites, there is no data to synchronize to the GPU during rendering except uniform values (shader program arguments) which is done with a
.preRender
message:Then you can begin a render pass and e.g. specify the background color of the frame:
Render sprites (you would duplicate this line to render multiple batches of sprites, which also controls draw order for e.g. transparency alpha blending purposes):
And finally end the render pass + present the frame: