Hey, I have the following problem hoping for your help.
It’s my first project with three.js and I’m importing an gltf model made in blender.
This model is only one mesh and now I want to apply a multicolor gradient to it.
The gradient should go from a magenta to yellow to green to blue.
I found some help online, which enabled me to apply
a two-color gradient from (boundingbox) y.max to y.min to my mesh - but not the
four-color gradient, which should go from (x.max,y.max,z.max) to (x.min,y.min,z.min).
The color changes should be equally distributed:
- 0-33% magenta to yellow
- 33%-66% yellow to green
- 66%-100% green to blue
Do you guys have an idea how to solve this?
My corresponding code looks like this till now.
[...]
importModel() {
const loader = new GLTFLoader()
const model = new URL('/models/my_mesh_model.gltf', import.meta.url);
loader.load(
// Model
model.href,
// called when the resource is loaded
gltf => {
gltf.scene.traverse(function (child) {
if (child.isMesh) {
child.material = new THREE.ShaderMaterial({
uniforms: {
color1: {
//magenta
value: new THREE.Color(0xFF0089)
},
color2: {
//yellow
value: new THREE.Color(0xCFC91E)
},
color3: {
//green
value: new THREE.Color(0x02E91E)
},
color4: {
//blue
value: new THREE.Color(0x00DAFF)
},
bboxMin: {
value: child.geometry.boundingBox.min
},
bboxMax: {
value: child.geometry.boundingBox.max
}
},
vertexShader: `
uniform vec3 bboxMin;
uniform vec3 bboxMax;
varying vec2 vUv;
void main() {
vUv.y = (position.y - bboxMin.y) / (bboxMax.y - bboxMin.y);
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
}
`,
fragmentShader: `
uniform vec3 color1;
uniform vec3 color2;
uniform vec3 color3;
uniform vec3 color4;
varying vec2 vUv;
void main() {
// works - but only for two colors
gl_FragColor = vec4(mix(color1, color2, vUv.y), 1.0);
// not working
//gl_FragColor = vec4(color1*vUv.y*0.2+color2*vUv.y*0.4+color3*vUv.y*0.6+color4*vUv.y*0.8, 1.0);
}
`,
wireframe: false
});
}
});
gltf.scene.position.set(0, 0, 1);
this.logo = gltf.scene;
this.scene.add(gltf.scene);
},
// called while loading is progressing
function ( xhr ) {
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
},
// called when loading has errors
function ( error ) {
console.log( 'An error happened' );
}
);
}
[...]
It’s my first time with three.js and I’m not quite into js in general, so please be nice with me.