Why does the teapot render on TV man but not the cube?

#!/usr/bin/env python

from direct.showbase.ShowBase import ShowBase
from panda3d.core import Filename, Texture
from panda3d.core import AmbientLight, DirectionalLight, PointLight
from panda3d.core import NodePath, TextNode
from direct.task.Task import Task
from direct.actor.Actor import Actor
from direct.gui.OnscreenText import OnscreenText
import sys
import os
import random
import gltf
import simplepbr


random.seed()

class TeapotOnTVDemo(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)
        self.disableMouse()
        self.setBackgroundColor((0, 0, 0, 1))

        # we now get buffer thats going to hold the texture of our new scene
        altBuffer = self.win.makeTextureBuffer("hello", 256, 256)

        # now we have to setup a new scene graph to make this scene
        altRender = NodePath("new render")

        # this takes care of setting up ther camera properly
        self.altCam = self.makeCamera(altBuffer)
        self.altCam.reparentTo(altRender)
        self.altCam.setPos(0, -10, 0)

        # get the teapot and rotates it for a simple animation
        self.teapot = loader.loadModel('teapot')
        self.teapot.reparentTo(altRender)
        self.teapot.setPos(0, 0, -1)
        self.teapot.hprInterval(1.5, (360, 360, 360)).loop()

        # put some lighting on the teapot
        dlight = DirectionalLight('dlight')
        alight = AmbientLight('alight')
        dlnp = altRender.attachNewNode(dlight)
        alnp = altRender.attachNewNode(alight)
        dlight.setColor((0.8, 0.8, 0.5, 1))
        alight.setColor((0.2, 0.2, 0.2, 1))
        dlnp.setHpr(0, -60, 0)
        altRender.setLight(dlnp)
        altRender.setLight(alnp)

        # Put lighting on the main scene
        plight = PointLight('plight')
        plnp = render.attachNewNode(plight)
        plnp.setPos(0, 0, 10)
        render.setLight(plnp)
        render.setLight(alnp)

        # Panda contains a built-in viewer that lets you view the results of
        # your render-to-texture operations.  This code configures the viewer.

        self.accept("v", self.bufferViewer.toggleEnable)
        self.accept("V", self.bufferViewer.toggleEnable)
        self.bufferViewer.setPosition("llcorner")
        self.bufferViewer.setCardSize(1.0, 0.0)

        # Create the tv-men. Each TV-man will display the
        # offscreen-texture on his TV screen.
        self.tvMen = []
        self.makeTvMan(-5, 30, 1, altBuffer.getTexture(), 0.9)
        self.MakeTvCube(1, 10, 1, altBuffer.getTexture(), 1.1)

    def makeTvMan(self, x, y, z, tex, playrate):
        man = Actor()
        man.loadModel('models/mechman_idle')
        man.setPos(x, y, z)
        man.reparentTo(render)
        faceplate = man.find("**/faceplate")
        faceplate.setTexture(tex, 1)
        man.setPlayRate(playrate, "mechman_anim")
        man.loop("mechman_anim")
        self.tvMen.append(man)
        
    def MakeTvCube(self, x, y, z, tex, playrate):
        man = loader.loadModel('models/box.glb')
        man.setPos(x, y, z)
        man.reparentTo(render)
        faceplate = man.find("**/Cube")
        faceplate.setTexture(tex, 1)
        #man.setPlayRate(playrate, "mechman_anim")
        #man.loop("mechman_anim")
        self.tvMen.append(man)



demo = TeapotOnTVDemo()
demo.run()

The cube is just a basic cube mesh exported from blender with an image texture material.

Well, to start with, do you see any errors in your output?

If not, then let me ask: Is your cube UV-mapped?

It might help to know the program versions:
Panda3D v. 1.10.10
Python v. 3.8.10
Blender v 3.0.1

In the script for the TV Man, the mesh is loaded with this code:

        man = Actor()
        man.loadModel('models/mechman_idle')

I first used that code to load the cube, but it told me that my model wasn’t a character. I changed the code to this:

        man = loader.loadModel('models/box.glb')

Program output when ran:
Known pipe types:
glxGraphicsPipe
(1 aux display modules not yet loaded.)

In Blender, I did this:

  1. Created a cube mesh.
  2. Created a material with a solid colored image texture (The image hex color: 98FFB0). Turned Specular down to 0.000. Then clicked the “Assign” material button.
  3. Switched to Edit Mode, pressed the U key and clicked “Mark Seam.”
  4. Pressed the U key and clicked “Unwrap.”
  5. Exported the cube as a gltf 2.0 file.

When I run the program it shows the teapot spinning on TV Man, but the cube is just a blank solid colored box.

I’m hoping to get the teapot to show on all six sides of the cube. I think Panda3D does that automatically for the render to texture like it does when a normal .jpg image texture is applied to a cube mesh.

You have to get rid of the material.

I remove the material and now it is a solid grey box.

What could be the problem?

You should have a texture coordinate - UV in model. Share the cube file so we can take a look.

1 Like

It looks really with .gltf has a problem. I think @Moguri knows what the problem is.

from direct.showbase.ShowBase import ShowBase
from panda3d.core import NodePath

class TeapotOnTVDemo(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)
        self.setBackgroundColor((0, 0, 0, 1))

        altBuffer = self.win.makeTextureBuffer("hello", 256, 256)

        altRender = NodePath("new render")

        altCam = self.makeCamera(altBuffer)
        altCam.setPos(0, -10, 0)
        altCam.reparentTo(altRender)

        teapot = loader.loadModel('teapot')
        teapot.reparentTo(altRender)
        teapot.hprInterval(1.5, (360, 360, 360)).loop()

        box = loader.loadModel('untitled.glb')
        box.reparentTo(render)
        box.setTexture(altBuffer.getTexture(), 1)

demo = TeapotOnTVDemo()
demo.run()

It doesn’t work.

untitled.glb (1.6 KB)

How should I apply the texture coordinate if the material is removed? Also, I tried to upload the blend file, but I get this message: “Sorry, new users can not upload attachments.”

I used the blend2bam program to convert my .blend file to a .bam file and it still does the same thing as the .glb file.

I’ve already used a cube with texture coordinates and it didn’t work. You can try it for an experiment .obj, it works for me. I believe that with the plugin .gltf has a problem, it’s not clear what the problem is yet.

I can now upload files besides just screen shots. Here is my project so y’all can see what’s going on with it:

TVCube.zip (465.9 KB)

I didn’t have time to dig through the blend file, but I tried a few things on the Python file. Setting a TextureStage nor rebuilding the material seemed to do the trick. I suspect an issue with the UVs. By default, Blender will not put all of the faces of the cube on the same UV positions, which means that the teapot will not show up on all faces. I suspect the teapot is showing up somewhere on the model, but is not visible from the fixed angle. You can try rotating the cube around or double-checking that all faces of the cube fill the full UV space.

I looked at all angles on the cube, resizing the UV map in Blender, and resetting the UV map after selecting all the faces to put them all in the same position. The cube is a grey box on all 6 sides with no teapot showing up. I also used the blend file in place of the gltf model and that didn’t work either. I guess it’s a problem with Panda3D’s render to texture feature, but I’m not really sure. Thanks for all the answers so far everyone.