2
votes

I have an OpenGL shader program which renders a cube. To colour the cube, I pass the normal of each vertex to the vertex shader, and calculate its greyscale shade with respect to a point light source.

However, I now want to also render a red triangle, whose colour is always red and does not depend on lighting. But if I just pass the normal to the vertex shader as before, the triangle's colour will be affected by the light.

What is the best solution for this? Should I calculate the vertex colour before the shaders, and pass that to the vertex shader? Or is that bad practice?

2

2 Answers

6
votes

There are two main options:

  1. Use one shader program that is flexible enough to handle both cases.

    For a shader that applies basic lighting, it is common to pass in values (typically as uniforms) that determine the weight of the ambient and diffuse terms in the lighting equation. With a shader like this, if you want a solid color for part of your objects, you simply crank up the ambient term all the way by setting the uniform accordingly.

  2. Use different shader programs.

Each one has benefits, and you have to figure out which works best for you.

The main downside of approach 1 is that your shader might do more work than needed. In this example, it will still evaluate the diffuse term of the lighting equation for the solid objects, even though it does not contribute to the final result. If you draw a lot of solid geometry, that could hurt performance.

The main downside of approach 2 is that you have to switch shaders. If you frequently switch between solid and lighted rendering, that can hurt performance. One way to work around this is that you first draw all lighted objects, then all solid objects, so that you have to switch shaders only once per frame. Depending on your software architecture, that may be easy to do, or it could require significant restructuring.

1
votes

Create another shader program that uses a fixed color as the output, since there are two types of rendering you want to do, is better to separate it accordingly.