Tresjs / tres

Declarative ThreeJS using Vue Components

Home Page:https://tresjs.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Gradient shader doesn't work

maelp opened this issue · comments

commented

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

https://stackblitz.com/edit/tresjs-shader-mthgxw?file=src%2Fcomponents%2Fshaders%2Ffragment.glsl,src%2Fcomponents%2FTheExperience.vue

Steps to reproduce

No response

System Info

No response

Used Package Manager

pnpm

Code of Conduct

commented

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)

commented

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;
};