Rendering 3d text using python

Hello guys,

I am totally new in python and panda3d, but trying to make 3d text for text data augmentation.

From the Panda3d manuals, I found that there is a renderMode to make 3d text, RMSolid.

I made very simple code as following, and it does not render any text.

However, when I change textNode = aspect2d.attachNewNode(text) instead of render.attach, it shows 2d text.

Is there any problems with my code for rendering 3d text?

Thank you very much in advance, and please help me a little novice :frowning:

from panda3d.core import *
import sys
import os
from direct.showbase.ShowBase import ShowBase
from direct.interval.IntervalGlobal import *
from direct.showbase.DirectObject import DirectObject
from direct.showbase import Loader

ShowBase()
fontPath = ConfigVariableString("on-screen-debug-font", "cmtt12").value
font = loader.loadFont(fontPath, color = (1,1,1,1), renderMode = TextFont.RMSolid)
font2 = loader.loadFont(fontPath, color = (1,1,1,1))
text = TextNode('text')
text.setFont(font)
text.setText("Hello, World!")
text.setFont(font)
text.setAlign(TextNode.ACenter)
textNode = render.attachNewNode(text)
textNode.setScale(0.2)
run()

Hi and welcome :slight_smile: !

The cmtt12 font is loaded from an .egg file and as such would be a StaticTextFont, whose render mode cannot be changed.
Instead, try loading a .ttf font file; I’ve just tried this myself and it works fine.

(If you can’t actually see the text, you’ll need to pull back the camera using the built-in camera controls, or call base.disable_mouse() and set the camera position to a negative Y-value, or set the position of the text itself to a positive Y-value.)

Thank you alot!

I downloaded arial.ttf and tried RMSolid, finally in works!

From now on, I would like to figure out how to put some textures on those three-dimensional text and how to take a picture of the texts!

Thank you again :slight_smile:

Since 3D-text doesn’t seem to have any texture coordinates applied, you will need to have them generated automatically, for example:

        tex = loader.load_texture("maps/envir-reeds.png")
        tex_stage = TextureStage.get_default()
        textNode.set_tex_gen(tex_stage, TexGenAttrib.M_world_position)
        textNode.set_tex_projector(tex_stage, render, textNode)
        textNode.set_tex_hpr(tex_stage, 0., -90., 0.)
        textNode.set_texture(tex)

See this manual page for more on this.

You can save a screenshot of the scene like this (press Enter key):

        base.accept("enter", lambda: base.win.save_screenshot("my_3d_text.png"))

Hope this helps.

Thank you so much Epihaius,

I successfully rendered 3D text with various texture!

I sincerely appreciate it :slight_smile:

May I then ask you my last question about vertically alignment of text?

I am wondering if I can find any functionals to align texts vertically or, should I put /n between every characters?

For 2D text(on screen text), some functions are seemed to be exist, but could not find for 3D yet…

Is there any way to automatically render 3D text vertically? (Characters are not rotated, but vertical direction of the word)

Not sure if that’s what you are referring to, but I see that OnscreenText has a setRoll method, which you could use to rotate the text 90 degrees about its local Y-axis.
But if you want the letters to appear above/below instead of next to each other, then I wouldn’t know of a way to do that apart from using \n, as you already suggested:

        text.set_text("\n".join("Hello, World!"))

By the way, OnscreenText is functionally almost the same as TextNode; it’s just a specialized kind of NodePath wrapped around a TextNode, so both of them can be used for 2D or 3D text.
So for example you could do:

        onscreen_text = OnscreenText(text="My text")
        text_node = onscreen_text.node()
        text_node.set_font(font)