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);
},
});