Apple M1 Support

Not sure if this is the right forum… but i wanted to report a possible problem on Apple M1 chip. I have a simple scene with the standard environment and Panda walking back and forth, alongside a couple of other models. Panda and my other animated models are rendering fine, no issues, but the environment is all black.

Is this a known issue? If so, is there maybe a configuration setting perhaps to combat this?

Thanks.

My system:
panda3d 1.10.9 (installed via pip)
Macbook Air (M1, 2020)
macOS Big Sur 11.2.3

(the same code and scene works fine with 1.10.7 on a different, older, Intel-based mac, if that helps)

Welcome back after 10 years!
Maybe because of the chip you told, there might be a problem loading all those models?
But can you send all the code, models and a screenshot of the bug?

EDIT:

Did you make any configuration changes? If so, please share them.

Which version of Python are you using? Are you running Python in x86_64 emulation mode or the native arm64 version?

Did you enable Cg shaders or the shader generator? There is a known limitation with the shader generator not working in the arm64 version, described here. This will be remedied in Panda3D 1.11.0.

thanks :slight_smile: it’s been a while.

i have Python 3.9.2.
Looks like it is x86_64 version running in emulation mode via Rosetta 2:

% file /usr/local/bin/python3 
/usr/local/bin/python3: Mach-O 64-bit executable x86_64

Thanks for the explanation, this indeed looks like a shader issue.
My code is a bit disorganized and large to upload all of it, but i was able to reproduce the problem with just the Hello World tutorial that has been modified slightly to add lights and shadows. Here it is:

from math import pi, sin, cos

from direct.showbase.ShowBase import ShowBase
from direct.task import Task
from direct.actor.Actor import Actor
from direct.interval.IntervalGlobal import Sequence
from panda3d.core import Point3, Vec3, VBase4
from panda3d.core import DirectionalLight, AmbientLight
from panda3d.core import BitMask32, Material


class Sun:
    r = 0.9
    g = 0.85
    b = 0.6
    angle = -90


sun = Sun()


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

        # Disable the camera trackball controls.
        self.disableMouse()

        # Load the environment model.
        self.scene = self.loader.loadModel("models/environment")
        # Reparent the model to render.
        self.scene.reparentTo(self.render)
        # Apply scale and position transforms on the model.
        self.scene.setScale(0.25, 0.25, 0.25)
        self.scene.setPos(-8, 42, 0)

        # Lights
        dlight = DirectionalLight('dlight')
        dlight.setColor(VBase4(sun.r, sun.g, sun.b, 1.0))
        dlight.setCameraMask(BitMask32.bit(1)) # allow some object not to cast shadows
        dlnp = render.attachNewNode(dlight)
        dlnp.setHpr(130, sun.angle, 0)
        render.setLight(dlnp)
        self.dlnp = dlnp
        self.dlight = dlight

        dlight.setShadowCaster(True, 2048, 2048)
        dlight.getLens().setFilmSize(260,260)
        dlight.getLens().setNearFar(-100,100)
        #dlight.showFrustum()

        # Shadows
        #self.scene.setShaderAuto()

        alight = AmbientLight('alight')
        alight.setColor(VBase4(0.4, 0.4, 0.4, 1))
        alnp = render.attachNewNode(alight)
        render.setLight(alnp)
        self.alnp = alnp

        # Add the spinCameraTask procedure to the task manager.
        self.taskMgr.add(self.spinCameraTask, "SpinCameraTask")

        # Load and transform the panda actor.
        self.pandaActor = Actor("models/panda-model",
                                {"walk": "models/panda-walk4"})
        self.pandaActor.setScale(0.005, 0.005, 0.005)
        self.pandaActor.reparentTo(self.render)
        # Loop its animation.
        self.pandaActor.loop("walk")

        # Create the four lerp intervals needed for the panda to
        # walk back and forth.
        posInterval1 = self.pandaActor.posInterval(13,
                                                   Point3(0, -10, 0),
                                                   startPos=Point3(0, 10, 0))
        posInterval2 = self.pandaActor.posInterval(13,
                                                   Point3(0, 10, 0),
                                                   startPos=Point3(0, -10, 0))
        hprInterval1 = self.pandaActor.hprInterval(3,
                                                   Point3(180, 0, 0),
                                                   startHpr=Point3(0, 0, 0))
        hprInterval2 = self.pandaActor.hprInterval(3,
                                                   Point3(0, 0, 0),
                                                   startHpr=Point3(180, 0, 0))

        # Create and play the sequence that coordinates the intervals.
        self.pandaPace = Sequence(posInterval1, hprInterval1,
                                  posInterval2, hprInterval2,
                                  name="pandaPace")
        self.pandaPace.loop()

    # Define a procedure to move the camera.
    def spinCameraTask(self, task):
        angleDegrees = task.time * 6.0
        angleRadians = angleDegrees * (pi / 180.0)
        self.camera.setPos(20 * sin(angleRadians), -20 * cos(angleRadians), 3)
        self.camera.setHpr(angleDegrees, 0, 0)
        return Task.cont


app = MyApp()
app.run()

If i run it like this, it works well, but if i uncomment this line:

#self.scene.setShaderAuto()

then the grassy environment turns black.

I have not yet tried the special wheel linked from 1.10.8 release notes. I guess i need a proper arm64 python for that… but will it help though? It sounds like it is best to wait until 1.11.0 release.

Thanks!

One more observation. Not sure if it helps, but just in case:

If i try the same code (as in the post above) on panda3d 1.10.8, with setShaderAuto() enabled, it works differently than 1.10.9: the environment isn’t black, and the light seems to be correctly illuminating things, but there are no shadows.

In that case, maybe there is an issue in 1.10.9, which might have broke the shaders, as it is working in previous versions.

1.10.8 had a bug wherein shaders would not be loaded at all on the macOS build, so that can explain why it did work in 1.10.8 but without shadows. It would be more interesting to see if it worked in 1.10.7.

The example program from the post above appears to work the same way on 1.10.7 and 1.10.9: if i uncomment self.scene.setShaderAuto() line, the environment goes black.

It worked for me, with and without the setShaderAuto on 1.10.9, so it might be an os-specific issue as I use Windows.

not just os, but looks like arch-specific too. To summarize:

macOS 10.15.4 on Intel Mac: all good on both 1.10.7 and 1.10.9
macOS 11.2.3 on M1 Mac: environment is black with setShaderAuto on both 1.10.7 and 1.10.9

(on both systems, i’m using x86_64 panda3d builds)