• Runtimes
  • Custom shaders/filters for spine-pixi-v8

Hi Spine,

Is there any documentation for setting custom shaders or filters for the Spine meshes? I have a need in my pixie game to set a custom Depth (Z) value. I can't see any documentation or tutorials regarding this. I tried setting the filter on the entire sprite itself, but it doesnt work, i think i need to set the filter on the individual meshes (WebGL, WebGPU) Themselves, thanks

    Related Discussions
    ...

    For setting custom shaders or filters for Spine meshes in a pixi-spine environment, you would typically need to work with the WebGL or WebGPU context directly. Unfortunately, there isn't specific documentation from Esoteric Software for pixi-spine as it is maintained by a third party. However, you can apply custom shaders by modifying the shader code used by the Spine runtime. You might need to delve into the pixi-spine source code to understand how it handles shaders and then apply your custom shader logic accordingly. If you are looking to set a custom Depth (Z) value, you would likely need to modify the vertex shader to adjust the Z position of the vertices.

    For more detailed guidance, you might want to explore the pixi-spine GitHub repository or reach out to the community there for specific examples and support.

    benjaminhon

    Hello! Pixi filters work with spine-pixi-v8.

    See the basic examples with an AsciiFilter.

    I haven't tried yet to create a custom filter, but mimicking the existing filters, I guess you can achieve your desired result.

    Ah yes it works, i think i was setting the uniforms wrong

    Hmmm I managed to get the filter working for the entire Spine container, however how do we handle the case for custom shaders for individual parts?

    For instance:

    • Normal maps, lighting

    For this we would need to be able to set the shaders for the individual meshes instead of the whole container

      6 jours plus tard

      benjaminhon

      Apologies for the delayed response; I've been away these past few days.
      Currently, it’s not possible to modify the shader of individual attachments directly.

      However, with a bit more effort, you can achieve the same effect by using a slot object, as demonstrated in the following example:

      To do this, you can extract the individual texture and replace the corresponding attachment with a slot object. Since slot objects are standard Pixi elements, you can then easily apply a filter to them.

        15 jours plus tard
        3 mois plus tard

        Hi @Davide i am wondering as i was looking into the source code in the pixi spine v8 repo under

        Spine.ts
        
        readonly _slotsObject: Record<string, { slot: Slot, container: Container, followAttachmentTimeline: boolean } | null>

        Do you think it will work if i iterate over the slots which has the pixijs Container and apply my normal filter map there?

        In my filter, i pass in the original texture (the atlas) so i can remap the vTextureCoord to the original texture coordinate to sample the normal map.

        Im not sure if theres more things that goes on behind the hood, but do you think this would work?

        precision mediump float;
        
        in vec2 vTextureCoord;
        
        uniform vec4 uInputSize;
        uniform vec4 uOutputFrame;
        uniform sampler2D uTexture;
        uniform sampler2D uNormalTexture;
        uniform vec3 uLight; // x, y, intensity
        uniform float uAmbient;
        
        void main(void)
        {
            // Sample the original texture using vTextureCoord
            vec4 color = texture2D(uTexture, vTextureCoord);
        
            if (color.a < 0.0001) {
                discard;
            }
        
            if(uLight[2] > 0.0) {
                // Sample the normal map (the UVs for uNormalTexture is not vTextureCoord, need to recalculate)
                // See https://github.com/pixijs/pixijs/issues/6266
                // See https://github.com/pixijs/pixijs/wiki/v5-Creating-filters#conversion-functions
                vec4 normalColor = texture2D(uNormalTexture, vTextureCoord * uInputSize.xy /  uOutputFrame.zw);
                
                // Convert normal map color from [0,1] to [-1,1] range
                vec3 normal = normalize(normalColor.rgb * 2.0 - 1.0);
                
                // Create light direction vector
                vec3 lightDir = normalize(vec3(uLight.xy, 1.0));
                
                // Calculate dot product between normal and light direction
                float lightIntensity = max(dot(normal, lightDir), 0.0);
                
                // Apply light intensity and user-defined light strength
                float finalLightIntensity = mix(uAmbient, 1.0, lightIntensity * uLight[2]);
                
                // Apply lighting to color
                color.rgb *= finalLightIntensity;
            }
        
            gl_FragColor = color;
        }

        On further investigation it seems i cant get the containers of the original skin, it seems that only added slot objects via code have containers and the original skin is rendered internally as 1 entire ViewContainer instead

          benjaminhon

          As you've already experienced, it doesn't work. With Pixi v8, we went low-level to improve performance. On the flip side, this means there's less room for customization.

          However, there may be an alternative approach. Have you looked at the tint black batcher code?
          Ideally, you could use it as a base, define your own shader, and implement further customizations.