SetTexture makes model black

Hello, I am attempting to create an animated texture by cycling through texture stages. However, when I use setTexture on my model, no texture is applied. This is how I have it set up:

tex = loader.loadTexture('../models/tex/transgradiet.png')
self.trail = loader.loadModel('../models/kick1trail.glb')
ts = TextureStage('texstage')
ts.setPriority(0)
ts.setSort(0)
self.trail.setTexture(ts,tex)

Using self.trail.ls() prints None
findAllTextureStages() prints
TextureStage default TextureStage texstage

Any help is greatly appreciated!

Just set the priority to one.

Although, I suspect that you are using simplepbr and you need to set the material as well. And use mode texture stage.

my_material = Material("material")

tex = loader.loadTexture('../models/tex/transgradiet.png')
self.trail = loader.loadModel('../models/kick1trail.glb')
ts = TextureStage('texstage')
ts.setMode(TextureStage.MModulate)
ts.setSort(0)
self.trail.setMaterial(my_material, 1)
self.trail.setTexture(ts, tex, 1)

Yes, I am using simplepbr. I added a material and set priority to one using your code, and it still appears black. It even appears black when I do not use simplePBr. Do you have any idea what the issue might be?

Do you have any lights in your scene? (Even if only an ambient light.)

Yes I do, and all other models (that arent using setTexture) appear fine.

Hmm… I’m guessing that the material for the model exists on a child-node of “self.trail” (due to the way that models are generally loaded in Panda, I believe). I wonder then whether the call to “setTexture” isn’t resulting in a new material being made on the parent-node that’s overriding what’s present on the child-node…

So. Panda has a method that allows you to replace a texture where it’s found, and to do so recursively in a given scene-graph (or part thereof, as in this case). It also has methods that allows you to search for a known texture. Between them, it should be possible to change your textures in a find-and-replace manner.

Something like this, I imagine (untested):

oldTexture = self.trail.findTexture(<old tex-file here>)

newTexture = loader.loadTexture(<tex-file here>)

self.trail.replaceTexture(oldTexture, newTexture)

You may have to do some investigation to determine the proper name to give to “findTexture”.

By the by:

The “ls()” method does indeed return “None”, and thus isn’t useful in a “print”-statement–however, the call should itself print output to the terminal.

i.e.:

print( myNodePath.ls() ) # Prints "None"

myNodePath.ls() # Prints the NodePath-hierarchy for "myNodePath"

On another note, have you looked at using the “VideoTexture” class in order to produce your animation?

So when I use self.trail.findAllTextures(), I see two textures, one called pbr-fallback and transgradiet (my desired texture).

I replaced pbr-fallback with transgradiet as per your suggestion, and the model still appears black, however the only texture in self.trail.findAllTextures() is transgradiet.

I have thought about using VideoTexture, however, animating the texture by cycling through texture stages better suits my purposes.

Ah, I was thinking that you would replace your own texture, not “pbr-fallback”. Still, the fact that even then you’re only seeing black is odd.

Could you perhaps put together a simple model and texture that demonstrates the problem, so that we can examine it ourselves and try to investigate what’s going on? Ideally something very simple–just a cube and a single-colour texture, for example.

here is a plain cube and 2 textures, when I attempt to set the texture to “papertex”, the model appears white, and when I attempt to set it to “transgradiet”, it appears black.

1 Like

Ah, I think that I might have an idea: Does your model have UV-coordinates?

My guess is that it doesn’t, and that what’s happening is that you’re seeing just one (sub-)pixel from each texture. In the case of the paper texture, that happens to be a white pixel; in the case of the transparent texture, that happens to be a black pixel.

1 Like

Ah, that seemed to be it, thanks!

1 Like

It’s my pleasure! I’m glad if I’ve helped. :slight_smile:

1 Like

I just had one more question about setting UV coordinates. I was able to get the texture to appear when I used setTexGen, however, I want to use the uv coordinates defined in my model. is there a way to do this? when I apply the texture in my exported model, it appears the way I want it to.

Generally speaking, I believe that it’s something that’s applied in the 3D modelling program.

If by this you mean within your 3D modelling program, then it may be that said package is using automatically-generated coordinates to do so–but these presumably are either not available to or not observed by the exporter.

So, it may be that more-explicitly-defined UV-mapping is called for. If you search online you should, I daresay, find tutorials regarding this for your modelling program!