About the problems encountered in using shader to create custom sequence frame effect, please consult the leaders for help

1、Is there a scene in which you can test whether the shader code is right or wrong? Can you upload your own maps in the playground of babylonjs?
After all, some materials need to provide related maps to see the effect.
2、
The following paragraph is about the shader for sequence frame playback, which I wrote myself. I have encountered several problems


export const sequenceVertexShader :string = `
#version 300 es
precision highp float;
// Attributes
in vec3 position;
in vec2 uv;
in vec3 normal;
// Uniforms
uniform mat4 worldViewProjection;
uniform float time;
uniform float speed;
// Varying
out vec2 vUV;
out vec3 vPos;
out vec3 vNoraml;
void main(void){ gl_Position=worldViewProjection*vec4(position,1.0); vUV=uv; vPos=position; vNoraml=normal;}`;

export const sequenceFragmentShader : string = `
#version 300 es
precision highp float;
in vec2 vUV;
in vec3 vPos;
in vec3 vNoraml;
uniform float time;
uniform vec3 cameraPos;
uniform float speed;
uniform vec4 bgcolor;
uniform sampler2D frameTex;
uniform vec2 frameTilesUV;
uniform float frameAnimationSpeed;
uniform float isPositive;
uniform float frameNum;

out vec4 fragColor;

void main(void) {
fragColor = bgcolor;
vec4 frameColor = vec4(0.0);
#ifdef USE_BG 
fragColor = vec4(0.0);
vec2 frameUVOffset = vec2(0.0);
vec2 frameUV = (vUV / frameTilesUV);
float count = frameTilesUV.x * frameTilesUV.y;
float frameIndex = frameNum + floor(mod(time * frameAnimationSpeed,count));

if(isPositive == 1.0){
// 左下角是1
float _x = floor(mod(frameIndex,frameTilesUV.x));
float _y = floor(frameIndex/frameTilesUV.x) - frameTilesUV.y;

if(frameTilesUV.x == frameTilesUV.y){

    if(mod(frameIndex,count) == 0.0){
        _y = 0.0;
    }
    else{
        float _mod = mod(frameIndex,frameTilesUV.x);
        _y = mod(frameIndex,frameTilesUV.x) == 0.0?floor(frameIndex/frameTilesUV.x):floor(frameIndex/frameTilesUV.x) + 1.0;
        
        // if(_mod != 0.0)
        // {
        //    _y = floor(frameIndex/frameTilesUV.x);
        // }
        // else
        // {
        //    _y = floor(frameIndex/frameTilesUV.x) + 1.0;
        // }

        // if(frameIndex == 3.0){_y = 1.0;}
        // else if(frameIndex == 6.0){_y = 2.0;}
    }
}

frameUVOffset = vec2(_x,_y) / frameTilesUV;
}else{
// 左上角是1
float _x = mod(frameIndex,frameTilesUV.x);
float _y = frameTilesUV.y - (floor(frameIndex/frameTilesUV.x)) - 1.0;
frameUVOffset = vec2(_x,_y) / frameTilesUV;
}
    
frameUV += frameUVOffset;

frameColor = texture(frameTex,frameUV) * bgcolor;
// fragColor = mix(bgColor,frameColor,frameColor.a);
fragColor = frameColor;
#endif
if(fragColor.a <0.01){discard;}
}`;

The above code works fine when playing sequence frame images with different dimensions in the u and v directions, such as 4x3 or 5x4. However, when the sequence frames have the same number of dimensions in both the u and v directions, such as 3x3 or 4x4, the playback order becomes incorrect. Taking 3x3 as an example, assuming there are 9 images arranged with the bottom-left corner as the first image, from left to right and bottom to top, theoretically, frame 0 should display the first image, frame 1 should display the second image, frame 2 should display the third image, frame 3 should display the fourth image, and so on. However, in reality, when the frame number reaches the 3rd frame, it displays the first image; at the 6th frame, it displays the fourth image; and at the 9th frame, it displays the seventh image. Why is this happening? I didn’t encounter this issue when I wrote similar effects in Unity before.

This page describes some ways to store external assets for use in a playground or in your project:

https://doc.babylonjs.com/toolsAndResources/thePlayground/externalPGAssets/

Regarding your other problem, can you create a repro in http://playground.babylonjs.com/? It will be a lot easier to help.

I simplified part of the sequence frame shader code based on the situation I encountered. Additionally, I uploaded a 5x4 sequence frame material and a 3x3 sequence frame material for comparison.

What’s the problem with your PG? I can see 1/2/3/4/5/6/7/8/9/1/2/3/… in sequence: is it not what you see?

1 Like

So do I

Same, I have an ordered sequence from 1 to 9. I even tried to replace by the 5x4 and adapt the frameTilesUV it works from 1 to 20

Maybe your simplification got rid of the issue ? :stuck_out_tongue:


Also, I had a look at the GLSL code itself. I think this is bad :

float _y = floor(frameIndex/frameTilesUV.x) - frameTilesUV.y;

There is no reason to subtract frameTilesUV.y, is there ?
Replacing by :

float _y = floor(frameIndex/frameTilesUV.x)

Still works. Maybe your original issue comes from there ?

1 Like

How can there be no problem? Isn’t it obvious that the sequence should have changed from 4 to 1, and the sequence should have changed from 6 to 4

1 Like

Are you sure you’ve read it? The current demonstration at the amusement park is clearly in sequence 1/2/3/1/5/6/4/8/9/1/2/3 Similarly, if it weren’t for what I thought was forcing the 9th frame to become 0, the 9th frame of the sequence would have displayed the 7th image in the sequence frame

1 Like

Er… no!

Given the explanation given in your first post, everyone in this thread understood that you wanted to display 1/2/3/4/5/6/7/8/9/1/2/3/… in order, and because that’s what the PG does, we thought it worked correctly.

If this isn’t what you’re looking for, can you explain what you’re trying to achieve?

1 Like

I agree, I also did not get there was a problem. @zertaul please trey to rewrite your need in a clearer way so we can help

1 Like