我正在生成噪声到三维纹理在计算着色器,然后建立网格在CPU上。当我在主循环中这样做时,它工作得很好,但我注意到,在第一次渲染时,我只得到了1%的噪声。下面是一个很小的例子,在这里,我试图用着色器中的一个填充3D纹理,但得到零或噪声作为回报:
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <stdlib.h>
void error(const char* message) { ... }
const char* slurp_file(const char* filename) { ... }
int main() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(100, 100, "", NULL, NULL);
glfwMakeContextCurrent(window);
gladLoadGL();
// create texture
GLuint texture;
glGenTextures(1, &texture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_3D, texture);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
// allocate it
size_t size = 4;
glTexImage3D(GL_TEXTURE_3D, 0, GL_R32F, size, size, size, 0, GL_RED, GL_FLOAT, NULL);
// create shader
const char* shader_source = slurp_file("shaders/example.comp");
GLuint shader = glCreateShader(GL_COMPUTE_SHADER);
glShaderSource(shader, 1, &shader_source, NULL);
glCompileShader(shader);
// check it
int code;
glGetShaderiv(shader, GL_COMPILE_STATUS, &code);
if (!code) error("shader compilation failed");
// create program
int program = glCreateProgram();
glAttachShader(program, shader);
glLinkProgram(program);
// check it
glGetProgramiv(program, GL_LINK_STATUS, &code);
if (!code) error("program linkage failed");
// run shader
glUseProgram(program);
// i don't think it's needed, as 0 would be a default value
int uniform_loc = glGetUniformLocation(program, "img_output");
glUniform1i(uniform_loc, 0);
// dispatch and sync
glDispatchCompute(size, size, size);
// originally i had GL_TEXTURE_FETCH_BARRIER_BIT here
glMemoryBarrier(GL_ALL_BARRIER_BITS);
// read texture data
float* data = malloc(size * size * size * sizeof(float));
glBindImageTexture(0, texture, 0, GL_TRUE, 0, GL_READ_WRITE, GL_R32F);
glGetTexImage(GL_TEXTURE_3D, 0, GL_RED, GL_FLOAT, data);
// prints 0s or noise, but i expect all 1s
for (int i = 0; i < size * size * size; i++)
printf("%f ", data[i]);
}
这是着色器:
#version 430
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
layout(binding = 0, r32f) writeonly uniform image3D img_output;
void main() {
ivec3 texture_coords = ivec3(gl_GlobalInvocationID.xyz);
vec4 pixel = vec4(1, 0, 0, 0);
imageStore(img_output, texture_coords, pixel);
}
在glDispatchCompute
之后添加睡眠没有什么作用,所以我想我错过了一些锁定吗?或者纹理应该以其他方式配置?
发布于 2022-01-26 06:06:38
在执行计算着色器之前,需要将纹理绑定到图像单元。纹理对象与着色器之间的绑定是通过纹理图像单元建立的。着色器知道单元,因为您设置了单元变量或使用布局限定符指定了绑定点,但还需要将对象绑定到该单元:
glBindImageTexture(0, texture, 0, GL_TRUE, 0, GL_READ_WRITE, GL_R32F);
glDispatchCompute(size, size, size);
https://stackoverflow.com/questions/70857263
复制相似问题