LeeMc
March 22, 2024, 6:20pm
1
I have this awesome code from @prisoner849
var material = new THREE.ShaderMaterial({
uniforms: {
color1: {
value: new THREE.Color("red")
},
color2: {
value: new THREE.Color("purple")
},
bboxMin: {
value: geometry.boundingBox.min
},
bboxMax: {
value: 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;
varying vec2 vUv;
void main() {
gl_FragColor = vec4(mix(color1, color2, vUv.y), 1.0);
}
`,
wireframe: true
});
Which results in this:
Iβm clueless with shaders, is there any way I can make it go from red to blue from start to finish? Rather than based on the y position.
(if you follow the line currently you can see it goes red, purple, blue, purple, blue⦠whereas I want red, purple, blue).
Iβd want something like
vUv.y = index / totalVertices
Or am I talking nonsense and this isnβt how shaders work at all?
1 Like
Not nonsense. But βindexβ might need to be
vUv.y = float(gl_VertexID) / totalVertices;
and somehow you have to get βtotalVerticesβ into the shader, either by hardcoding a number, or passing it in as a uniform.
edit: whoops gl_VertexID is in GLES 3 only.
but I think it might be available by default now since threejs is webGL2 by default. Sorry itβs a bit confusing tbh.
If you use TubeGeometry
, then
vUv.y = (position.y - bboxMin.y) / (bboxMax.y - bboxMin.y);
should be enough to turn it into:
vUv = uv;
I think OP is wanting a gradient along the line⦠not from top to bottom in Y.
This is what vUv.y
vUv.x
will do, if you use TubeGeometry
Snippet:
let g = new THREE.TubeGeometry(new THREE.CatmullRomCurve3([
[-1, -1, 0],
[0, 0, 0],
[1, 1, 1],
[-1, 2, 0],
[-1, -2, -1]
].map(p => {return new THREE.Vector3(...p)})), 100, 0.1, 6);
let m = new THREE.ShaderMaterial({
uniforms: {
colorStart: {value: new THREE.Color(0xff0000)},
colorEnd: {value: new THREE.Color(0x0000ff)}
},
vertexShader: `
varying vec2 vUv;
void main(){
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.);
}
`,
fragmentShader: `
uniform vec3 colorStart;
uniform vec3 colorEnd;
varying vec2 vUv;
void main(){
vec3 col = mix(colorStart, colorEnd, vUv.x); // the using of uv.x is enough
gl_FragColor = vec4(col, 1);
}
`
})
1 Like
Ahhhh yessss this is the way. @LeeMc
LeeMc
March 22, 2024, 8:32pm
7
Thank you both @manthrax and @prisoner849
Shaders are an alien language to us mortals, continue the great work
2 Likes