Alternative to Texture2D.Apply() that doesn't require synchronizing with the render thread, avoiding stalls in the main thread.
- Asynchronous texture data update in CPU in the render thread, avoiding stalls in the main thread
- Supports Unity's Built-in Render Pipeline as well as Scriptable Render Pipelines (e.g: URP and HDRP).
- To guarante the texture is applied before appearing in the screen:
- In BRP, updates are scheduled in the first Camera's
Camera.onPreRender
event - In SRP, updates are scheduled in
RenderPipelineManager.beginContextRendering
event
- In BRP, updates are scheduled in the first Camera's
- Supports registering for updates every frame or for a single frame
- Prebuilt for Windows, Linux, macOS and Android
- Built from source in iOS, tvOS, visionOS and WebGL projects
- You should not update the texture's data while the camera/render pipeline is rendering, or else garbage data could be applied to the texture.
Either:
- Use the openupm registry and install this package using the openupm-cli:
openupm add com.gilzoide.texture-apply-async
- Install using the Unity Package Manager with the following URL:
https://github.com/gilzoide/unity-texture-apply-async.git#1.1.0
- Clone this repository or download a snapshot of it directly inside your project's
Assets
orPackages
folder.
- Random Colors: simple sample with a UI that shows random colors.
- Plasma Color Job: sample scene with a plasma effect UI that is updated using the C# Job System.
using Gilzoide.TextureApplyAsync;
// 1. Create a `TextureApplyAsyncHandle` for your texture.
var textureApplyAsyncHandle = new TextureApplyAsyncHandle(myTexture);
// 2. If you want to update your texture every frame,
// schedule the apply handle to update every frame.
textureApplyAsyncHandle.ScheduleUpdateEveryFrame();
// 3. Update the texture data normally.
for (int x = 0; x < myTexture.width; x++)
{
for (int y = 0; y < myTexture.height; y++)
{
myTexture.SetPixel(x, y, Random.ColorHSV());
}
}
// 4. If you want to update your texture only once,
// schedule a one-shot update.
textureApplyAsyncHandle.ScheduleUpdateOnce();
// 5. Cancel updates if necessary.
// Works for both one-shot and every frame updates.
textureApplyAsyncHandle.CancelUpdates();
// 6. Dispose of the `TextureApplyAsyncHandle` when not needed
// anymore, e.g. inside a component's `OnDestroy`.
textureApplyAsyncHandle.Dispose();