Vertex shader is not working as I wanted

Hello

I have plane and I want to show something like bellow picture and it’s move by uTime

line

To be able to see what calculation I did, I displayed it as a colored waveform through the fragment and it works fine but I expect vertex to work like fragment, but it doesn’t

my vertex shader :

attribute vec3 aPosition;
attribute vec2 aUv0;

uniform mat4 matrix_model;
uniform mat4 matrix_viewProjection;
uniform float u_Time;
uniform float u_Float;
uniform float u_Float1;
uniform float u_Float2;

varying vec2 uv2;
varying vec3 position2;

void main(void)
{

    uv2 = aUv0;
    position2 = aPosition;

    // VectorSplitter
    float x = aPosition.x;
    float z = aPosition.z;

    //Multiply
    float output6 = u_Time * u_Float;

    //Subtract
    float output5 = x - output6;

    //Divide
    float output4 = output5 / u_Float1;

    //Sin
    float output3 = sin(output4);

    //Multiply
    float output2 = output3 * u_Float2;

    //VectorMerger
    vec3 xyz2 = vec3(x, output2, z).xyz;

    gl_Position = matrix_viewProjection * matrix_model * vec4(xyz2, 1.0);
}

my fragment shader :

varying vec2 uv2;
varying vec3 position2;

uniform float u_Time;
uniform float u_Float;
uniform float u_Float1;
uniform float u_Float2;

void main(void)
{

    //VectorSplitter
    float x = position2.x;
    float z = position2.z;

    //Multiply
    float output6 = u_Time * u_Float;

    //Subtract
    float output5 = x - output6;

    //Divide
    float output4 = output5 / u_Float1;

    //Sin
    float output3 = sin(output4);

    //Multiply
    float output2 = output3 * u_Float2;

    //VectorMerger
    vec3 xyz2 = vec3(0, output2, 0).xyz;

    gl_FragColor = vec4(xyz2, 1.0);
}

my shader .js

    var ShaderTestTwo = pc.createScript('shaderTestTwo');

    ShaderTestTwo.attributes.add('vs', {
        type: 'asset',
        assetType: 'shader',
        title: 'Vertex Shader'
    });

    ShaderTestTwo.attributes.add('fs', {
        type: 'asset',
        assetType: 'shader',
        title: 'Fragment Shader'
    });

    // initialize code called once per entity
    ShaderTestTwo.prototype.initialize = function() {

        // console.log('>>>>', this.app.graphicsDevice.precision)

        this._time = 0;


        let fShaderPercision = "precision " + this.app.graphicsDevice.precision + " float;\n";
        fShaderPercision = fShaderPercision + this.fs.resource

        var shaderDefinition = {
            attributes: {
                aPosition: pc.SEMANTIC_POSITION,
                aUv0: pc.SEMANTIC_TEXCOORD0
            },
            vshader: this.vs.resource,
            fshader: fShaderPercision
        };

        var shader = new pc.Shader(this.app.graphicsDevice, shaderDefinition);
        this.material = new pc.Material();

        // this.material.setParameter('uTime', 0);
        this.material.setParameter('u_Time', 1);
        this.material.setParameter('u_Float', 0.1);
        this.material.setParameter('u_Float1', 0.02);
        this.material.setParameter('u_Float2', 0.3);

        this.material.setShader(shader);

        // Replace the material on the model with our new material
        var renders = this.entity.findComponents('render');

        for (var i = 0; i < renders.length; ++i) {
            var meshInstances = renders[i].meshInstances;
            for (var j = 0; j < meshInstances.length; j++) {
                meshInstances[j].material = this.material;
            }
        }  

    };

    // update code called every frame
    ShaderTestTwo.prototype.update = function(dt) {

        this._time += dt;
        this.material.setParameter('u_Time', this._time);

    };

Does it work if you set xyz2 as a uniform directly from CPU side, rather than calculating it on GPU?

I know how uniform works ! but i don’t have any idea how can i calculate from CPU side and send each position to my shader :slight_smile:

Don’t you already do that with other uniforms in your code? For example, u_Time is a uniform that you calculate on CPU side and send to GPU.

Yes i did it, but those uniforms are only a number
but for my calculation i need aPosition ( position of each vertex )
I don’t know how send position of each vertex from CPU side to GPU side

Please check this project : PlayCanvas | HTML5 Game Engine

I want to have wave on my plane like the green and black color

I think your plane simply doesn’t have enough vertices to do those waves. The default plane has only 4 vertices. You want to generate a custom plane, like in this example:

https://playcanvas.github.io/#/graphics/mesh-generation

Edit:
I just added an example, which is a different topic, but you can see how I create waves there:

2 Likes

Thanks
You are right, my plane doesn’t have enough vertices ! I create new plane with more vertices from blender and it’s works correctly

1 Like