In the Construct 3 plugin which uses spine-ts / webgl, I implemented a batch rendering of all skeleton instances, to greatly reduce context switch cost between C3 renderer and the Spine renderer.
I wanted to see if anyone had suggestions on improving the render/draw loop I implemented. My first idea was to try to make the polygon batcher batch all the skeletons, since we are using the same basic parameters for all the skeleton instances. However the issue is that we will likely change the mvp for each instance based on some resizing we are doing and the instances could be from a mix of different original skeletons. I know I am just scratching the surface of spine-ts / webgl, so I imagine there are at least a few ways to improve the current method. Thanks in advance for the help.
// Per instance render
for (const uid in skeletonInstances)
{
const skeletonInstance = skeletonInstances[uid];
if (skeletonInstance.initialized)
{
const bounds = skeletonInstance.skeletonInfo.bounds;
// Render to our targetTexture by binding the framebuffer to the SpineFB texture
gl.bindFramebuffer(gl.FRAMEBUFFER, skeletonInstance.spineFB);
// Set viewport
gl.viewport(0, 0, bounds.size.x, bounds.size.y);
// Set proper webgl blend for Spine render
gl.enable(gl.BLEND);
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
gl.bindTexture(gl.TEXTURE_2D, null);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
// Bind the shader and set the texture and model-view-projection matrix.
this.shader.bind();
this.shader.setUniformi(spine.webgl.Shader.SAMPLER, 0);
// Resize
this.resize(bounds, skeletonInstance.skeletonScale);
this.shader.setUniform4x4f(spine.webgl.Shader.MVP_MATRIX, this.mvp.values);
// Start the batch and tell the SkeletonRenderer to render the active skeleton.
this.batcher.begin(this.shader);
// Apply vertex effect
this.renderer.vertexEffect = null;
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
// Render
this.renderer.premultipliedAlpha = this.premultipliedAlpha;
this.renderer.draw(this.batcher, skeletonInstance.skeletonInfo.skeleton);
this.batcher.end();
this.shader.unbind();
}
}
Also, the improvement from just changing to this batcher/loop was significant 4X higher performance for the C3 plugin.
Example below: