为什么我的计算着色器不执行任何操作?
Why isn't my compute shader doing anything?
我在 OpenGL 4.5(OpenGL.net 在 c# 中,但代码与普通 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));
}
如果我理解正确的话,我的纹理在着色器运行后应该是 purple/pink 颜色,但它只是黑色,打印出一些像素的颜色表明所有值都是也为零。我做错了什么?
问题在于你如何告诉着色器使用哪个纹理。
设置的值
int location = Gl.GetUniformLocation(program, "destTex");
Gl.Uniform1(location, texture);
必须是图像纹理单元(Gl.BindImageTexture
命令的第一个参数),而不是纹理本身。由于你使用的是图像纹理单元0,你也必须将0传递给uniform:
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);
我在 OpenGL 4.5(OpenGL.net 在 c# 中,但代码与普通 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));
}
如果我理解正确的话,我的纹理在着色器运行后应该是 purple/pink 颜色,但它只是黑色,打印出一些像素的颜色表明所有值都是也为零。我做错了什么?
问题在于你如何告诉着色器使用哪个纹理。
设置的值int location = Gl.GetUniformLocation(program, "destTex");
Gl.Uniform1(location, texture);
必须是图像纹理单元(Gl.BindImageTexture
命令的第一个参数),而不是纹理本身。由于你使用的是图像纹理单元0,你也必须将0传递给uniform:
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);