Textures wrap and not using materials?

Hello,
I’m new in Panda, but I used some other engines like Unity3D (and others).

I cannot understand why some “effects” are applied at textures level and not “material” level.
For example, wrapping UV is applied to textures, but I don’t understand why it is not a material feature.
In fact, I can load a texture, then I will decide, using materials, if that texture will be clamped or wrapped (using repeat) over a specific model.

Maybe I’m missing something.
Can you help me to understand the pipeline? How can I apply the same texture using different wrapping modes to different models?

Thank you for your help!

Panda3d has a very exposed API, you as the programmer have access to… everything, this is one of Panda’s original design goals. Tools like Unity3D (from what I have seen) are more specific at hiding what actually goes on in the background.

When a texture is applied to a model, it has several things attached to that, UV coordinates, and the mode as to how it’s applied (stretch, clamp, etc) those are naturally, and programmatically, tied to a texture.

A material in a sense, is a different programmatic stage, and while it also has ties to a texture, is a very different place in code. A model can have a texture, and UV coordinates, with a texture mode (clamp, stretch, etc) without explicitly having a material assigned to it.

Normally most of this fun jazz would be hidden behind your modeler/exporter (be it Blender, Maya, etc) otherwise you’d have to refer to the manual and lay out the code for each model, etc. For that you can refer to most of the manual pages on Materials, Texturing, etc.

This is just from my knowledge, and perhaps someone who has a little bit more knowledge will clarify anything else or anything obscure I’ve said.

Hope this helps,
~powerpup118

In most moddeling packages a ‘material’ holds all the data about how a model should look when rendered. This includes texture images, but also things like gloss, glow, transparency, refraction and shading method.
Usually a texture is added to a material and a material is added to a model. I think some game sdk also use this convention.

In Panda3D a model has texture ‘slots’ (stages) and a ‘slot’ for a material. Both are independent.

Thank you, I understood the concept.
Instead of working on pure materials (shader+texture+fx=material) I need to work on the model, using the slots.

Thank you!

Hello,
I red some info about stages, but I found only the class “TextureStage”. So it means stages belong to textures not models.
Can you give me a link to read how texture stages and models and materials work?

Thank you!

I was thinking this is a simple thing, but it’s not. In fact I’m not sure if it’s not a bug.

I was thinking it should work like this:

from panda3d.core import *
import direct.directbase.DirectStart


box1=loader.loadModel('box.egg.pz')
box1.reparentTo(render)

box2=loader.loadModel('box.egg.pz')
box2.reparentTo(render)
box2.setPos(2, 0, 0)

texture=loader.loadTexture('maps/envir-ground.jpg')

box1.setTexture(texture, 1)
box2.setTexture(texture, 1)

box1.setTexScale(box1.findTextureStage('default'), 2, 2)
box2.setTexScale(box2.findTextureStage('default'), 3, 3)

box1.getTexture().setWrapU(Texture.WMClamp) 

box2.getTexture().setWrapV(Texture.WMClamp) 
 
run()

box1 should have the U clamped and box2 V clamped… but both have U and V clamped!

Even if I load the texture twice it’s still the same:

from panda3d.core import *
import direct.directbase.DirectStart


box1=loader.loadModel('box.egg.pz')
box1.reparentTo(render)

box2=loader.loadModel('box.egg.pz')
box2.reparentTo(render)
box2.setPos(2, 0, 0)

texture=loader.loadTexture('maps/envir-ground.jpg')
texture2=loader.loadTexture('maps/envir-ground.jpg')

box1.setTexture(texture, 1)
box2.setTexture(texture2, 1)

box1.setTexScale(box1.findTextureStage('default'), 2, 2)
box2.setTexScale(box2.findTextureStage('default'), 3, 3)

box1.getTexture().setWrapU(Texture.WMClamp) 

box2.getTexture().setWrapV(Texture.WMClamp) 
 
run()

Yes, that’s the point. I’m studying how textures/materials/shaders/models work, and I think there is something I don’t understand about textures modification.
In fact, it seems (sorry but I’m new in Panda) that everything you load (textures, models, etc…) are loaded only once but instanced (reference) multiple times, unless (I think…) one can explicitly make copies.
So I think if you load a texture twice you have 2 references to the same texture. But if I need to apply different UV using the same texture, I think is crazy I need to load two copies (not reference but real copy/duplicate) of a texture.

So…?

Update: I tried your example and it works well! In fact I have two boxes with different texture wrap.

I didn’t know the method setTexScale(). But the problem is still the same for other texture effects: TextureStage()/ alpha / UV, etc…

I think one needs to load a texture, then I “wrap” or apply effects based on the texture. I don’t need to apply effects to the texture self!

I will check more methods and will do more tests.
Please help me you too in order to solve this problem!

UPDATE: You need to modify the program in order to use a single texture: I wish to load one texture but I need to apply to different models using different parameters.

setTexScale() in my sample makes the texture smaller, so the wrap mode will be visible… but maybe that’s what you were after in the first place? Not wrap modes (panda3d.org/manual/index.php … Wrap_Modes ) but simply making a texture repeat itself over the model?

from panda3d.core import *
import direct.directbase.DirectStart 


box1=loader.loadModel('box.egg.pz') 
box1.reparentTo(render) 

box2=loader.loadModel('box.egg.pz') 
box2.reparentTo(render) 
box2.setPos(2, 0, 0) 

texture=loader.loadTexture('maps/envir-ground.jpg') 

box1.setTexture(texture, 1) 
box2.setTexture(texture, 1) 

box1.setTexScale(box1.findTextureStage('default'), 1, 1) 
box2.setTexScale(box2.findTextureStage('default'), 6, 6) 

This works. Ok, I understood.
Basically when you assign a texture to a model, you will “insert” the texture in a model’s stage.
Later you can grab the stage and applying different effects to that texture stage (TextureStage).
Two models have different stages, and in this way I can apply different effects to the same texture.
I will make a couple of tests more, but I think this is the way!

That’s about right :wink:

I did some digging on the forum and come up with this topic:
panda3d.org/forums/viewtopic … t=setwrapu

So, you can use makeCopy() to… well… make a copy of the texture and apply a different wrap mode to it (if you still need that), but you will end up with two copies of the same texture in memory.

from panda3d.core import *
import direct.directbase.DirectStart


box1=loader.loadModel('box.egg.pz')
box1.reparentTo(render)

box2=loader.loadModel('box.egg.pz')
box2.reparentTo(render)
box2.setPos(2, 0, 0)

texture=loader.loadTexture('maps/envir-ground.jpg')
texture2=texture.makeCopy()

box1.setTexture(texture, 1)
box2.setTexture(texture2, 1)

box1.setTexScale(box1.findTextureStage('default'), 2, 2)
box2.setTexScale(box2.findTextureStage('default'), 3, 3)

box1.getTexture().setWrapU(Texture.WMClamp) 

box2.getTexture().setWrapV(Texture.WMClamp) 


run()

Well, finally it seems there are not so big constrains. In fact using Texture Stage one can change offset, scale, rotation, etc… The only constrain is WRAPPING mode.

Thank you!