Hello everyone,
I am trying to create an effect similar to a “Color Ramp” node on Blender, or Gradient Map in Photoshop. The idea would be to sample a texture (grayscale) and read one of the channels (Blender apparently uses the green one) and use the value to mix two different colors. So the darker tones would be closer to color1 and darker tones would be closer to color2, and so we go.
I am importing a model with GLTF loader (using GLB file, compressed KTX2 texture, and DRACO for mesh compression) and then changing it’s material.
To keep things as simple as possible, I am trying to just expand/modify the MeshStandardMaterial fragment shader, by creating a new Material and modifying some lines of its fragment shader using onBeforeCompile
.
One example I have that currently works is doing the gradient between 2 colors using the UVs Y coordinate as the factor, with vec3 col = mix(color1, color2, vUv.y);
My code for this would be
onBeforeCompile: shader => {
shader.uniforms.color1 = uniforms.color1;
shader.uniforms.color2 = uniforms.color2;
shader.fragmentShader = `
uniform vec3 color1;
uniform vec3 color2;
uniform sampler2D colorTexture;
${shader.fragmentShader}
`.replace(
`vec4 diffuseColor = vec4( diffuse, opacity );`,
`vec3 col = mix(color1, color2, vUv.y);
vec4 diffuseColor = vec4( col, opacity ); `
);
}
And this works perfectly as expected, creating a color gradient in the model that changes the color based on the UV.
But when I try using the actual color of the textures, I don’t seem to be able to read the color values at all. Every time I sample the color from the texture I get the same value for all pixels, all the time, resulting in the same color all over the model instead of any gradient.
I tried sampling from the texture from map
or even including a new texture in uniforms; tried to use the values after they were loaded into diffuseColor
in the map_fragment.glsl include, but nothing seems to work.
Here is an example of the code I am trying, which results in a monochromatic rendering of the model:
onBeforeCompile: shader => {
shader.uniforms.color1 = uniforms.color1;
shader.uniforms.color2 = uniforms.color2;
shader.fragmentShader = `
uniform vec3 color1;
uniform vec3 color2;
${shader.fragmentShader}
`.replace(
`#include <map_fragment>`,
`
#include <map_fragment>
vec3 col = mix(color1, color2, diffuseColor.g);
diffuseColor = vec4( col, diffuseColor.a );
`
);
}
I feel like I am missing some part of how the fragment shader is put together or how the color is sampled, so any help would be appreciated!
Thanks in advance