使用 modernGL 执行简单的 GLSL 计算着色器不起作用

问题描述 投票:0回答:1

我最近发现了计算着色器的优势。但是,不知何故我无法让他们正确写入数据。

在下面的最小示例中,我想使用计算着色器来旋转图像的前三个通道。但是,当使用着色器时,生成的输出图像始终为零。

在执行着色器之前将目标图像填充为蓝色,执行后它也变成黑色,这表明着色器正在对纹理进行处理。我错过了什么?

import moderngl
import numpy as np
import cv2

compute_shader_source = """
#version 450

layout (local_size_x = 16, local_size_y = 16) in;

layout (binding = 0, rgba8ui) uniform   uimage2D src_texture;
layout (binding = 1, rgba8ui) uniform   uimage2D dest_texture;

// rotate channels
void main() {
    ivec2 texel_pos = ivec2(gl_GlobalInvocationID.xy);
    uvec4 color = imageLoad(src_texture, texel_pos);
    uvec4 flipped_color = color.gbra;
    imageStore(dest_texture, texel_pos, flipped_color);
}
"""

dims            = (256, 128)

ctx             = moderngl.create_standalone_context()
compute_shader  = ctx.compute_shader(compute_shader_source)
compute_shader['src_texture']   = 0
compute_shader['dest_texture']  = 1

# Input Image (RED)
in_color    = np.array([0, 0, 100, 255] * dims[0] * dims[1], dtype=np.uint8)
in_texture  = ctx.texture(dims, 4, data = in_color)

# Output Image (initialized BLUE)
out_color   = np.array([100, 0, 0, 255] * dims[0] * dims[1], dtype=np.uint8)
out_texture = ctx.texture(dims, 4, data = out_color)

# Bind textures to units
in_texture.bind_to_image(0, read=True, write=True)
out_texture.bind_to_image(1, read=True, write=True)

# Input
a = np.frombuffer(in_texture.read(), dtype=np.uint8).reshape(in_texture.height, in_texture.width, -1)
cv2.imshow('input', a)

# Before shader execution
a = np.frombuffer(out_texture.read(), dtype=np.uint8).reshape(in_texture.height, in_texture.width, -1)
cv2.imshow('destination before', a)

# Execute the compute shader
compute_shader.run(dims[0] // 16, dims[1] // 16, 1)

# After shader execution (should be GREEN, is BLACK)
a = np.frombuffer(out_texture.read(), dtype=np.uint8).reshape(in_texture.height, in_texture.width, -1)
cv2.imshow('destination after', a)
cv2.waitKey()

python glsl compute-shader python-moderngl
1个回答
0
投票

我终于弄清楚出了什么问题。根据docs,创建纹理时需要明确设置数据类型,否则假定为 float 或“f1”。由于我的图像由无符号整数组成,dtype 需要为 'u1':

in_texture   = ctx.texture(dims, 4, data = in_color, dtype='u1')
out_texture  = ctx.texture(dims, 4, data = out_color, dtype='u1')

这最终产生了绿色图像!

© www.soinside.com 2019 - 2024. All rights reserved.