Blur SVG where primitives overlap SVG shape and more (needs help)

Hello, I’m quite new to ThreeJs (I’m currently following the threejs journey course). I’m trying to achieve the following (screenshot below is made in photoshop):

  • When a primitive overlaps our logo, the part that overlaps should be blurring the svg in the background (1)
  • Display primitives with a gradient that has noise (2)
  • The primitives have a slight transparency (as you see there are lines behind the 3D elements but those lines are NOT part of the canvas element)

Currently I was able to produce this:

Alternative angle to illustrate the depth:

The “The craft” part is an svg logo I imported and added to the center of the scene:

const svgLoader = new SVGLoader(loadingManager);

svgLoader.load("/svg/logo.svg", (svgResult) => {
    const paths = svgResult.paths;
    const group = new THREE.Group();

    for (let i = 0; i < paths.length; i++) {
        const path = paths[i];
        const shapes = SVGLoader.createShapes(path);

        for (let j = 0; j < shapes.length; j++) {
            const shape = shapes[j];
            const geometry = new THREE.ShapeGeometry(shape);
            const mesh = new THREE.Mesh(geometry, textMaterial);
            group.add(mesh);
        }
    }
    // Scale to fit the screen
    group.scale.y = -1;
    group.scale.multiplyScalar(0.0042); // 0.006 * 0.7
    // Get correct bouding box for the group
    const groupBounding = new THREE.Box3().setFromObject(group);
    const groupCenter = groupBounding.getCenter(new THREE.Vector3());
    // Apply correct center to group
    group.position.copy(groupCenter).negate();
    // Add group to scene
    scene.add(group);
});

The primitives currently all use a MeshBasicMaterial with a basic gradient texture that is been loaded.

const primitiveMap = textureLoader.load("/textures/map/gradient.jpg");
const cube = new THREE.Mesh(
    new THREE.BoxGeometry(0.5, 0.5, 0.5),
    primitiveMaterial
);
scene.add(cube);

I also tried a ShaderMaterial with a custom shader (curtesy to stackoverflow) to create the gradient on my primitives but I’m not sure if this is the right way to tackle this issue)

const primitiveMaterial = new THREE.ShaderMaterial({
    uniforms: {
      color1: {
        value: new THREE.Color("#4771b5")
      },
      color2: {
        value: new THREE.Color("#a47bb4")
      }
    },
    vertexShader: `
      varying vec2 vUv;
  
      void main() {
        vUv = uv;
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1);
      }
    `,
    fragmentShader: `
      uniform vec3 color1;
      uniform vec3 color2;
    
      varying vec2 vUv;
      
      void main() { 
        // 0.6 is the opacity
        gl_FragColor = vec4(mix(color1, color2, vUv.y), 0.60);
      }
    `,
    transparent: true,
  });

I’m not quite sure what the steps are that I have to take… What materials do I use? Do I use lights? How to blur the logo where parts of the primitives overlap? How to add the grain? Do I use shaders for this or do I need a completely different setup? Any help would be appreciated!

this tutorial should help you to achieve a similar look with meshPhysical material

1 Like

Thank you very much, that helped quite a lot! Only issue I’m having now is applying a grain on my texture. Used a bumpmap but that actually reflects my light. Any way to have an extra (grain) texture above my main (gradient) texture?

i dont know any shader stuff so

easy way is to just use a noise texture on the color channel

there’s also a noise post processing passes three.js examples

but it’ll affect everything

Yeah post processing is not an option to do that, has to be only on the primitives, thanks though! :smiley:

Hi. I’m 4 days banging my head with overlapping svg Alpha region. Dont even know If this is your issue. Finally I managed a graphical monkeypatch. I added a solid square in the svg area the same color as the background. When I get back to this project I’ll try an invisible fill, in flash this didnt work. Hope I helped