Howdy! In our game engine we use a shader to let our players change the color of their character. We also have a web based (spine-ts/spine-player) preview of the character and would like to reuse this shader there.
Naively, I tried hooking spine-player's success callback and calling player.context.gl.attachShader. The shader compiles and these calls don't throw, but there is no change in what's rendered.
After looking at the source, I'm assuming this is because the gl->canvas pipeline is inititalized and managed outside of any of the lifecycle hooks that are exposed in spine-player.
Is there a way to do this without "diving deeper" into spine-webgl, if not, is there an example showing usage of a custom frag shader with spine-webgl?
Thanks so much for taking a look!
Here is where I left off:
playerRef.current = new SpinePlayer("container", {
jsonUrl: "https://thumbnails.r2.allout.game/playercharacter-8.json",
atlasUrl: "https://thumbnails.r2.allout.game/playercharacter-8.atlas.txt",
animations: ["Player_Shop/Idle"],
showControls: false,
backgroundColor: "#00000000",
alpha: true,
preserveDrawingBuffer: true,
showLoading: false,
defaultMix: 0,
viewport: {
x: -350,
y: -120,
width: 600,
height: 700,
padLeft: "0%",
padRight: "15%",
padTop: "10%",
padBottom: "0%",
debugRender: false,
},
success: (player: SpinePlayer) => {
const gl = player.context?.gl as WebGLRenderingContext;
const vertexShaderSource = `
attribute vec4 a_position;
void main() {
gl_Position = a_position;
}
`;
const fragmentShaderSource = `
void main() {
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); // all black for testing
}
`;
const compileShader = (gl: WebGLRenderingContext, source: string, type: number) => {
const shader = gl.createShader(type)!;
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.error(gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}
return shader;
};
const vertexShader = compileShader(gl, vertexShaderSource, gl.VERTEX_SHADER);
const fragmentShader = compileShader(gl, fragmentShaderSource, gl.FRAGMENT_SHADER);
if (!vertexShader || !fragmentShader) {
console.error("Error compiling shaders");
return;
}
const shaderProgram = gl.createProgram()!;
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
console.error("Error linking shader program", gl.getProgramInfoLog(shaderProgram));
return;
}
gl.useProgram(shaderProgram);
setSkins(skins);
setReady(true);
},
});