Search code examples
three.jsglslshader

Three.js ShaderMaterial Post Processing and Transparent Background


I'm trying to work with this shader, but I need a transparent background and it renders a black background. I realized that this is done within the fragmentShader, but I haven't figured out how to change it, and I don't even know if it's possible. Would anyone with experience in shaders know how to tell me?

var myEffect = {
        uniforms: {
            "tDiffuse": { value: null },
            "distort": { value: 0 },
            "resolution": { value: new THREE.Vector2(1., innerHeight / innerWidth) },
            "uMouse": { value: new THREE.Vector2(-10, -10) },
            "uVelo": { value: 0 },
            "time": { value: 0 }
        },
        vertexShader: `uniform float time;
        uniform float progress;
        uniform vec2 resolution;
        varying vec2 vUv;
        uniform sampler2D texture1;
        
        const float pi = 3.1415925;
        
        void main() {
          vUv = uv;
          gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0 );
        }`,
        fragmentShader: `uniform float time;
        uniform float progress;
        uniform sampler2D tDiffuse;
        uniform vec2 resolution;
        varying vec2 vUv;
        uniform vec2 uMouse;
        uniform float uVelo;            
        
        float circle(vec2 uv, vec2 disc_center, float disc_radius, float border_size) {
            uv -= disc_center;
            uv*=resolution;
            float dist = sqrt(dot(uv, uv));
            return smoothstep(disc_radius+border_size, disc_radius-border_size, dist);
        }
        
        float map(float value, float min1, float max1, float min2, float max2) {
            return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
        }
        
        float remap(float value, float inMin, float inMax, float outMin, float outMax) {
            return outMin + (outMax - outMin) * (value - inMin) / (inMax - inMin);
        }
        
        float hash12(vec2 p) {
            float h = dot(p,vec2(127.1,311.7)); 
            return fract(sin(h)*43758.5453123);
        }
        
        // #define HASHSCALE3 vec3(.1031, .1030, .0973)
        vec2 hash2d(vec2 p)
        {
            vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973));
            p3 += dot(p3, p3.yzx+19.19);
            return fract((p3.xx+p3.yz)*p3.zy);
        }
          
        void main() {
            vec2 newUV = vUv;
            vec4 color = vec4(1.,0.,0.,1.);
          
            float c = circle(newUV, uMouse, 0.0, 0.2);
            float r = texture2D(tDiffuse, newUV.xy += c * (uVelo * .5)).x;
            float g = texture2D(tDiffuse, newUV.xy += c * (uVelo * .525)).y;
            float b = texture2D(tDiffuse, newUV.xy += c * (uVelo * .55)).z;
            color = vec4(r, g, b, 1.);

            gl_FragColor = color;
        }`
    }

Solution

  • Well, assuming you set up three.js for transparency then my guess is

    the last part

         void main() {
                vec2 newUV = vUv;
                vec4 color = vec4(1.,0.,0.,1.);
              
                float c = circle(newUV, uMouse, 0.0, 0.2);
                float r = texture2D(tDiffuse, newUV.xy += c * (uVelo * .5)).x;
                float g = texture2D(tDiffuse, newUV.xy += c * (uVelo * .525)).y;
                float b = texture2D(tDiffuse, newUV.xy += c * (uVelo * .55)).z;
                float a = texture2D(tDiffuse, newUV.xy += c * (uVelo * .525)).w;  // added
                color = vec4(r, g, b, a);  // changed
    
                gl_FragColor = color;
            }`
    

    This might also work better

                vec4 c1 = texture2D(tDiffuse, newUV.xy += c * (0.1 * .5));
                vec4 c2 = texture2D(tDiffuse, newUV.xy += c * (0.1 * .525));
                vec4 c3 = texture2D(tDiffuse, newUV.xy += c * (0.1 * .55));
                float a = min(min(c1.a, c2.a), c3.a);
    
                vec4 color = vec4(c1.r, c2.g, c3.b, a);
                gl_FragColor = color;
    

    You maybe also need to premultiply the alpha

                gl_FragColor = color;
                gl_FragColor.rgb *= gl_FragColor.a;