Gradient shader doesn't work
maelp opened this issue · comments
Describe the bug
I'm trying to create a gradient Fragment Shader using this
const gradientMaterialVertexShader = `
varying vec2 vUv;
void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
vUv = uv;
}
`;
const gradientMaterialFragmentShader = `
varying vec2 vUv;
uniform vec3 fromColor;
uniform vec3 toColor;
void main() {
gl_FragColor = vec4(mix(fromColor, toColor, vUv.y), 1.0);
}
`;
and
<TresShaderMaterial
:vertex-shader="gradientMaterialVertexShader"
:fragment-shader="gradientMaterialFragmentShader"
:uniforms="{
fromColor: {value: new THREE.Color('#ffff00')},
toColor: {value: new THREE.Color('#ff00ff')},
}"
></TresShaderMaterial>
but the object has uniform color instead of a gradient. I'm not sure what I'm doing wrong, but I tried to do something similar to the fragment shader example on the playground
Reproduction
Steps to reproduce
No response
System Info
No response
Used Package Manager
pnpm
Code of Conduct
- I agree to follow this project's Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- The provided reproduction is a minimal reproducible example of the bug.
The weird thing is that when copying the code in StackBlitz it works https://stackblitz.com/edit/tresjs-shader-mthgxw?file=src%2Fcomponents%2Fshaders%2Ffragment.glsl,src%2Fcomponents%2FTheExperience.vue
but on my local install it doesn't... and I don't see what I'm doing differently?
could it be because I need to do custom UV mapping if it's on my own mesh (I'm not using a default geometry like eg TresSphereGeometry etc)
Seems it was my mesh missing UV mapping, fixed it using this
const updateUVMap = (geometry: THREE.BufferGeometry) => {
geometry.computeBoundingBox();
const max = geometry.boundingBox.max;
const min = geometry.boundingBox.min;
const offset = new THREE.Vector2(0 - min.x, 0 - min.y);
const range = new THREE.Vector2(max.x - min.x, max.y - min.y);
const positions = geometry.attributes.position.array;
const uvs: number[] = [];
for (let i = 0; i < positions.length; i += 3) {
const x = positions[i];
const y = positions[i + 1];
uvs.push((x + offset.x) / range.x, (y + offset.y) / range.y);
}
geometry.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(uvs), 2));
geometry.uvsNeedUpdate = true;
};