GLSL transparent area


I have customized a shader and created a flowing line effect, but there is a problem where the starting and ending positions are directly cut off. I want the starting position to be slowly displayed, and then the ending position to be slowly hidden, with a transitional effect. I don’t know where the problem lies with my shader code. The glsl code does not have this problem when used in three.js, and I really hope someone can help me
Code Highlight var shaderDefinition = {
attributes: {
aPosition: pc.SEMANTIC_POSITION,
aUv0: pc.SEMANTIC_TEXCOORD0
},
vshader: `
attribute vec3 aPosition;
attribute vec2 aUv0;

    uniform mat4 matrix_model;
    uniform mat4 matrix_viewProjection;

    varying vec2 vUv;

    void main(void) {
        vUv = aUv0;
        mat4 MVP = matrix_viewProjection * matrix_model;
        gl_Position = MVP * vec4(aPosition, 1.0);
    }`,
    fshader: `
    
    
    precision mediump float;

    uniform float vTime;
    uniform vec3 color;
    uniform float opacity;
    varying vec2 vUv;
    uniform float random;

    #define S smoothstep
    #define IS(x,y,z) (1. - smoothstep(x,y,z))

    vec3 draw_line(vec2 uv,vec3 color, float shift, float freq){
        float line_thickness = 0.14;
        float amp_coef = 0.9;

        uv.y -=IS(1.1,1.9,abs(uv.x)) * sin(uv.x + shift * freq) * amp_coef * sin(uv.x + shift);
        return IS(0.,line_thickness*S(-0.9,.9,abs(uv.x)),abs(uv.y*1.2)) * color;
    }
   
    void main() {
        float speed = 0.5;
        float freq_coef = 1.5;
        vec2 uv = vUv*2. - 1.;
        
        float shift = vTime * speed;

        float vProgress = smoothstep(-1.,1.,sin(vUv.x*12. + vTime*6.*random));
        float hideCorners = smoothstep(1., 0.9, vUv.x);
        float hideCorners1 = smoothstep(0., 0.1, vUv.x);
        
        vec3 color = vec3(0.);
        for (float idx = 0.; idx < 4.; idx += 1.){
            color += draw_line(uv,vec3(0.2,0.3,0.6),shift+idx,1.+freq_coef);
        }
        vec3 finalColor = mix(color,color * 0.25,vProgress);
        gl_FragColor = vec4(finalColor,opacity*hideCorners*hideCorners1);
    }`
};

Here is my project address
https://playcanvas.com/project/1228022/overview/opacity_demo

Because it was only an hour between this post and creating the topic :grimacing:

I had a look at this and I’m not a shader person so my GLSL is not the best.

From what I can tell, ‘black’ is fully transparent so to make the ends fade out nicely, you need to multiply the color by a value related to the UV coords. The closer it is to the edge of the mesh, the ‘darker’ the color.

The UVs on the mesh go from -1 to +1 on the U axis so I used some if statements to start fading from a particular point on the UV map

// 
        void main() {
            float speed = 0.5;
            float freq_coef = 1.5;
            vec2 uv = vUv*2. - 1.;
            
            float shift = vTime * speed;
    
            float vProgress = smoothstep(-1.,1.,sin(vUv.x*12. + vTime*6.*random));
            float hideCorners = smoothstep(1., 0.9, vUv.x);
            float hideCorners1 = smoothstep(0., 0.1, vUv.x);
            
            vec3 color = vec3(0.);
            for (float idx = 0.; idx < 4.; idx += 1.){
                color += draw_line(uv,vec3(0.2,0.3,0.6),shift+idx,1.+freq_coef);
            }
            vec3 finalColor = mix(color,color * 0.25,vProgress);
            float alpha = 1.0;
            if (uv.x < -0.9) {
                alpha = (1.0 - (uv.x * -1.0)) * 10.0;
            }

            if (uv.x > 0.9) {
                alpha = (1.0 - uv.x) * 10.0;
            }

            gl_FragColor = vec4(finalColor * alpha, opacity);
        }`

I also changed the material not to write to the depth buffer so that they look nicer overlaid in this particular example. YMMV

https://playcanvas.com/project/1228447/overview/opacity_demo

1 Like

@mvaligursky Is there an alpha channel assignment missing in the material setup somewhere in the example project?

Oh, it’s the blend type that’s affecting this

I’ve updated the project. The main issue is that the blend type was set to pc.BLEND_ADDITIVE (which doesn’t use the alpha channel).

It should be pc.BLEND_ADDITIVEALPHA

See Material | PlayCanvas API Reference

I’ve also made some other fixes while I was at it.

var WindMesh = pc.createScript('windMesh');

// initialize code called once per entity
WindMesh.prototype.initialize = function () {
    this.initMaterial()
    this._start = pc.app._time
    this.counter = 0;
};
WindMesh.prototype.getElapsedTime = function() {
    return pc.app._time - this._start;
};

WindMesh.prototype.initMaterial = function () {

    var app = this.app;
    var gd = app.graphicsDevice;

    var shaderDefinition = {
        attributes: {
            aPosition: pc.SEMANTIC_POSITION,
            aUv0: pc.SEMANTIC_TEXCOORD0
        },
        vshader: `
        attribute vec3 aPosition;
        attribute vec2 aUv0;
    
        uniform mat4 matrix_model;
        uniform mat4 matrix_viewProjection;
    
        varying vec2 vUv;
    
        void main(void) {
            vUv = aUv0;
            mat4 MVP = matrix_viewProjection * matrix_model;
            gl_Position = MVP * vec4(aPosition, 1.0);
        }`,
        fshader: `
        
        
        precision mediump float;
    
        uniform float vTime;
        uniform vec3 color;
        uniform float opacity;
        varying vec2 vUv;
        uniform float random;
    
        #define S smoothstep
        #define IS(x,y,z) (1. - smoothstep(x,y,z))
    
        vec3 draw_line(vec2 uv,vec3 color, float shift, float freq){
            float line_thickness = 0.14;
            float amp_coef = 0.9;
    
            uv.y -=IS(1.1,1.9,abs(uv.x)) * sin(uv.x + shift * freq) * amp_coef * sin(uv.x + shift);
            return IS(0.,line_thickness*S(-0.9,.9,abs(uv.x)),abs(uv.y*1.2)) * color;
        }
       
        void main() {
            float speed = 0.5;
            float freq_coef = 1.5;
            vec2 uv = vUv*2. - 1.;
            
            float shift = vTime * speed;
    
            float vProgress = smoothstep(-1.,1.,sin(vUv.x*12. + vTime*6.*random));
            float hideCorners = smoothstep(1., 0.9, vUv.x);
            float hideCorners1 = smoothstep(0., 0.1, vUv.x);
            
            vec3 color = vec3(0.);
            for (float idx = 0.; idx < 4.; idx += 1.){
                color += draw_line(uv,vec3(0.2,0.3,0.6),shift+idx,1.+freq_coef);
            }
            vec3 finalColor = mix(color,color * 0.25,vProgress);
            gl_FragColor = vec4(finalColor, opacity * hideCorners * hideCorners1);
        }`
    };


    // Create the shader from the definition
    this.shader = new pc.Shader(gd, shaderDefinition);
    console.log(this.shader)


    

    // 创建材质
    this.material = new pc.Material()
    this.material.shader = this.shader;

    console.log(this.material.shader)
    // 设置扩展(如果需要)
    // material.setParameter('extensions', { /* 相关扩展设置 */ });
    this.material.cull = pc.CULLFACE_NONE;
    this.material.depthWrite = false;
    // 设置 uniforms
    this.material.setParameter('vTime', 265);
    this.material.setParameter('color', new pc.Color(0.5, 0.5, 0.13));
    this.material.setParameter('vProgress', 0.8);
    this.material.setParameter('opacity', 1);
    this.material.setParameter('random', Math.random());
    this.material.transparent = true;
    // this.material.depthWrite = false;
    this.material.blendType = pc.BLEND_ADDITIVEALPHA;
    for (var i = 0; i < this.entity.children.length; ++i) {
        // 因为现在只有一个材质球 默认获取第一个
        this.entity.children[i].render.meshInstances[0].material = this.material
    }

}


// update code called every frame
WindMesh.prototype.update = function (dt) {
    this.counter += 0.5 * dt;
    // console.log(this.counter);
    this.material.setParameter('vTime', this.counter);
};

// uncomment the swap method to enable hot-reloading for this script
// update the method body to copy state from the old instance
// WindMesh.prototype.swap = function(old) { };

// learn more about scripting here:
// https://developer.playcanvas.com/user-manual/scripting/

2 Likes

Thank you very much for your help. I don’t know how to thank you. I was moved to see your reply because I know nothing about GLSL, so I am very distressed now. Thank you very much, and I hope you have good luck in your life

1 Like