Hi all,
I’m trying to learn how to use compute shaders in panda3d by starting directly from the code in the documentation:
https://docs.panda3d.org/1.10/python/programming/shaders/compute-shaders
Almost entirely copy/pasted directly from the docs, the python code is:
from panda3d.core import Shader, Texture, ConfigVariableBool, NodePath, ShaderAttrib, PNMImage
from direct.showbase.ShowBase import ShowBase
immutableTextureStore = ConfigVariableBool("gl-immutable-texture-storage", False)
immutableTextureStore.setValue(True)
print ("immutable texture storage", immutableTextureStore.getValue())
base = ShowBase()
# Setup the textures
myTex1 = Texture()
myTex2 = Texture()
myTex1.setup_2d_texture(512, 512, Texture.T_unsigned_byte, Texture.F_rgba8)
myTex2.setup_2d_texture(512, 512, Texture.T_unsigned_byte, Texture.F_rgba8)
myTex1.set_clear_color((1,0,0,1))
myTex2.set_clear_color((0,0,0,1))
myTex1.clear_image()
# Create a dummy node and apply the shader to it
shader = Shader.load_compute(Shader.SL_GLSL, "compute_shader.glsl")
dummy = NodePath("dummy")
dummy.set_shader(shader)
dummy.set_shader_input("fromTex", myTex1)
dummy.set_shader_input("toTex", myTex2)
# Retrieve the underlying ShaderAttrib
sattr = dummy.get_attrib(ShaderAttrib)
# Dispatch the compute shader, right now!
base.graphicsEngine.dispatch_compute((32, 32, 1), sattr, base.win.get_gsg())
# Store the output
frame = PNMImage()
myTex2.store(frame)
frame.write("/c/Users/domin/Documents/Projects/Python/Shader Test/test.png")
and the shader code is:
#version 430
// Set the number of invocations in the work group.
// In this case, we operate on the image in 16x16 pixel tiles.
layout (local_size_x = 16, local_size_y = 16) in;
// Declare the texture inputs
layout (rgba8) uniform readonly image2D fromTex;
uniform writeonly image2D toTex;
void main() {
// Acquire the coordinates to the texel we are to process.
ivec2 texelCoords = ivec2(gl_GlobalInvocationID.xy);
// Read the pixel from the first texture.
vec4 pixel = imageLoad(fromTex, texelCoords);
// Swap the red and green channels.
pixel.rg = pixel.gr;
// Now write the modified pixel to the second texture.
imageStore(toTex, texelCoords, pixel);
}
The only changes I made were code to set gl-immutable-texture-storage = True
, code to setup the textures, including changing the format from rgb8
to rgba8
, changing alpha to 1 so the results will be visible, adding code to save the output texture, and adding a format layout to the input texture uniform in the shader code (without which it won’t compile).
format layouts are required for any image2D that is read from, according to the opengl documentation:
https://www.khronos.org/opengl/wiki/Image_Load_Store
“So if you want to read from an image, you must declare the format.”
The output from running this code is:
immutable texture storage True
Known pipe types:
wglGraphicsPipe
(all display modules loaded.)
But no image is saved at the specified filepath.
Any help is appreciated!