I'm having a problem with a GLSL shader that interpolates color in 3D space, and assigns it based on the 3D coordinates of the bounding box and I can't seem to fix it:
The stamen in this codepen: https://codepen.io/ricky1280/pen/BaxyaZY
this is the code that I feel like probably has the problem, the geometry of the sphere:
const stamenEndCap = new THREE.SphereGeometry( sinCurveScale/120, 20, 20 );
// stamenEndCap.scale(1,1.5,1)
stamenEndCap.scale(4,1,1) //find a way to rotate geometry relative to the sin curve at the end
stamenEndCap.toNonIndexed();
stamenEndCap.computeBoundingSphere();
stamenEndCap.computeBoundingBox();
stamenEndCap.normalizeNormals();
stamenEndCap.computeTangents();
console.log(stamenEndCap.attributes.position.array)
for (var i=0; i<stamenEndCap.attributes.position.array.length; i=i+3){
stamenEndCap.attributes.position.array[i]=stamenEndCap.attributes.position.array[i]+((centerEnd.x)) //offset
stamenEndCap.attributes.position.array[i+1]=stamenEndCap.attributes.position.array[i+1]+((centerEnd.y))
stamenEndCap.attributes.position.array[i+2]=stamenEndCap.attributes.position.array[i+2]+((centerEnd.z)) //height?
}
stamenEndCap.computeVertexNormals();
// let positionVector = new THREE.Vector3(spherePoint.x,spherePoint.y,spherePoint.z)
// console.log(positionVector)
stamenEndCap.attributes.position.needsUpdate = true;
console.log(stamenEndCap.attributes.position.array)
let merge = THREE.BufferGeometryUtils.mergeBufferGeometries([geometry2,stamenEndCap])
merge.attributes.position.needsUpdate = true;
It is shaded improperly, it looks like this:
The color harshly changes from white to that light blue color on the vertical axis, even though the stamen end cap (line 364 of the codepen) is merged with the tube geometry and the shader is calculated across the 3D space of the entire merged object. The geometry becomes "merge" on line 394, and then "stamenGeom" on line 400. Then its boundingbox is used in the vertex and fragment shaders that exist on lines 422-552.
I'm not sure how to shade this properly so that it transitions smoothly, without the line denoting the change in color from white-blue. It doesn't seem to respond to normals, unfortunately.
Viewing the stamen from plan (top-down?) shows that the color is transitioning properly, but viewed from the side it appears as the image.
If anyone has any advice or solutions please let me know, and thank you for reading all of this.
figured it out: in the shader code the colors weren't being blended properly.
previous fragment shader code:
`vec4 diffuseColor = vec4( diffuse, opacity );`,
`
vec4 white = vec4(1.0, 1.0, 1.0, 1.0);
vec4 red = vec4(1.0, 0.0, 0.0, 1.0);
vec4 blue = vec4(0.0, 0.0, 1.0, 1.0);
vec4 green = vec4(0.0, 1.0, 0.0, 1.0);
float f = clamp((vPos.z - bbMin.z) / (bbMax.z - bbMin.z)+vertOffset, 0., 1.);
// + is slider for vertical color position, -1 to 1
float linear_modifier = (1.00 * abs(1.) * f);
//vertical gradient position!!
//moves from 0-10?
vec3 col = mix(color1, color2, linear_modifier);
//float f2 = clamp((vPos.x - bbMin.x) / (bbMax.x - bbMin.x), 0., 1.);
float f2 = clamp(vUv.x, 0., 1.);
vec2 pos_ndc = vPos.xy*centerSize2;
float dist = length(pos_ndc*centerSize);
//controls central gradient position!
//the lower the larger?
//0-20
// float linear_modifier2 = (1.00 * abs(sin(1.0)) * dist);
//col = mix(color3, col, dist);
//NOT USING DIST REMOVES VERTICAL CENTRAL GRADIENT
// vec4 diffuseColor = vec4( col, opacity );
float f3 = clamp(vUv.x+f3Offset, 0., 1.);
// ^ THIS controls brightness of lowlights. lower the more intense.
col = mix(color3, col, f3);
//not using this removes LOWLIGHTS
//f3 is subtle fade
//col = mix(color3, col, f3);
//col = mix(color3, col, f2);
//f2 is default
vec4 diffuseColor = vec4( col, opacity );`
fixed shader code:
`vec4 diffuseColor = vec4( diffuse, opacity );`,
`
vec4 white = vec4(1.0, 1.0, 1.0, 1.0);
vec4 red = vec4(1.0, 0.0, 0.0, 1.0);
vec4 blue = vec4(0.0, 0.0, 1.0, 1.0);
vec4 green = vec4(0.0, 1.0, 0.0, 1.0);
float f = clamp((vPos.z - bbMin.z) / (bbMax.z - bbMin.z)+vertOffset, 0., 1.);
// + is slider for vertical color position, -1 to 1
float linear_modifier = (1.00 * abs(1.) * f);
//vertical gradient position!!
//moves from 0-10?
vec3 col = mix(color1, color2, linear_modifier);
float f2 = clamp((vPos.x - bbMin.x) / (bbMax.x - bbMin.x), 0., 1.);
//float f2 = clamp(vUv.x, 0., 1.);
vec2 pos_ndc = vPos.xy*centerSize2;
float dist = length(pos_ndc*centerSize);
//controls central gradient position!
//the lower the larger?
//0-20
// float linear_modifier2 = (1.00 * abs(sin(1.0)) * dist);
//col = mix(color3, col, dist);
//NOT USING DIST REMOVES VERTICAL CENTRAL GRADIENT
// vec4 diffuseColor = vec4( col, opacity );
float f3 = clamp(vUv.x+f3Offset, 0., 1.);
// ^ THIS controls brightness of lowlights. lower the more intense.
//col = mix(color3, col, f3);
//not using this removes LOWLIGHTS
//f3 is subtle fade
//col = mix(color3, col, f3);
//col = mix(color3, col, f2);
//f2 is default
vec4 diffuseColor = vec4( col, opacity );
`