我正在尝试将一些数据从计算着色器输出到纹理,但是imageStore()似乎什么都不做.这是着色器:
#version 430
layout(RGBA32F) uniform image2D image;
layout (local_size_x = 1, local_size_y = 1) in;
void main() {
imageStore(image, ivec2(gl_GlobalInvocationID.xy), vec4(0.0f, 1.0f, 1.0f, 1.0f));
}
Run Code Online (Sandbox Code Playgroud)
和应用程序代码在这里:
GLuint tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, 0);
glBindImageTexture(0, tex, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
glUseProgram(program->GetName());
glUniform1i(program->GetUniformLocation("image"), 0);
glDispatchCompute(WIDTH, HEIGHT, 1);
Run Code Online (Sandbox Code Playgroud)
然后使用该纹理渲染全屏四边形,但目前它只显示来自视频内存的一些随机旧数据.知道什么可能是错的吗?
编辑:
这是我显示纹理的方式:
// This comes right after the previous block of code
glUseProgram(drawProgram->GetName());
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex);
glUniform1i(drawProgram->GetUniformLocation("sampler"), 0);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 6);
glfwSwapBuffers();
Run Code Online (Sandbox Code Playgroud)
drawProgram包括:
#version …Run Code Online (Sandbox Code Playgroud) 我有一个SSBO,它为屏幕上的每个像素存储vec4颜色值,并在主循环之前通过计算着色器预先填充值.
我现在正试图在屏幕上获取这些数据,我猜这涉及到使用片段着色器(虽然如果你知道一个更好的方法,我可以接受建议)
所以我试图将缓冲区或至少其中的数据添加到片段着色器中,以便我可以将每个片段的颜色设置为缓冲区中的相应值,但我找不到任何方法这样做?
有人告诉我,我可以将SSBO绑定到片段着色器,但我不知道该怎么做?我的其他想法是以某种方式将数据从SSBO移动到纹理,但我也无法解决这个问题
更新:
作为回应thokra的优秀答案和以下评论是设置我的缓冲区的代码:
//Create the buffer
GLuint pixelBufferID;
glGenBuffers(1, &pixelBufferID);
//Bind it
glBindBuffer(GL_SHADER_STORAGE_BUFFER, pixelBufferID);
//Set the data of the buffer
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(vec4) * window.getNumberOfPixels, new vec4[window.getNumberOfPixels], GL_DYNAMIC_DRAW);
//Bind the buffer to the correct interface block number
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, pixelBufferID);
Run Code Online (Sandbox Code Playgroud)
然后我调用计算着色器,这部分工作,我检查数据是否已正确填充.然后在我的片段着色器中,就像测试一样:
layout(std430, binding=0) buffer PixelBuffer
{
vec4 data[];
} pixelBuffer
void main()
{
gl_FragColor = pixelBuffer.data[660000];
}
Run Code Online (Sandbox Code Playgroud)
我注意到的是,它似乎需要越来越长的索引越高,因此在660000它实际上并没有崩溃,只是花了很多时间.
我正在尝试通过捕获 GPU 帧来分析 Metal 内核。在具有 Metal runloop 的应用程序中,我会单击调试区域中的“相机按钮”,但是每个应用程序生命周期我只调度内核一次,因此我无法单击“相机按钮”(它保持灰色)。
\n\n因此,我尝试通过在第一次调用之前使用“捕获 GPU 帧”操作设置断点来解决此问题mQueue.insertDebugCaptureBoundary()(请参阅下面的代码)。
我期望发生的事情是这样的\ xe2\x80\x93 ,即每个内核函数的执行持续时间的概述,以及执行各行内核函数所花费的时间百分比。
\n\n实际发生的情况是:我很少得到所描述的预期分析概述。大多数时候(大约 95% 的时间)我没有得到这样的分析概述,而是在构建并运行应用程序后发生以下情况之一:
\n\n下面的代码显示了我的问题的简化示例(如果您想知道;不,我在 ViewController 中没有计算逻辑 - 下面的代码只是一个玩具示例;))。
\n\nclass ViewController : UIViewController { \n // initialize Metal, create buffers, etc. \n\n override func viewDidLoad() { \n tick() …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用计算着色器实现流体动力学。在这篇文章中,对纹理进行了一系列处理,因为这是在计算着色器之前编写的。
对纹理或缓冲区进行每次传递会更快吗?无论如何,最终通道都必须应用于纹理。
我正在开发一个计算着色器,其中输出写入SSBO。现在,该缓冲区的使用者是 CUDA,它期望它包含无符号字节。我目前无法找到如何在 SSBO 中为每个索引写入一个字节的方法.对于纹理或图像,规范化浮点到无符号字节的转换由 OpenGL 处理。例如,我可以附加具有内部格式 R8 的纹理并为每个条目存储字节。但是 SSBO 不可能实现这样的操作。这是否意味着除了 bool 之外数据类型 SSBO 中的所有数值存储类型每个条目至少只能有 4 个字节?
实际上,我希望能够做到以下几点:
计算着色器:
#version 430 core
layout (local_size_x = 8,local_size_y = 8 ) in;
struct SSBOBlock
{
byte mydata;
};
layout(std430,binding = BUFFER_OUTPUT) writeonly buffer bBuffer
{
SSBOBlock Ouput[];
} Out;
void main()
{
//..... Compute shader stuff...
//.......
Out.Ouput[globalIndex].mydata = val;//where val is normalized float
}
Run Code Online (Sandbox Code Playgroud) 我正在将全屏效果转换为计算着色器,以便我可以利用片段着色器无法完成的一些计算功能。现在,这种全屏效果使用模板来避免写入它不应该影响的像素,我想用我的计算着色器来模仿这种行为。
我知道我可以将此信息写入某处的颜色通道,但我希望避免这种情况,而是直接在计算着色器中读取模板位。但是,我找不到任何方法将 D24S8 缓冲区绑定到计算着色器,以便我可以实际读取模板位。它似乎只提供深度信息。
有什么办法可以做到这一点吗?谷歌让我失望了,因为在谈论采样深度值时每个人都将其称为深度/模板缓冲区。
我有一个灰度纹理(8000*8000),每个像素的值是一个ID(其实这个ID就是这个片段所属的三角形的ID,我想用这个方法计算出有多少个三角形,有哪些三角形在我的场景中可见)。
现在我需要计算有多少唯一 ID 以及它们是什么。我想用 GLSL 实现这一点,并最大限度地减少 GPU RAM 和 RAM 之间的数据传输。
我最初的想法是使用一个shader存储缓冲区,将其绑定到GLSL中的一个数组,其大小为totalTriangleNum,然后在shader中遍历ID纹理,将索引等于ID的数组元素加1质地。
之后,将缓冲区读取到 OpenGL 应用程序并得到我想要的。这是一种有效的方法吗?或者是否有一些更好的解决方案,例如计算着色器(我不熟悉它)或其他什么。
假设我在金属中分派了两个计算着色器 A 和 B。我不希望 B 在 A 完成之前运行。目前,我在自己的命令缓冲区中对每个着色器进行编码,并像这样提交:
commandBufferA.commit()
commandBufferA.waitUntilCompleted()
commandBufferB.commit()
Run Code Online (Sandbox Code Playgroud)
这是正确的技术吗?
获得统一的"均匀球体球体[10]"的位置(通过glGetUniformLocation(程序,名称)).返回-1,即使程序中有其他制服(frustum_planes)有效.
frustum_planes和球体制服也在相同的地方使用,这使得奇怪的是两者中只有一个存在.
什么想法可能会出错?
着色器
#version 460 core
// Required by compute shaders apparently
// Process one object per shader invocation (optimisation?)
layout (local_size_x = 1) in;
struct Sphere {
vec3 center;
float radius;
};
uniform Sphere spheres[10];
// Plane defined as: Ax + By + Cz = D
uniform vec4 frustum_planes[6];
uint test(Sphere obj, vec4 plane) {
const float distance = plane.x * obj.center.x + plane.y * obj.center.y + plane.z * obj.center.z + plane.w;
if (distance < -obj.radius) {
return …Run Code Online (Sandbox Code Playgroud) 我尝试优化工作计算着色器。它的目的是创建一个图像:找到合适的颜色(使用一个小调色板),然后调用imageStore(image, ivec2, vec4).
这里是代码:
struct Entry
{
*some other data*
uint rgb;
};
layout(binding = 0) uniform SConfiguration
{
Entry materials[MATERIAL_COUNT];
} configuration;
void main()
{
Entry material = configuration.materials[currentMaterialId];
float r = (material.rgb >> 16) / 255.;
float g = ((material.rgb & G_MASK) >> 8) / 255.;
float b = (material.rgb & B_MASK) / 255.;
imageStore(outImage, ivec2(gl_GlobalInvocationID.xy), vec4(r, g, b, 0.0));
}
Run Code Online (Sandbox Code Playgroud)
我想清理/优化一下,因为这种颜色转换在着色器中看起来很糟糕/无用(并且应该预先计算)。我的问题是: …