Panda3d Materials

Hi there

I recently resorted to using panda3d’s internal materials, because
some material properties don’t quite export from blender.
However, the materials look grainy while other properties have no effect when applied using python e.g. setDefuse

from direct.showbase.ShowBase import ShowBase
from panda3d.core import *
from panda3d.core import Material

class MyApp(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)
        self.model = loader.loadModel("models/model.egg")
        self.dlight = PointLight('my dlight')
        self.dlight.setAttenuation((1, 1, 1))
        self.dlnp = render.attachNewNode(self.dlight)
        #Texturing the model
        self.myMaterial = Material()
        self.myMaterial.setRoughness(1.0)
        self.myMaterial.setSpecular((5,2,1,0.5))
        #self.myMaterial.setShininess(100.0) #Make this material shiny
        #self.myMaterial.setAmbient((0.45, 0.14, 0.04, 1)) #Make this material blue
        self.myMaterial.setTwoside(True)
        #self.myMaterial.setDiffuse((0,0,0,1))
        self.myMaterial.setEmission((350,140,70,1))
        self.modelNM = loader.loadTexture("models/tex/modelNM.png")
        self.modelDF = loader.loadTexture("models/tex/modelDF.png")
        self.model.setMaterial(self.myMaterial,1)
        
        self.model.setTransparency(True)
        self.model.setTransparency(TransparencyAttrib.MDual)
        self.model.set_two_sided(True);
        self.modleNM_ts = TextureStage('ts')
        self.modleNM_ts.setMode(TextureStage.MNormal)
        self.model.setTexture(self.modleNM_ts,self.modelNM)
        self.model.setTexture(self.modelDF)
        render.setLight(self.dlnp)
        
        self.model.setMaterial(self.myMaterial) #Apply the material to this nodePath        
        self.model.reparentTo(render)
        render.setShaderAuto()

app = MyApp()
app.run()

.
Any ideas on what I could be doing wrong?
May someone please help.

Best regards

If you are using a texture, then the setDefuse method is invalid. You can use self.model.setColor(0, 1, 0, 1) if you want to set the tinting for the texture.

To set values that affect the output color, you should use values in the range 0.0 - 1.0

Hi there

@serega-kkz
Thank you for the help I really appreciate.
The specular and shininess are not effective. While the grainy image remains a problem.

Best regards.

Regarding “setSpecular”, it looks to me as though the same issue is present there as was with “setEmission”: the values that you’re passing in for each channel go above the maximum of 1.

(Aside from the value being passed in for the alpha-channel–and I’m not sure at all of what effect that might be having; I’d suggest setting it to 1.)

Regarding “setShininess”, I’m not sure of why that might not be working; at a guess, perhaps it’s the same issue, with the specular-colour being so over-intense that it’s overwhelming the effect of the material’s shininess-value.

(Well, other than the fact that it’s commented-out in the code above, of course.)

However, there is one caveat, it looks like the shader generator has never processed mirror shine, so these two parameters specular and shininess have no effect.

I noticed this during the discussion of this topic: Trying to obtain Panda3ds synthesized shaders (or looks) - #33 by jnpickee

In this connection, I tried to remember if I had ever seen a mirror shine when using a standard shader generator, but I could not remember anything.

1 Like

Hi there

@serega-kkz
@Thaumaturge
Thank you for the help, I really appreciate it.

I had originally used values within 0 and 1 without effect, that is how, I came to trying those astronomical values.

Any Ideas as to what could be causing the grainy image?
Normal maps applied in blender look fine, however, applying the same normal map directly in panda3d produces a grainy result.
I do not know what is causing it or how to fix it.
Please help.

Best regards

I think you’d better post a screenshot of what you call graininess. Or attach a sample code with resources to the message.

Hi there

I apologize, a took a bit of time.
Here’s a bit more info.

The above models had their textures applied in blender3d.

The second image is of models with textures applied directly in panda3d, with the ground model being an exception.
It is a lot closer to what I am trying to achieve; if only I could get rid of the graininess.

The image file size is a bit large, so I will have to setup a file sharing resource, before I can post the sample code files.
I apologize.

Best regards.

The first thing that comes to mind is that the filtering mode is not used.

https://docs.panda3d.org/1.10/python/programming/texturing/texture-filter-types

I think setting the filtering to linear mode should fix this.

Looking closely, it appears to me that the graininess is some form of transparency–it looks as though the model has black-and-white “noise” in the alpha (i.e. transparency) channel of some texture that’s affecting it.

So, do you perhaps have a texture–any texture–applied to the model or some node above it in the scene that has such grain in its alpha channel…?

(Note: Whether that transparency shows up elsewhere in Panda or not–it may not be visible on a node that doesn’t have a relevant transparency setting applied. If there’s nothing obvious, it might be worth checking your textures yourself in whatever image-viewer you have installed on your system.)

Hi there

@serega-kkz
Thank you for the help I really appreciate it.
I tried the filtering, it did not quite work. Some filtering options remove the graininess, but make the alpha channels reflective.

@ Thaumaturge
Thank you for the help I really appreciate it.
You are right, the grainy looking texture has alpha channels.
Here it is.

It does not seem to have any grain in the alpha channel, though I can’t be sure.

Here is the code snippet.

from direct.showbase.ShowBase import ShowBase
from panda3d.core import *
from panda3d.core import Material
from direct.gui.DirectGui import *
try:
    import Tkinter as tk
    import tkFileDialog as fd
except:
    import tkinter as tk
    from tkinter import filedialog as fd
    

class MyApp(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)
        self.modelPath = "grass.egg"
        self.model = loader.loadModel(self.modelPath)
        self.dlight = DirectionalLight('my dlight')
        #self.dlight.setAttenuation((1, 0, 1))
        self.dlnp = render.attachNewNode(self.dlight)
        self.modleNM_ts = TextureStage('ts')
        self.modleNM_ts.setMode(TextureStage.MNormal)
        self.modelNM = loader.loadTexture("tex/modelNM.png")
        self.modelDF = loader.loadTexture("tex/modelDF.png")
        self.modelDF.setMagfilter(Texture.FT_linear)
        self.modelDF.setMinfilter(Texture.FT_linear)
        self.model.setTexture(self.modleNM_ts,self.modelNM)
        self.model.setTexture(self.modelDF)
        self.model.setTransparency(True)
        self.model.setTransparency(TransparencyAttrib.MAlpha)
        self.model.set_two_sided(True) 
        render.setLight(self.dlnp)      
        self.model.reparentTo(render)
        render.setShaderAuto()
    
app = MyApp()
app.run()

Best regards

Hmm… In Blender, how are you applying that texture to your model? Are you using a UV map, and if so, just one, or multiple?

Hmm, the texture size is not a power of two, this may be a problem. Try using only 2048.

For me, textures with alpha channel work fine.

from direct.showbase.ShowBase import ShowBase
from panda3d.core import TextureStage, PointLight, NodePath, Material, Texture, SamplerState

class MyApp(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)

        model_tex = loader.load_texture("tree.png")
        model_tex.set_magfilter(SamplerState.FT_linear_mipmap_linear)
        model_tex.set_minfilter(SamplerState.FT_linear_mipmap_linear)

        model = loader.load_model("plane_1x1.bam")
        model.set_scale(5)
        model.set_transparency(True)
        model.set_texture(model_tex, 1)
        model.set_two_sided(True)
        model.reparent_to(render)

        plight = PointLight('my dlight')
        plight_np = NodePath(plight)
        plight_np.set_pos(0, 0, 5)
        plight_np.reparent_to(render)
        render.set_light(plight_np)

        render.set_shader_auto()

app = MyApp()
app.run()

plane_1x1.bam (925 Bytes)

Hi there

@serega-kkz
Thank you for the help, I really appreciate it.
I tried out the sample you provided. It also works on my system. That probably also has to do with the fact that it is only one plane. The problem seems to pop up when there are multiple objects with alpha channels in close proximity.
The manual describes it here.
https://docs.panda3d.org/1.10/python/programming/texturing/transparency-and-blending
I also changed the texture sizes, it does not seen to have any visible effects.

@Thaumaturge
Thank you for the help, I really appreciate it.
I am using a single UV per object.

Here the link to the code file

Best regards.

Interestingly, running your code (and using your models and texture) on my own system I don’t see the issue that you’re seeing on your system:

So I suppose that my next few questions are these:

  • What version of Panda are you using?
    • You should be able to find this by adding the following to your program:
      from panda3d import __version__ as pandaVersion
      print (pandaVersion)
  • What version of Python are you using?
    • Similarly, you should be able to find this by adding the following to your program:
      import sys
      print (sys.version)
  • And are there any errors being printed when you run your program?

I suspect that this is actually a problem with the video card driver settings. You need to either update or reset the user settings.

Hi there

@Thaumaturge
@serega-kkz
Thank you for the help I really appreciate it.
I am sincerely sorry. I forgot to remove the filtering lines before posting the code.

 self.modelDF.setMagfilter(SamplerState.FT_linear_mipmap_linear)
  self.modelDF.setMinfilter(SamplerState.FT_linear_mipmap_linear)

May you please try removing the filters to get the grainy result.
Filtering gives me a result very similar to @Thaumaturge. The problem is this also dulls out the alpha-channel-cut effect.
Looking at @Thaumaturge’s image, the parts of the model with alpha channels are now visible. From other angles this problem is even worse.
I trying to remove the graininess but keep a complete alpha-channel-cut effect.

Panda3D Version 1.10.9
Python Version 3.7.9

Best regards

Ah, I see!

Okay, trying the program again with those removed, I do now see the effect, and I think that it’s a consequence of having narrow bands in a texture that doesn’t use mip-maps.

(Note that the issue disappears at close range, and gradually becomes worse the further the view moves away from an affected object.)

Quite what you might do about this, given that you don’t want the blurriness of the default mip-mapping, I’m not sure.

One thing that you might try is using “SamplerState.FT_linear_mipmap_nearest” (or even “SamplerState.FT_nearest_mipmap_nearest”) instead of “SamplerState.FT_linear_mipmap_linear”.

However, if you do so I’d suggest closely examining the results to see if they’re to your liking, as this approach might incur some pixelation, I fear.

Alternatively, you could of course make your own mip-maps–but that is additional work. (And I don’t know the details of implementing it, I’m afraid, as I don’t think that I’ve done so myself.)

But perhaps someone else will have another answer for you!

That, I believe, is a separate problem: In short, correct transparency (of this sort) relies heavily on the surfaces in question being rendered in order from furthest to closest.

This then becomes complicated when transparent objects overlap, which may result in some parts of one object being closer than the corresponding parts of another object–but other parts being instead further away. As a result, simply sorting the objects by distance may not be effective; in the worst case, one might have to sort each fragment, which I imagine could be expensive.

For a more in-depth discussion of the matter, with at least one suggestion that you might try, I’d suggest taking a look at the following manual page:
https://docs.panda3d.org/1.10/python/programming/texturing/transparency-and-blending

Hi there

@Thaumaturge
Thank you for the help I really appreciate it.
I tried the SamplerState.FT_linear_mipmap_nearest filter, The result was a just a little bit better.

Thank you for the mip-mapping suggestion. Time to learn about mip-mapping hopefully that will bring me to a working solution.
May you please let me know, if you come up with a solution or any other suggestions, please.
Thank you.

Best regards.

1 Like