setShaderAuto/setShaderOff on nodes

Hi all,

Quite new to Panda3D, but having a blast… I ran into some unexpected behaviour, that neither the manual or forum posts seem to cover. I’m doing something wrong, yet I am very sure I’m following the right steps. Please prove me wrong, 'cause I can’t get it to work.

Problem is with setShaderAuto() and setShaderOff(), especially on nodes in the scene graph. Setting on render works as expected, but anything below that (even with a priority given) seems to do nothing. A node.reverseLs() shows the scene graph is working as I’d like, and the attributes are set:

PandaNode render S:(AntialiasAttrib CullFaceAttrib LightAttrib RescaleNormalAttrib)
PandaNode Models
PandaNode Actors
PandaNode Bots S:(ShaderAttrib)

In this case I did a setShaderAuto() on node Bots, but no shadows are shown. If I do setShaderAuto() on the render root, everything gets shaded, even nodes that I used setShaderOff() on. It seems to be all or nothing on de render root, but no way to change the behaviour down the tree.

I feel like I am missing something really basic, but after shuffleing my code around for a few hours, I can’t figure out what it might be.

Any ideas?

Hi, welcome to the forums!

The shader needs to be applied to the nodes that are receiving shadows, not to the ones that are casting the shadows.

Hi, thanks for replying so fast. I think I know what you mean, and I think I implemented that correctly. The shader is applied to the bots node, which has a few nodes with models attached. The caster is a spotlight that has shadow casting set (self.spot_light.node().setShadowCaster(True, 1024, 1024)).

Like I said, it works when I apply setShaderAuto() to render, but it doesn’t if I apply the same method to a node other than render…

I tried to simplify, to see if that fixed anything… but it didn’t:

        bot = loader.loadModel('models/bot')
        bot.reparentTo(render)
        render.setShaderAuto()

This gives my bot the expected drop shadow. But:

        bot = loader.loadModel('models/bot')
        bot.reparentTo(render)
        bot.setShaderAuto()

doesn’t.

What I mean is that the floor will not show the shadow of the bot unless the floor node has setShaderAuto() applied. You need to make sure that all the objects that need to have the shadow projected onto them have the shader.

With the code you showed, the bot (and other things in view of the light) will only cast shadow on other bot parts.

1 Like

Oh my god… why didn’t I think of that. You are absolutely right, and from a rendering stand point it makes sense. I was thinking like a human.

I applied setShaderAuto() to the floor and it works like expected now. Thank you so much!