Using setShaderAuto() with custom shaders on cameras.


I’m trying to do something very similar to the advanced cartoon shader tutorial (, but I want to use regular shaders for the main camera. I’ve found that when I call render.setShaderAuto(), I can not use the camera.setInitialState() method to set a custom shader for a secondary camera that renders to an offscreen buffer, e.g.

tempnode = NodePath(PandaNode("temp node"))

The camera just uses whatever shaders were assigned to the model by setShaderAuto(). This is easily demonstrated by adding “render.setShaderAuto()” near the top of init() in

I can live without setShaderAuto(), but I’m under the impression that it gives a nicer-looking render. Is there a way to get my custom camera working?


The problem is that the state you assign with the setInitialState() is implicitly above the render node, and then the setShaderAuto() call on the render node replaces the setShader() call on your initial state.

So, you have several choices:
(1) Don’t assign setShaderAuto() to the render node, but instead assign it to the initial state of the default camera. This way your two different cameras have different shaders assigned, but render (which is seen by both cameras) doesn’t specify one or the other.

(2) Use a priority override on the setShader() attribute given to your setInitialState(). Any priority greater than the default value of 0 would be fine; we usually use 1. A priority override means that a higher-level attribute can override a lower-level attribute, so this would cause your setShader() to override the setShaderAuto() on render. Do this with an optional second parameter to tempnode.setShader(), e.g. tempNode.setShader(myShader, 1).

(3) Don’t use the setInitialState() call to assign the state for your auxiliary camera, but use the tag state keys instead. This allows you to specify the shader on a lower node instead of above render. However, it’s a bit clumsier to use.

You could go other routes, too, involving more convoluted scene graph structures, but it just gets silly.


Thanks so much! Solution #1 seems so obvious now that you tell me. Solution #2 also makes good sense now – I was looking for an override parameter in setInitialState() but didn’t think to use the one for setShader().