Render Targets

  Edit on GitHub

WebGPU makes render targets/framebuffer objects easy. There is no need for an API to be built on top as a RenderPassEncoder is essentially a render target. Instead of rendering the surface frame, as we usually do, we can create an EmptyTexture of a specified size and use it as the output in a render pass.

EmptyTexture

Creates a new Texture of size 256, 256.

val preferredFormat = graphics.preferredFormat
val target = EmptyTexture(device, preferredFormat, 256, 256)

Rendering to a Texture

Render to a texture.

val commandEncoder = device.createCommandEncoder("command encoder")
val renderTargetRenderPass =
    commandEncoder.beginRenderPass(
        RenderPassDescriptor(
            listOf(
                RenderPassColorAttachmentDescriptor(
                    view = target.view, // our texture specified here!
                    loadOp = LoadOp.CLEAR,
                    storeOp = StoreOp.STORE,
                    clearColor =
                        if (preferredFormat.srgb) Color.YELLOW.toLinear()
                        else Color.YELLOW
                )
            ),
            label = "Surface render pass"
        )
    )

batch.begin()
batch.draw(mySprite, 0f, 0f) // we are drawing to the render target
batch.flush(renderTargetRenderPass)
renderTargetRenderPass.end()

val surfaceRenderPass =
    commandEncoder.beginRenderPass(
        RenderPassDescriptor(
            listOf(
                RenderPassColorAttachmentDescriptor(
                    view = frame,
                    loadOp = LoadOp.CLEAR,
                    storeOp = StoreOp.STORE,
                    clearColor =
                        if (preferredFormat.srgb) Color.DARK_GRAY.toLinear()
                        else Color.DARK_GRAY
                )
            ),
            label = "Surface render pass"
        )
    )
// now we draw the render target ouput to the surface frame
batch.draw(
    target,
    0f,
    0f,
    originX = target.width * 0.5f,
    originY = target.height * 0.5f,
)
batch.flush(surfaceRenderPass)
batch.end()
surfaceRenderPass.end()