Custom shader and setShaderAuto

For my terrain I have a shader, which blends the my textures according to some specified texture maps. Like in this thread. … 3404#17470

However my directional lights and fog do not affect the terrain. Even with setShaderAuto called.

The shaders are being applied to other objects (e.g. the teapot I attached to my camera).

How do I overcome this? Can I do another run over the terrain with the auto shaders (simplest for me), or do I have to include these things (lights/fog etc) in my terrain shader manually (less simple, but doable)


My first response would be that you need to build that kind of thing into your own shader, since once you decide to use shaders at all, all the usual blending operations are replaced by whatever your shader does.
However, whenever I speak out too adamantly on the way I would do things, I seem to get corrected by someone who knows undocumented engine shortcuts I never even dreamed of, so there may be a way to specify more than one shading pass (although it would be tricky, since after one pass you’ve effectively reduced your geometry to a flat image…).

Regardless, my current understanding is that SetShaderAuto() sets up a node to use the Panda auto-generated shaders (which have documented limitations), and is mutually exclusive with a manual setShader() call.

You can get a couple of multitextures using texture stages - allows up to 3 different detail textures on most older cards. If you want to even remove that limit, call setShaderAuto on your model - then you’re basically letting the auto-shader do the blending.

For TexScale to work, it requires Panda’s 1.7.0 trunk, though.

# Stage 1: alpha maps
ts = TextureStage("stage-alphamaps")
root.setTexture(ts, loader.loadTexture("l3dt/terrain_Alpha_2.png", "l3dt/terrain_Alpha_3.png"))

# Stage 2: the first texture
ts = TextureStage("stage-first")
root.setTexture(ts, loader.loadTexture("rock.png"))
root.setTexScale(ts, 256, 256)

# Stage 3: the second texture
ts = TextureStage("stage-second")
ts.setCombineRgb(TextureStage.CMInterpolate, TextureStage.CSTexture, TextureStage.COSrcColor,
                                             TextureStage.CSPrevious, TextureStage.COSrcColor,
                                             TextureStage.CSLastSavedResult, TextureStage.COSrcColor)
root.setTexture(ts, loader.loadTexture("grass.png"))
root.setTexScale(ts, 256, 256)

# Stage 4: the third texture
ts = TextureStage("stage-third")
ts.setCombineRgb(TextureStage.CMInterpolate, TextureStage.CSTexture, TextureStage.COSrcColor,
                                             TextureStage.CSPrevious, TextureStage.COSrcColor,
                                             TextureStage.CSLastSavedResult, TextureStage.COSrcAlpha)
root.setTexture(ts, loader.loadTexture("dirt.png"))
root.setTexScale(ts, 256, 256)

That’s a pretty good point. I completely overlooked that you mainly just want to blend textures. What end effect are you trying to accomplish? There are a variety of custom blend options documented in the manual if the basic decal/modulate/replace/etc. don’t cut it. My experience has largely been that PNGs are well-supported for transparency, so you may not even need the custom alpha map handling that other thread was addressing depending on what you want to do.

That won’t work, since you’ll want the detail texture to have a tex scale, but the alpha map stretched across the terrain. That is not supported if you put it in the same texture stage.