GLSL не может получить значение sampler3D - PullRequest
0 голосов
/ 24 апреля 2019

Я не могу получить значение sampler3D в своем фрагментном шейдере GLSL.

Я пишу шейдер в GLSL и хочу взять sampler3D (3d-текстуру) в качестве объемных данных и выполнить объемный рендеринг.Тем не менее, кажется, я не могу связать 3D-текстуры с Sampler3D моего шейдера.texture3D () всегда возвращает (0,0,0,0) на стороне шейдера.Но на стороне приложения я могу использовать glGetTexImage для получения данных.

Сторона приложения (dS - объект класса Shader):

dS.use();
dS.setInt("volumeData", 0);
uint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_3D, texture);
float data[64];
for (int i = 0; i < 64; ++i)    data[i] = 1.0f;
glTexImage3D(GL_TEXTURE_3D, 0, GL_R16F, 4, 4, 4, 0, GL_RED, GL_FLOAT, data);
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);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_3D, 0);
float read[64];
glBindTexture(GL_TEXTURE_3D, texture);
glGetTexImage(GL_TEXTURE_3D, 0, GL_RED, GL_FLOAT, read);
std::cout << read[0] << "," << read[63] << std::endl;   // 1,1
glBindTexture(GL_TEXTURE_3D, 0);

// When drawing.

dS.use();
dS.setMat4("model", glm::mat4(1.0f));
dS.setMat4("view", view);
dS.setMat4("projection", projection);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_3D, texture);
cube.draw();

Vertex Shader

#version 330 core
// for snow rendering
layout (location = 0) in vec3 aPos;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);
}

Фрагментный шейдер

#version 330
out vec4 FragColor;

uniform sampler3D volumeData;

void main()
{
    ivec3 size = textureSize(volumeData, 0);
    float c = texture3D(volumeData, vec3(0)).x;
    if (size.x == 1)
        FragColor = vec4(1.0, 0.0, c, 1.0);
    else if (size.x > 2)
        FragColor = vec4(0.0, 1.0, 0.0, 1.0);
    else if (size.x == 0)
        FragColor = vec4(0.0, 0.0, 1.0, 1.0);
    else
        FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}

Я получил только красный куб, что означает size.x == 1, а texture3D возвращает 0, что, как ожидается, будет size.x == 4, а texture3D возвращает 1.0

Я использовал аналогичный метод для 2d текстуры, и он работает.Так что я думаю, что мой класс шейдеров правильный.И я также попытался добавить glEnable (GL_TEXTURE_3D), прежде чем я сделал какую-либо операцию с текстурой 3d.

И я не уверен, поможет ли это: я использовал glfw-3.2.1 WIN64 и рад.

1 Ответ

0 голосов
/ 25 апреля 2019

Я решил это. Это действительно глупая опечатка.

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

следует использовать GL_TEXTURE_3D вместо GL_TEXTURE_2D. А так как GL_TEXTURE_MIN_FILTER, по умолчанию используется GL_NEAREST_MIPMAP_LINEAR. Это приводит к неполноте mipmap.

...