GLSL: sampler3D в вершинном шейдере, текстура выглядит пустой

РЕДАКТИРОВАТЬ: думаю, что я сузил проблему. Перейти к разделу бега.

Я пытаюсь сэмплировать трехмерную текстуру в своем вершинном шейдере, я собираюсь использовать значения текселей в качестве угловых значений в Marching Cubes. У меня проблема в том, что независимо от того, какой метод я использую для его выборки, я всегда получаю (0,0,0,0). Я пытался использовать texelFetch и texture3D, и ни один из них, похоже, не работает.

Я также использую обратную связь преобразования, но насколько я знаю, это не должно вызывать эту проблему.

Настройка шейдера:

glEnable(GL_TEXTURE_3D);

Shader vertListTriangles(GL_VERTEX_SHADER_ARB);
vertListTriangles.setSource(lst_tri_vert); //Util to load from file.
vertListTriangles.compile();
vertListTriangles.errorCheck(); //Prints errors to console if they exist - shader compiles fine.

Shader geomListTriangles(GL_GEOMETRY_SHADER_ARB);
geomListTriangles.setSource(lst_tri_geom); //Util to load from file
geomListTriangles.compile();
geomListTriangles.errorCheck(); //Prints errors to console if they exist - shader compiles fine.

program.attach(vertListTriangles);
program.attach(geomListTriangles);

//Setup transform feedback varyings, also works as expected.
const GLchar* varyings1[1];

varyings1[0] = "gTriangle";
glTransformFeedbackVaryings(program.getID(), 1, varyings1, GL_INTERLEAVED_ATTRIBS);

program.link();

program.checkLink(); //Prints link errors to console - program links fine aparently.

Настройка текстуры:

glBindTexture(GL_TEXTURE_3D, textureID);
errorCheck("texture bind"); //<- Detects GL errors, I actually get a GL_INVALID_OPERATION here, not sure if its the cause of the problem though as all subsuquent binds go smoothly.

if(!(glIsTexture(textureID)==GL_TRUE)) consolePrint("Texture Binding Failed."); //Oddly the texture never registers as failed despite the previous error message.

//Generate Texture
GLfloat volumeData[32768*3];

for(int z = 0; z < 32; z++)
{
    for(int y = 0; y < 32; y++)
    {
        for(int x = 0; x < 32; x++)
        {
            //Set all 1s for testing purposes
            volumeData[(x*3)+(y*96)+(z*3072)] = 1.0f;
            volumeData[(x*3)+(y*96)+(z*3072)+1] = 1.0f;
            volumeData[(x*3)+(y*96)+(z*3072)+2] = 1.0f;
        }
    }
}

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_MAX_LEVEL, 0);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB8, 32, 32, 32, 0, GL_RGB,
         GL_FLOAT, volumeData);

glBindTexture(GL_TEXTURE_3D, 0);

Running Shader: EDIT: вот это становится интересным. Если я укажу неправильное унифицированное имя или закомментирую нижеследующие строки, это, похоже, будет работать

program.use();

//Disable Rastering
glEnable(GL_RASTERIZER_DISCARD);

//Input buffer: Initial vertices
glBindBuffer(GL_ARRAY_BUFFER, mInitialDataBuffer);

glEnableVertexAttribArray(0);
glVertexAttribIPointer(0, 1, GL_UNSIGNED_INT, 0, 0); //Initial input is array of uints

//Output buffer: Triangles
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mTriangleBuffer); //Triangle Markers, in the form of uints. NOT actual triangles.

//Texture setup

//If I comment out from here....
GLint sampler = glGetUniformLocation(program.getID(), "densityVol");
glUniform1i(sampler, GL_TEXTURE0);
glActiveTexture(GL_TEXTURE0);
//To here. It appears to work.

glBindTexture(GL_TEXTURE_3D, textureID);

//Just using this to debug texture.
//test is all 1s, so the texture is uploading correctly.
GLfloat test[32768*3];
memset(test, 0, sizeof(test));
glGetTexImage(GL_TEXTURE_3D, 0, GL_RGB, GL_FLOAT, test);

//Transform Feedback and Draw
glBeginTransformFeedback(GL_POINTS);

    glDrawArrays(GL_POINTS, 0, 29790);

glEndTransformFeedback();

//Re-enable Rastering and cleanup
glDisable(GL_RASTERIZER_DISCARD);
glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);

Мой код немного более распространен в реальности, но я надеюсь, что мне удалось отредактировать его в нечто связное. В любом случае, если я отображаю в выходной буфер, он действительно выводит некоторую информацию, однако обрабатывается так, как будто все данные текстуры равны 0. Я взломал шейдер, чтобы вместо этого вывести некоторые результаты теста, но не могу найти доказательств того, что шейдер правильно использует текстуру:

#version 410
#extension GL_EXT_gpu_shader4 : require

layout (location = 0) in int x_y_z;
uniform sampler3D densityVol;

out Voxel
{
    /*
    Each triangle is the edges it joins. There are 12 edges and so we need 12 bits. 4 For each edge.
    There are up to 32 voxels, which means we need 6 bits for each coord, which is 18.
    30 bits total.
    int format 00xxxxxxyyyyyyzzzzzz111122223333
    */
    uint triangles[5];
    uint triangleCount;

} vVoxel;

//... Omitted some huge ref tables.

void main()
{
    vec4 sample0 = texture3D(densityVol, vec3(0.1,0.1,0.1) );
    vec4 sample1 = texture3D(densityVol, vec3(0.9,0.9,0.9) );
    vec4 sample2 = texture3D(densityVol, vec3(0.1,0.1,0.9) );
    vec4 sample3 = texture3D(densityVol, vec3(0.9,0.9,0.1) );

    if(sample0.r > 0.0f)
    {
        vVoxel.triangles[1] = 1;
    }
    if(sample1.r > 0.0f)
    {
        vVoxel.triangles[2] = 2;
    }
    if(sample2.r > 0.0f)
    {
        vVoxel.triangles[3] = 3;
    }
    if(sample3.r > 0.0f)
    {
        vVoxel.triangles[4] = 4;
    }

    vVoxel.triangleCount = 5;
}

Не самый удачный тест, но я не хотел писать что-то с нуля. Если я изменяю условия if на if (true), тест выводит правильно. Когда шейдер скомпилирован, как указано выше, буфер пуст. Я использую GS для прохода.

Кто-нибудь может увидеть очевидную ошибку там? Я был в тупике около 2 часов, и я не вижу, чем я занимаюсь, в отличие от многих учебников по GLSL-текстурированию.

1 ответ

Ладно разобрался.

glUniform1i(sampler, GL_TEXTURE0);

GL_TEXTURE0 здесь неверен.

glUniform1i(sampler, 0);

Так и должно быть.

Другие вопросы по тегам