Three.js ShaderMaterial Post 处理和透明背景

Three.js ShaderMaterial Post Processing and Transparent Background

我正在尝试使用此 shader,但我需要一个透明背景,它呈现黑色背景。 我意识到这是在 fragmentShader 中完成的,但我还没有想出如何改变它,我什至不知道这是否可能。 哪位有shader经验的知道怎么告诉我吗?

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;
        }`
    }

好吧,假设你 set up three.js for transparency 那么我的猜测是

最后一部分

     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;
        }`

这也可能会更好

            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;

您可能还需要预乘 alpha

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

谢谢@gman,你帮助我理解了算法。我是这样解决的

void main() {
   vec2 newUV = vUv;
          
   float c = circle(newUV, uMouse, 0.0, 0.2);
   float a = texture2D(tDiffuse, newUV.xy+c*(uVelo)).w; //added
   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;              
   vec4 color = vec4(r, g, b, r+g+b+a); //changed   
        
   gl_FragColor = color;              
}