Comparing Texture to Image Using Shader

I’ve set up a scene with multiple buffers that get the result of render-to-texture.

I use the following code to set up my texture/buffer/camera

# config is a dumb container that stores properties
# and behaves exactly how you'd expect

film_size = config.intrinsics.get_size()
window_props = p3dc.WindowProperties.size(*film_size)
buffer = self.graphics_engine.make_output(
  p3dc.GraphicsPipe.BFRefuseWindow,  # don't open a window,,
texture = p3dc.Texture()
buffer.add_render_texture(texture, p3dc.GraphicsOutput.RTMCopyRam)

lens = p3dc.PerspectiveLens()
camera = self.make_camera(buffer, lens=lens, camName=f'Camera[{name}]')


Now I can retrieve the results of rendering from the buffer using something like

texture = buffer.get_texture()
data = texture.get_ram_image()
frame = np.frombuffer(data, self._dtype)

What I really want to do (without losing access to the existing buffer/texture that I have, because sometimes I do want to examine the image), is take this texture and compare it to an image I already have.

For example, I want to be able to load an image into a second texture, and then produce a third buffer/texture that gives the difference between the textures at each pixel. I believe I should be using a fragment shader (?) to do this, but am unclear on how to set up the mechanics in Panda3D.

I think I know how to load the image in as the second texture:

second_texture = loader.load_texture("myImage.png")

but am unclear how to set up the third texture. Should I be using filters for this (even though I don’t want anything to appear in the window)?

I realized maybe I wasn’t very clear in the above.

All I’m really looking to do, is calculate the difference between two textures and store the result in a third texture. For example, say I have tex1 and tex2, what’s the easiest (fast) way to compute

tex3 = tex1 - tex2

and get the result to the CPU (I assume through a buffer)?

I would really appreciate any suggestions.

Writing a shader to do perform that operation shouldn’t be too difficult in and of itself. What you might then do is use render-to-texture (see this manual page; I imagine that you would be using the FilterManager) to send the result to a texture that you can access in your code.

Whether that’s the fastest way of doing it I don’t know, I’m afraid.

A compute shader might be a good alternative that doesn’t require any buffer setup.

1 Like