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!