If anyone is ever trying to replicate this, the working shaders and code can be found below.
Vertex Shader
#version 150
// Uniform inputs
uniform mat4 p3d_ProjectionMatrix;
uniform mat4 p3d_ModelViewMatrix;
// Vertex inputs
in vec4 p3d_Vertex;
// Vertex outputs
out float distanceToCamera;
void main() {
vec4 cs_position = p3d_ModelViewMatrix * p3d_Vertex;
distanceToCamera = length(cs_position.xyz);
gl_Position = p3d_ProjectionMatrix * cs_position;
}
Fragment Shader
#version 150
in float distanceToCamera;
out vec4 fragColor;
void main() {
fragColor = vec4(distanceToCamera, 0, 0, 1);
}
Code
import os
import numpy as np
from direct.showbase.ShowBase import ShowBase
from panda3d.core import FrameBufferProperties, WindowProperties
from panda3d.core import GraphicsOutput, GraphicsPipe
from panda3d.core import Texture, PerspectiveLens, Shader
from panda3d.core import ConfigVariableString, ConfigVariableBool, Filename, ConfigVariableManager
import matplotlib.pyplot as plt
class SceneSimulator(ShowBase):
def __init__(self):
ShowBase.__init__(self)
# set up texture and graphics buffer
window_props = WindowProperties.size(1920, 1080)
frame_buffer_props = FrameBufferProperties()
frame_buffer_props.set_float_color(True)
frame_buffer_props.set_rgba_bits(32, 0, 0, 0)
buffer = self.graphicsEngine.make_output(self.pipe,
f'Buffer',
-2,
frame_buffer_props,
window_props,
GraphicsPipe.BFRefuseWindow, # don't open a window
self.win.getGsg(),
self.win
)
texture = Texture()
buffer.add_render_texture(texture, GraphicsOutput.RTMCopyRam)
buffer.set_clear_color_active(True)
buffer.set_clear_color((10, 0, 0, 0))
self.buffer = buffer
# place a box in the scene
x, y, side_length = 0, 0, 1
box = self.loader.loadModel("models/box")
box.reparentTo(self.render)
box.setScale(side_length)
box.setPos(x - side_length / 2, y - side_length / 2, 0)
# set up camera
lens = PerspectiveLens()
lens.set_film_size(1920, 1080)
lens.set_fov(45, 30)
pos = (0, 6, 4)
camera = self.make_camera(buffer, lens=lens, camName=f'Camera')
camera.reparent_to(self.render)
camera.set_pos(*pos)
camera.look_at(box)
self.camera = camera
# load shaders
vert_path = '/Users/michael/mit/sli/scene/scene/glsl_simple.vert'
frag_path = '/Users/michael/mit/sli/scene/scene/glsl_simple.frag'
custom_shader = Shader.load(Shader.SL_GLSL, vertex=vert_path, fragment=frag_path)
self.render.set_shader(custom_shader)
def render_image(self) -> np.ndarray:
self.graphics_engine.render_frame()
texture = self.buffer.get_texture()
data = texture.get_ram_image()
frame = np.frombuffer(data, np.float32)
frame.shape = (texture.getYSize(), texture.getXSize())
frame = np.flipud(frame)
return frame
if __name__ == '__main__':
simulator = SceneSimulator()
image = simulator.render_image()
plt.imshow(image)
plt.colorbar()
plt.show()