How to make the face of the model facing down to use another color?

refer to this example https://discourse.threejs.org/t/color-bottom-x-of-a-boxgeometry-using-faces/18502
The model is transformable, so it cannot be the y-axis

Could you be more specific in description, providing more details of what you have and what you want to achieve?


Hello, This is a screenshot I found elsewhere, to achieve this function, the face of the model facing down has a different color.
I’m not too familiar with shaders.

If normal.y<0 then color=green
Or hemisphere light three.js examples

Hello, this should not be achieved with lights, I tried

mesh.material.onBeforeCompile=(shader)=>{
shader.fragmentShader=shader.fragmentShader.replace("#include <normal_fragment_maps>",
`#include <normal_fragment_maps>
if(normal.y<0.0){ diffuseColor.rgb=vec3(0.0,1.0,0.0); }`
)};

1 Like

Thank you for your answer, but my model will use the transform function, so it can’t be locked on the Y axis

But not model’s geometry, so, the solution from @Chaser_Code looks acceptable.

mesh.material.onBeforeCompile=(shader)=>{
shader.fragmentShader=shader.fragmentShader.replace("#include <normal_fragment_maps>",
shader.fragmentShader=shader.fragmentShader.replace("#include <dithering_fragment>", #include <dithering_fragment>
if(vNormal.y<0.0){ gl_FragColor.rgb=vec3(0.0,1.0,0.0); }`
)};
image

2 Likes

Thanks, I’ll try it out, and I’ll let you know if it works

Hello, can you provide an online demo, or fiddle? I follow hemisphere light and it has no effect, thanks!

Into post was deleted quotes because was not in tag “code”

mesh.material.onBeforeCompile=(shader)=>{
shader.fragmentShader=shader.fragmentShader.replace(
"#include <dithering_fragment>",
`#include <dithering_fragment>
if(vNormal.y<0.0){ gl_FragColor.rgb=vec3(0.0,1.0,0.0); }`
)};
1 Like

Thank you very much!

1 Like

hello, the demo looks right, but why is it wrong for me to use the model

Didnt undertood. Can you show whats wrong?

This is my online demo:https://codesandbox.io/s/goofy-sky-fsmr5h?file=/src/App.vue
The color of the model, it also changes with the camera

Try this:

node.material.onBeforeCompile = (shader) => {
  shader.vertexShader = `
    varying vec3 vN;
    ${shader.vertexShader}
  `.replace(
    `#include <normal_vertex>`,
    `#include <normal_vertex>
    vN = normal;
    //vN = (modelMatrix * vec4(normal, 1.)).xyz;
    `
  );
  shader.fragmentShader = `
    varying vec3 vN;
    ${shader.fragmentShader}
  `.replace(
    `#include <dithering_fragment>`,
    `#include <dithering_fragment>
    if(vN.y<0.0){ gl_FragColor.rgb=vec3(0.0,1.0,0.0); }`
  );
};

Depends on your needs, use
vN = normal; - object’s space
изображение

or
vN = (modelMatrix * vec4(normal, 1.)).xyz; - global space
изображение

image
Thanks for your answer, I updated the code of the demo. My goal is to make the face in the red box green (below the model), and not needed elsewhere, what else do I need to modify?

Get the size of your model, and pass it in the uniform, process values in shaders to restrict the changing of color by Y-coord (step or smoothstep) :thinking:

If the model is transformed, it may not be the Y axis. It seems that there is no way to solve it. :pensive: