【问题标题】:Why isn't my compute shader doing anything?为什么我的计算着色器不做任何事情?
【发布时间】:2016-06-20 03:38:34
【问题描述】:

我使用的是 OpenGL 4.5(c# 中的 OpenGL.net,但代码与普通的 OpenGL 代码非常相似),并且正在尝试使用计算着色器。到目前为止,这是我所拥有的:

// (Compile and link stuff, this part I know works)

// Use the compute shader
Gl.UseProgram(program);

// Create the texture the compute shader will output to
int textureWidth = 512, textureHeight = 512;
uint[] texturesMaking = new uint[1];
Gl.GenTextures(texturesMaking);
uint texture = texturesMaking[0];
Gl.ActiveTexture(Gl.TEXTURE0);
Gl.BindTexture(TextureTarget.Texture2d, texture);
Gl.TextureParameter(Gl.TEXTURE_2D, Gl.TEXTURE_MAG_FILTER, Gl.NEAREST);
Gl.TextureParameter(Gl.TEXTURE_2D, Gl.TEXTURE_MIN_FILTER, Gl.NEAREST);
Gl.TexImage2D(TextureTarget.Texture2d, 0, Gl.RGBA32F, textureWidth, textureHeight, 0, PixelFormat.Rgba, PixelType.Float, IntPtr.Zero);

// Get the shader output variable and set it
int location = Gl.GetUniformLocation(program, "destTex");
Gl.Uniform1(location, texture); 
Gl.BindImageTexture(0, texture, 0, false, 0, Gl.READ_WRITE, Gl.RGBA32F);

// Send off the compute shader to do work, with one group per pixel
//  (I know this is far less than optimal, it was just a debugging thing)
Gl.DispatchCompute((uint)textureWidth, (uint)textureHeight, 1);

// Wait for compute shader to finish
Gl.MemoryBarrier(Gl.SHADER_IMAGE_ACCESS_BARRIER_BIT);

// Looking at the texture, it is black

这是我的计算着色器:

#version 450
layout(local_size_x = 1, local_size_y = 1) in;
layout(rgba32f) uniform image2D destTex;

void main () {
  imageStore (destTex, ivec2(gl_GlobalInvocationID.xy), vec4(1.0, 0.0, 1.0, 1.0));
}

如果我理解正确,我的纹理在着色器运行后应该是紫色/粉红色,但它只是黑色,打印出一些像素的颜色表明所有值也为零。我做错了什么?

【问题讨论】:

  • 你“看纹理”怎么样?您是否有与您正在做的“寻找”类型相匹配的记忆障碍?
  • 啊,这可能是问题所在。我正在使用Gl.GetTexImage(TextureTarget.Texture2d, 0, PixelFormat.Rgba, PixelType.Float, pixelArrayPointer);(用于指向大小为textureWidth*textureHeight*4float[] 的指针)。然后,一旦我有了浮动数据,我将其保存到图像中,然后打开该图像以查看内容。
  • 对于那些感兴趣的人,我把我的结果代码here
  • 如果您使用 object 重载版本,则不需要固定 pixelArrayPointer。对象可以是任何 Array 实例或值类型。

标签: c# opengl textures compute-shader


【解决方案1】:

问题在于如何告诉着色器使用哪个纹理。

设置的值
int location = Gl.GetUniformLocation(program, "destTex");
Gl.Uniform1(location, texture); 

必须是图像纹理单元(Gl.BindImageTexture 命令的第一个参数),而不是纹理本身。由于您使用的是图像纹理单元 0,因此您还必须将 0 传递给制服:

GLuint unit = 0;
int location = Gl.GetUniformLocation(program, "destTex");
Gl.Uniform1(location, unit); 
Gl.BindImageTexture(unit, texture, 0, false, 0, Gl.READ_WRITE, Gl.RGBA32F);

【讨论】:

  • 或者,只需从着色器设置统一位置。他用的是CS,所以他必须有GL 4.30,这样他才能做到。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-11
相关资源
最近更新 更多