2

编辑:认为我已经缩小了问题的范围。跳到跑步部分。

我正在尝试在我的顶点着色器中对 3d 纹理进行采样,我将使用纹素值作为 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);

运行着色器: 编辑:这里变得有趣了。如果我指定了不正确的统一名称或注释掉以下行,它似乎可以工作。

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 纹理教程不同。

4

1 回答 1

3

好吧想通了。

glUniform1i(sampler, GL_TEXTURE0);

GL_TEXTURE0 在这里不正确。

glUniform1i(sampler, 0);

是应该的样子。

于 2012-11-20T10:33:48.123 回答