编辑:认为我已经缩小了问题的范围。跳到跑步部分。
我正在尝试在我的顶点着色器中对 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 纹理教程不同。