How to change the color of the triangle according to the orientation of the camera and the normal vector of the triangle

Hello, I am looking for a way to change the display color of the triangular patch based on its normal vector and camera orientation, as shown in the following picture. If the normal vector is facing the camera, it is displayed in blue; if the normal vector is in the same direction as the camera, it is displayed in yellow.

I should be able to set up settings through ShaderProperty by searching for information, but I found some information online and couldn’t solve it. Does anyone know what to do?
readingfiles:
https://examples.vtk.org/site/Cxx/Shaders/ColorByNormal/
https://gitlab.kitware.com/vtk/vtk/-/blob/master/Rendering/OpenGL2/Testing/Cxx/TestUserShader.cxx
https://gitlab.kitware.com/vtk/vtk/-/blob/master/Rendering/OpenGL2/Testing/Cxx/TestUserShader2.cxx
https://gitlab.kitware.com/vtk/vtk/-/blob/master/Rendering/OpenGL2/Testing/Python/TestUserShader2.py

Hello,

You’ve found exactly the kind of material that I would suggest you to read. What exactly you didn’t understand in the examples?

best,

PC

by the examples, it shows that the color of triangle is defined by normal, i fond that it is defiend by
" ```
diffuseColor = abs(myNormalMCVSOutput);\n

in https://examples.vtk.org/site/Cxx/Shaders/ColorByNormal/, but how can i change the triangle color by its normal and camera normal?
① how to define the triangle color instead of diffusecolor
② how to get the camera's normal in shaders priority.

Based on your response, I guess I need to make modifications using the OpenGL language. Could you please provide the relevant code?

Or is there another way to make the two faces of a triangle appear differently under lighting, such as making one side brighter and the other side darker? I tried to modify DiffuseColor, but it didn’t work.

Hello,

Please, take a look at this: How to get the viewing angle relative to the normal in a GLSL fragment shader? - Stack Overflow. It has even a browser-runnable example in WebGL.

GLSL code for the vertex shader (the shader in which you can do geometry computations). Notice the out modifier of the viewNV vector, signaling you want to communicate it to other shaders down the rendering pipeline:

in vec3 inPos;
in vec3 inNV;

out vec3 viewNV;

uniform mat4 u_projectionMat44;
uniform mat4 u_viewMat44;
uniform mat4 u_modelMat44;

void main()
{   
    viewNV      = mat3(u_viewMat44 * u_modelMat44) * inNV;

    vec4 pos    = u_viewMat44 * u_modelMat44 * vec4( inPos, 1.0 );
    gl_Position = u_projectionMat44 * pos;
}

You actually need only the viewNV information, but writing to the built-in gl_Position variable is required in order to have a valid vertex shader.

Next, here’s the GLSL code for the fragment (pixel) shader (the shader where you can calculate the pixel color). Notice it receives the viewNV vector (the in modifier) previously computed in the vertex shader:

in vec3 viewNV;

void main()
{
    vec3  N      = normalize(viewNV);
    vec3  L      = vec3(0.0, 0.0, 1.0);
    float NdotL  = dot(N, L);

    vec3  color  = vec3(NdotL, 0.0, 1.0-NdotL);

    gl_FragColor = vec4( color.rgb, 1.0 );
} 

The fragment shader above will give redder hues for pixels of faces facing the camera and more violet hues for faces more edge-on.

I hope this helps,

PC

Thank you. I will try it. :grinning:

1 Like

Thank you for your answer.
by looking for the vtk function, i found that the actor can use SetBackfaceProperty, which can solve the problem. anyway, thank you for your answer.

the complete code is
vtkSmartPointer backProperty = vtkSmartPointer::New();
backProperty->SetColor(colors->GetColor3d(“Red”).GetData());
actor->SetBackfaceProperty(backProperty);