I'm currently studying opengl shaders but I can't figure out something: how to apply different shaders to the objects, for example, a teapot rendered using toon shader and another one in the same scene using a very reflective surface and other distorted from a noise function, like in this video


Another one is applying a bloom shader in a scene and a motion blur shader afterwards. How to achieve those effects when you can only have one vertex shader and one fragment shader? Is there any trick such as using more than one shader program?

  • \$\begingroup\$ Re Nathan and David's good answers, this is why you see the term render pass or shader pass; there are multiple passes required to compose the final image/frame. One of the reasons why GPU processing has become so damned parallel and thus so fast is the need for multiple passes per frame. Go back to the Quake II or Half Life software renderers to remind yourself just how much love shader passes add to the whole 3D graphics experience. \$\endgroup\$
    – Engineer
    Jan 11, 2012 at 2:36

4 Answers 4


The simple answer is you change them between each draw call. Set a shader, draw a teapot, set another shader, draw another teapot.

For more complex stuff where you need to apply multiple shaders to just one object such as blur, glow and so on. You basically have everything rendered to texture(s). Then you render a quad over your entire screen with that texture applied while using another shader.

For example if you want to render a glow effect, you first need to render your regular non-glowing scene, then render just the colored silhouette of the stuff that you want to glow on a texture then you switch to a blur shader and render your quad with that texture attached over your non-glowing scene.

There is another technique called Deferred shading where you render the scene without lighting and apply it later in screen space. The core goal is to reduce the expense of per pixel lighting.

Normally you render a color buffer which is put on the screen. With deferred shading you instead render a color buffer as well as a normal and depth buffer in one shader pass (you can store the normal vectors and the depth in a texture like with normal and height mapping).

This means that, for every pixel, you know the position of the nearest piece of non transparent geometry (depth or distance from eye) the color and the normal. Because of this you can apply lighting to each pixel on the screen instead of to each visible pixel of every object you render. Remember that some object will be drawn over the top of other objects if the scene isn't perfectly rendered in front to back order.

For shadows you actually render just the depth buffer from the point of view of your light then use that depth information to work out where the light strikes. That's called shadow mapping (there is also another approach called shadow volumes that works out a silhouette of the geometry and extrudes it, but your still going to be using shaders.).

With more modern OpenGL (3.0+) you use a Framebuffer Object with Renderbuffers Objects attached. Since renderbuffers can be treated like a texture. You might do things like have 1 shader render to multiple different renderbuffers (so you don't have to render your texture then your normals then the glow components) but the underlying practice is still the same.

Also it's desirable to minimize the number of shader switches as much as possible to save on overhead. So some engines will group everything with the same material together so it can all be drawn at once.


You just bind one shader, render all the objects using that shader, then bind the next shader, render the objects using that one, etc.

You can have as many shader objects (shaders loaded into memory and compiled) as you want; only one can be bound (active) at a time.

  • 5
    \$\begingroup\$ In terms of implementation, in every frame I use glUseProgram(1) and glUseProgram(2) to change shaders? How costly for performance is that? \$\endgroup\$ Jan 11, 2012 at 12:09
  • 5
    \$\begingroup\$ It's a nontrivial cost (although less on recent GPUs than earlier ones). That's why most people sort their objects by material, rendering all the objects with the same material together. But you can certainly afford to change programs tens to hundreds of times per frame, if not more. \$\endgroup\$ Jan 11, 2012 at 17:34

Using more than one shader in a scene is quite simple; change the shader, set the values for it, then render the object.

Beware, however, switching shaders can be costly, so shader switching should be kept to a bare minimum. There are a few ways to reduce this impact while getting all of the effects you want.

The first method, and usually the most desirable, is to add the functionality for all your shader techniques to just one shader and use conditions you set to render each object in a different way with the same shader. I don't know about OpenGL and GLSL shaders but with HLSL shaders and DirectX these can be grouped together as a "technique" and you can set the technique instead of changing the shader. This allows you to actually have several different pixel and vertex shaders in the same file.

The second way to reduce performance impact is to set the shader, render every object that uses that shader, then repeat. In other words, batching your rendering.

If you wish to apply two different effects to the same object (i.e. apply say a toon shader then some lighting) you can do it in two different ways. The first is to write a shader that applies multiple effects in the same function. The second way is to render the model once with each shader and blend the results by setting different blend options. However, this is a lot more work, and not achievable in all circumstances. Therefore the best option is to combine all your effects into one shader.


Another way of doing that I have discovered is through something called glsl subroutines, where each type of shader is defined in one function, and in the OpenGL application, we can define the current subroutine, draw the vertex of a buffer, change the subroutine and rendering another buffer

  • 4
    \$\begingroup\$ This requires GL 4.x-capable hardware, which is DX11-class hardware. \$\endgroup\$ Jan 30, 2012 at 0:59
  • \$\begingroup\$ ... which no longer is a problem unless supporting obsolete hardware is a goal. The vast majority of people use cards (or iGPUs) capable of at least OpenGL 4.0. \$\endgroup\$
    – Zoe
    Nov 6, 2022 at 9:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .