I’m working on gradient for my project, but I’m in trouble because the only solutions I found is about THREE.Geometry which is deprecated to use VertexColor (which seems the more simpliest to use Material and gradient in same time), or Shader which seems too complicate for me.
I tried to use ShaderGraph for it but the result wasn’t what I expected
For it I found this on overflow :
Making gradient (watch vertexColor)
Accessing faces because face property is not available on BufferGeometry
But to access to the index array I need to use geometry.setIndex(geometry.attributes.position)
I get this error : THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The “position” attribute is likely to have NaN values.
But without index I can’t access to my faces. I’m completly blocked.
setGradient = (mesh, axis, reverse, geometryType) => {
//works for meshBasicMaterial
// let reverse = true;
mesh.material.vertexColors = true
let geometry = mesh.geometry
let colors = this.colorMap[geometryType] // The gradient
geometry.computeBoundingBox();
geometry.setIndex(geometry.attributes.position) // Here the error
let bbox = geometry.boundingBox;
let size = new THREE.Vector3().subVectors(bbox.max, bbox.min); // To manage graident on the axis
const colorsAttr = geometry.attributes.position.clone();
geometry.setAttribute('color', colorsAttr); // Creation of color attributes to use VertexColor
const colorAttributes = geometry.attributes.color
// let vertexIndices = ['a', 'b', 'c'];
let face = new THREE.Vector3()
let normalized = new THREE.Vector3()
let normalizedAxis = 0;
let vertex = new THREE.Vector3()
for (let c = 0; c < colors.length - 1; c++) {
let colorDiff = colors[c + 1].stop - colors[c].stop;
for (let i = 0; i < geometry.attributes.position.count; i++) {
// face = geometry.attributes.color[i];
for (let v = 0; v < 3; v++) {
let index = geometry.index.array[ 3 * i + v ];
vertex = vertex.fromBufferAttribute( geometry.attributes.position, index );
normalizedAxis = normalized.subVectors(vertex, bbox.min).divide(size)[axis];
if (reverse) {
normalizedAxis = 1 - normalizedAxis;
}
if (normalizedAxis >= colors[c].stop && normalizedAxis <= colors[c + 1].stop) {
let localNormalizedAxis = (normalizedAxis - colors[c].stop) / colorDiff;
geometry.attributes.color.array[i*3 + v] = colors[c].color.clone().lerp(colors[c + 1].color, localNormalizedAxis);
// colors.setXYZ( i, color.r, color.g, color.b )
}
}
}
}
}
Hey !
I found a solution without index, I was confuse between the function call which use index and the vertex selection.
I fact I load obj from a server so I need to assign my material dynamically, so I load the model, I add the material to the model geometry, after it I set a gradient and I add it to my context.scene