Examples for stim3d?

I’m looking for pointers to demos for the recently added stim3d classes. Any help?


There is a demo called rigidBodyTransform.py in the demos/misc folder to demonstrate rigid body transforms and lighting. Support for 3D is pretty new, so be sure to report any issues you encounter.

For more advanced 3D stimuli, like those loaded from OBJ files. You can modify the code so instead of SphereStim, you can use ObjMeshStim like so:

mdl = ObjMeshStim(win, 'mymodel.obj')

Obj files can be exported from Blender with textures and materials. Make sure that faces are triangulated, quads are not supported.

Much appreciated. I also note that there’s a stim3d.py demo in the demos/coder/stimuli directory that I somehow missed previously.

I have follow-up question about the 3D stimuli. In pyglet, multiple windows can share the same OpenGL context, meaning that they can have different views of the same objects. Is there some way to do this in PsychoPy? It currently looks like a BoxStim, e.g., requires a single window as a parent.

As background, I’m evaluating PsychoPy to generate the stimuli for a head-fixed rodent VR experiment, where the visual stimuli would be displayed on front and side-viewing monitors.


I think Pyglet should share windows by default. If you are having trouble with that, consider using the GLFW backend where you can explicitly share contexts.

win1 = Window(winType='glfw')
win2 = Window(winType='glfw', share=win1)

Thanks so much for continuing to respond on the forum. PsychoPy is awesome and I’m excited about 3D extensions!

I modified the rigidBodyTransform.py demo to use glfw and to have a second window:

win = visual.Window((600, 600), allowGUI=False, monitor='testMonitor', winType='glfw', )
win2 = visual.Window((600, 600), allowGUI=False, monitor='testMonitor', winType='glfw', share=win)

I made no other changes, and now the script fails with the error:

 File "rigidBodyTransform.py", line 53, in <module>
  File "/home/ckemere/anaconda3/lib/python3.7/site-packages/psychopy/visual/stim3d.py", line 1571, in draw
    gt.drawVAO(self._vao, GL.GL_TRIANGLES)
  File "/home/ckemere/anaconda3/lib/python3.7/site-packages/psychopy/tools/gltools.py", line 2390, in drawVAO
  File "/home/ckemere/anaconda3/lib/python3.7/site-packages/pyglet/gl/lib.py", line 107, in errcheck
    raise GLException(msg)
pyglet.gl.lib.GLException: b'invalid operation'

I searched the demo directory to see if there were any examples with context sharing and didn’t see any. This is under Ubuntu with intel graphics.


Ah, I forgot I made it use VAOs for drawing. Those cannot be shared across contexts. In VR, both images are rendered to framebuffers within the same context which I intended the 3D stim support to be mainly used for. You’ll need to create duplicate stimuli for each window ATM, however I’ll see if I can improve the situation.


Thank you for sharing the demos - they are great!

Is it possible to create a wire framed cube out of BoxStim (e.g., just the outline of the cube with transparent sides)? It seems like setting lineColor is not an option.



It’s possible, though not something that can do easily. Actually using “lineColor” seems like a good idea. I’ll provide some code soon for wireframe drawing.

Cool! I am using glutWireCube for now.

Any chance you could post some example code? (I’m looking to see how people mix psychopy with general opengl.)


Anything in particular you would like to do? There is a module called psychopy.tools.gltools with loads of tools for working with OpenGL vertex buffers and shaders. There are quite a few examples listed there. Also check out psychopy.tools.viewtools and psychopy.tools.mathtools. Keep in mind these features are quite new and testing would be appreciated.

I’m hoping to integrate with a doom-like vr. Any known solutions are appreciated.

What’s doom-like VR?

Sorry - should have been a bit more clear. We’re doing experiments with head-fixed rodents running on treadmills. Since they can’t move their heads, their movements are limited to a plane (or 1D in the cases that I’m looking at right now). What I meant was 2.5D (short hand for rendering a 3D perspective when movement is limited - “Doom” was one of the original games to do this and there are a few nice examples of pyglet implementations).

You should be able to do that with the current system, you can create the “levels” in Blender or something and import them into PsychoPy using ObjStim. For movement, you can create a “RigidBodyPose” object (https://www.psychopy.org/api/visual/rigidbodypose.html#psychopy.visual.RigidBodyPose) and modify it’s ‘pos’ and ‘ori’ according to your treadmill data, then call the getViewMatrix method and set it as the window’s viewMatrix attribute. You can create the projection matrix using what’s available in the viewtools module and set win.projectionMatrix to it.

I don’t have a lot of time right now to put an example together, but you can see the ‘rigidBody’ example in the demos for more information. Maybe I can include one in the future.3D stuff works pretty well right now but is still a WIP. Now that I’m getting a good idea of people’s use cases I can make it simpler and provide more relevant examples in the future.

Hey there,

when I run the demo “rigidBodyTransform”, the demo crashes with the error message saying the following:
(I run the latest version of PsychoPy 3 on a Mac with the latest OS).

Welcome to PsychoPy3!

Running: /Applications/PsychoPy3.app/Contents/Resources/lib/python3.6/psychopy/demos/coder/misc/rigidBodyTransform.py

2020-05-13 08:42:06.454 python[6161:1526172] ApplePersistenceIgnoreState: Existing state will not be touched. New state will be written to (null)
Traceback (most recent call last):
File “/Applications/PsychoPy3.app/Contents/Resources/lib/python3.6/psychopy/demos/coder/misc/rigidBodyTransform.py”, line 36, in
lightSphere = SphereStim(win, radius=0.05, color=‘white’, useShaders=False)
File “/Applications/PsychoPy3.app/Contents/Resources/lib/python3.6/psychopy/contrib/lazy_import.py”, line 120, in call
return obj(*args, **kwargs)
File “/Applications/PsychoPy3.app/Contents/Resources/lib/python3.6/psychopy/visual/stim3d.py”, line 1822, in init
self._vao = self._createVAO(vertices, textureCoords, normals, faces)
File “/Applications/PsychoPy3.app/Contents/Resources/lib/python3.6/psychopy/visual/stim3d.py”, line 1501, in _createVAO
indexBuffer=indexBuffer, legacy=True)
File “/Applications/PsychoPy3.app/Contents/Resources/lib/python3.6/psychopy/tools/gltools.py”, line 2283, in createVAO
GL.glGenVertexArrays(1, ctypes.byref(vaoId))
File “/Applications/PsychoPy3.app/Contents/Resources/lib/python3.6/pyglet/gl/lib.py”, line 105, in errcheck
raise GLException(msg)
pyglet.gl.lib.GLException: b’invalid operation’
Exception ignored in: <bound method TextStim.del of <psychopy.visual.text.TextStim object at 0x1250759e8>>
Traceback (most recent call last):
File “/Applications/PsychoPy3.app/Contents/Resources/lib/python3.6/psychopy/visual/text.py”, line 239, in del
File “/Applications/PsychoPy3.app/Contents/Resources/lib/python3.6/pyglet/gl/lib.py”, line 97, in errcheck
ModuleNotFoundError: import of ‘pyglet’ halted; None in sys.modules

Experiment ended.

Strange error, seems to not allow for the creation of vertex arrays. Not sure if that’s a Mac OSX specific thing at this time. I’ll look into it when I have time later next week.

just tried it on windows and it runs (PsychoPy 2020.1.3).

Any examples for Anaglyphs(red/cyan glasses)


Not yet, that’s going to be added once multi-buffer rendering is implemented. You can do it yourself by calling
glColorMask(True, False, False, True) or glColorMask(False, True, True, True) and updating the view/projection matrix before drawing each eye’s view.