RenderPipeline: Displaying shapes procedurally generated in Panda3D

Hello,
I recently started integrating the RenderPipeline in my project, downloader from:
https://github.com/tobspr/RenderPipeline
because it looks awesome! :smiley:

However I have a problem when trying to display shapes that I am generating procedurally using the GeomVertexFormat, GeomVertexData and GeomTriangles(Geom.UHStatic) from panda3d.core.
The problem is that all these shapes appear pitch black regardless of the lights that I put in the scene.

I’m using a GeomVertexFormat with V3n3c4t2, so I have rows with: vertex, color, normal and texcoord.I couldn’t find any documentation on how to procedurally apply textures when using the RenderPipeline, and all the examples provided with the library use pre-created textured assets. So for the moment, I am only applying colors to my vertuces, no textures or materials (texcoord is always 0.0).

To fix my problem I tried:

  • flipping the normals of my shapes
  • adding more and stronger lights from rpcore and panda.core in my scene

but my models remain black.

My code after the creation of the GeomTriangles(Geom.UHStatic) looks like this:

geom.addPrimitive(triangle)
node = GeomNode("my_test")
node.addGeom(geom)
nodePath = NodePath(node)
nodePath .reparent_to(self.render)
self.render_pipeline.prepare_scene(nodePath)

Any ideas about what I might be missing here?
Thanks a lot!

  1. Try to set the time.
self.render_pipeline.daytime_mgr.time = "12:20"
  1. Customize the material.
        myMaterial = Material()
        myMaterial.setDiffuse((1, 1, 1, 1))
        myMaterial.setSpecular((0, 0, 0, 0))
        myMaterial.setShininess(-1.804294705390930)
        myMaterial.setAmbient((1, 1, 1, 1))
        myMaterial.setAmbient((0, 0.615175, 0, 1))
        
        myMaterial.setRoughness(1.7879559993743896)
        myMaterial.setMetallic(0.0)
        myMaterial.setRefractiveIndex(1.5)
        myMaterial.setLocal(False)
        
        self.model = self.loader.loadModel("box")
        self.model.reparentTo(self.render)
        
        self.model.setMaterial(myMaterial)

All code:

        self.render_pipeline.daytime_mgr.time = "12:20"

        myMaterial = Material()
        myMaterial.setDiffuse((1, 1, 1, 1))
        myMaterial.setSpecular((0, 0, 0, 0))
        myMaterial.setShininess(-1.804294705390930)
        myMaterial.setAmbient((1, 1, 1, 1))
        myMaterial.setAmbient((0, 0.615175, 0, 1))
        
        myMaterial.setRoughness(1.7879559993743896)
        myMaterial.setMetallic(0.0)
        myMaterial.setRefractiveIndex(1.5)
        myMaterial.setLocal(False)
        
        self.model = self.loader.loadModel("box")
        self.model.reparentTo(self.render)
        
        self.model.setMaterial(myMaterial)
        
        tex = loader.loadTexture("data/tex/ConcreteDiffuse.png")
        tex.setMagfilter(SamplerState.FT_linear)
        tex.setMinfilter(SamplerState.FT_linear)
        tex.setWrapU(Texture.WM_repeat)
        tex.setWrapV(Texture.WM_repeat)
        ts = TextureStage('ConcreteDiff')
        ts.setMode(TextureStage.MModulate)
        self.model.setTexture(ts, tex)
        
        tex = loader.loadTexture("data/tex/ConcreteNormal.png")
        tex.setMagfilter(SamplerState.FT_linear)
        tex.setMinfilter(SamplerState.FT_linear)
        tex.setWrapU(Texture.WM_repeat)
        tex.setWrapV(Texture.WM_repeat)
        ts1 = TextureStage('ConcreteNrm')
        ts1.setMode(TextureStage.MModulate)
        self.model.setTexture(ts1, tex)
        
        tex = loader.loadTexture("data/tex/empty_specular.png")
        tex.setMagfilter(SamplerState.FT_linear)
        tex.setMinfilter(SamplerState.FT_linear)
        tex.setWrapU(Texture.WM_repeat)
        tex.setWrapV(Texture.WM_repeat)
        ts2 = TextureStage('empty_specular')
        ts2.setMode(TextureStage.MModulate)
        self.model.setTexture(ts2, tex) 
        
        tex = loader.loadTexture("data/tex/ConcreteRoughness.png")
        tex.setMagfilter(SamplerState.FT_linear)
        tex.setMinfilter(SamplerState.FT_linear)
        tex.setWrapU(Texture.WM_repeat)
        tex.setWrapV(Texture.WM_repeat)
        ts3 = TextureStage('ConcreteRough')
        ts3.setMode(TextureStage.MModulate)
        self.model.setTexture(ts3, tex)

        tex = loader.loadTexture("data/tex/ConcreteDisp.png")
        tex.setMagfilter(SamplerState.FT_linear)
        tex.setMinfilter(SamplerState.FT_linear)
        tex.setWrapU(Texture.WM_repeat)
        tex.setWrapV(Texture.WM_repeat)
        ts4 = TextureStage('ConcreteDisp')
        ts4.setMode(TextureStage.MModulate)
        self.model.setTexture(ts4, tex)
1 Like

Thanks a lot for your answer! The trick was to apply a material on my shape, now it works. :slight_smile:

You should not set diffuse/specular/ambient separately on PBR materials; rather use something like this:

        myMaterial.setBaseColor((1, 1, 1, 1))
        myMaterial.setRoughness(1.7879559993743896)
        myMaterial.setMetallic(False)
        myMaterial.setRefractiveIndex(1.5)

Also, the roughness overrides the shininess, so setting the shininess is pointless (and negative values are invalid anyway).

1 Like

I researched Render_Pipeline examples using.

    def print_mat(self):

        mats_all = self.model.findAllMaterials()
        mats = mats_all.getMaterial(6)
        #print (mats)
        
        print ("")
        print ("Diffuse: ", mats.getDiffuse())
        print ("Specular: ", mats.getSpecular())
        print ("Shininess: ", mats.getShininess())
        print ("Ambient: ", mats.getAmbient())
        print ("Emission: ", mats.getEmission())
        print ("")
        print ("Roughness: ", mats.getRoughness())
        print ("Metallic: ", mats.getMetallic())
        print ("RefractiveIndex: ", mats.getRefractiveIndex())
        print ("Local: ", mats.getLocal())
Diffuse:  LVecBase4f(0.8, 0.284849, 0, 1)
Specular:  LVecBase4f(0, 0, 0, 0)
Shininess:  0.0
Ambient:  LVecBase4f(1, 1, 1, 1)
Emission:  LVecBase4f(1, 0, 0, 0)

Roughness:  1.0
Metallic:  0.0
RefractiveIndex:  1.0
Local:  False

Although it was enough to use

print (mats)
  base_color = 0.8 0.284849 0 1
  refractive_index = 1
  emission = 1 0 0 0
  roughness = 1
  metallic = 0
  local = 0
  twoside = 0

I set a negative value by accident.

1 Like

Thank you both for your answers, they have been very useful. My scene looks significantly better already.

I have one follow-up question, regarding creating PBR materials in Panda3D. I am trying to use texture maps not only for the base color, but also for the metallic, normal and roughness of my materials. Do you know have any suggestions on how to do that?

Thanks!
@rdb @serega-kkz

I think the RenderPipeline requires PBR textures to be applied to four successively numbered texture stages; consult the RenderPipeline documentation for the precise order in which these should be applied.

The plans are to make this easier to do in Panda3D 1.11 by creating a new interface for assigning these texture slots in the Material class.

I can advise you to study .blend files with examples. To do this, you need to install Blender version <2.7. Also YABEE and Panda3D-Bam-Exporter. Save the EGG use YABEE, after which it will be possible to study the structure of the material in a text file.

1 Like