TextureProjection Iimitations?

Is there a limit to the number of setTexProjector calls you can make on a NodePath, or any limitations on any of the components there of, that could cause odd behavior?

The reason I ask is because I set up some simple shadowing using texture projection, and I’m getting an error I can’t wrap my head around. I have 4 vehicles racing along a track. They are 4 instances of the same class. In that class is a function that sets up a “shadow” as a texture projected onto the track. When I run the game, 2 of the vehicles have a proper shadow. 1 has no shadow. 1 has 2 shadows (or, sometimes, one shadow). I am making the assertion that it is 2 shadows because it is much more opaque than it should be, but is still showing some transparency on the edges where the image is fuzziest.

Here’s the code in the vehicle class that creates the shadow. Note that I refer to shadows as light, because my vehicles have glowing crap on the bottom and therefore should cast light, not shadow. Functionally, it’s the same as a shadow.

	def setupLight(self):
		self.lightCaster = render.attachNewNode(LensNode("Light Caster"))
		lens = PerspectiveLens()
		self.lightCaster.setPos(0, 0, 10)
		self.lightCaster.setHpr(0, -90, 0)

		tex = loader.loadTexture("Images/Utilities/Shadow.png")
		tex.setBorderColor(VBase4(0, 0, 0, 0))
		self.projTS = self.track.getTexProjection()
		self.track.track.setTexture(self.projTS, tex)
		self.track.track.setTexProjector(self.projTS, NodePath(), self.lightCaster)

And this is the getTexProjection method of the track class that it calls:

	def getTexProjection(self):
		projTS = TextureStage("ProjTexStage")
		self.track.setTexGen(projTS, TexGenAttrib.MWorldPosition)

Any thoughts on how I could possibly be misplacing a shadow onto another vehicle, or losing it entirely?

There is a limit to the number of different TextureStages you can simultaneously apply to a given piece of geometry. If you exceed this limit, some of your textures will not be visible. This limit is built into the graphics hardware and can be queried with base.win.getGsg().getMaxTextureStages(). Is this what you’re experiencing?

To a certain extent you can avoid this limit by using a shader (such as the auto-shader). When you are using a shader, there is not a hard limit on the number of textures, but additional textures will increase render time (and you will eventually reach a hard limit of shader complexity).


Okay, base.win.getGsg().getMaxTextureStages() is reporting 4, so that’s probably the issue. Does the AutoShader have anything built into it that would me do a bunch of texture stages? I want eight shadows, so Including the stage for the base texture, I need nine.

Nine is a lot.

You can simply turn on the auto-shader and see if it works; but if it doesn’t, you might need to find another approach.


Is nine too many for a custom shader? I suppose I need to learn to code shaders either way.

Before I was trying to achieve the desired effect by putting point lights underneath the cycles, but I got shader complexity errors doing that.

You won’t do much better with a custom shader than with what the auto-shader makes for you. The limit is just in the number of instructions you can execute per pixel, and nine texture fetches will add up to a bunch of instructions. Probably cheaper than a bunch of lights, though, so it’s still worth a try. Why not try it now? It just takes one line of code to enable the auto-shader.


I can’t use the autoshader with texture projection because the autoshader gets recompiled every frame, as you have informed me early today. :slight_smile:

[url]AutoShader and Texture Projection[SOVLED]]

Well, you can still use it; it will just be slow. But at least you’ll know whether it will work or not.

You can also install the buildbot version and try that to verify that it will no longer be slow in 1.8.0.


I have no experience with buildbot, but I’m guessing it’s some sort of code repository. I don’t really know how those work, and if I’d have to compile something, that would be new to me too.

So I suppose I’m just going to have to figure out another way to put non-black shadowing on my track.

Sometimes I really, really wish I’d gotten a CS degree instead of fine arts degree.

By “buildbot”, I just mean the devel builds at the top of the list of available builds for download under the SDK link. The buildbot is a server which is constantly building a snapshot of the latest development version, for early adopters to download and install like any other version. If you download and install this (and uninstall 1.7.2 for good measure), you will be running a pre-release version of Panda3D 1.8.0.


It’s a self contained installer? I can handle that, I bet. It’s 5 o’clock here, so I’ll think about it and maybe try it tomorrow.

Yeah, it is. Just click the “devel” link at the version list on the download page.