无限制阵列纹理不起作用

Bindless array texture not working

我将对象的 material 存储在由漫反射、凹凸、镜面反射等组成的数组纹理 2D 中。然后按顶点、顶点、uv、法线存储此纹理数组的句柄VAO 中的数组,而不是使用 UBO 或 SSBO 来实现相同的目的。

我的目标是将整个模型压缩到一个顶点数组对象中,因为一个模型可能有很多网格,每个网格可能有自己的纹理。这样,通过按顶点存储纹理句柄,我可以在 1 个绘制调用中渲染整个模型。

问题是所有对象都呈现黑色,向我暗示采样器不工作或不知何故句柄没有完全传输。着色器程序编译成功,几何体渲染正确(也就是说,我可以用固定颜色替换最终的漫反射颜色并查看场景)。


纹理创建:

void TextureManager::FinishWorkOrders()
{
    for ( ... ) {
        Material_WorkOrder *material = Mat_Work_Orders[x];   
        glGenTextures(1, material->gl_array_ID);
        glBindTexture(GL_TEXTURE_2D_ARRAY, *material->gl_array_ID);
        glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, material->size.x, material->size.y, 5, 0, GL_RGBA, GL_UNSIGNED_BYTE, material->textureData);
        glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
        glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_GENERATE_MIPMAP, GL_TRUE);
        glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
        glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f);

        // Material handle is of type GLuint64
        *material->handle = glGetTextureHandleARB(*material->gl_array_ID);
        glMakeTextureHandleResidentARB(*material->handle);
    }
}

VAO 代数:

GLuint ModelManager::genVAO(const vector<vec3> &vs, const vector<vec2> &uv, const vector<vec3> &nm, const vector<vec3> &tg, const vector<vec3> &bt, const vector<GLuint64*> &ts)
{
    AttribBuffers b;
    GLuint vao = 0;
    size_t arraySize = vs.size();
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    glGenBuffers(MAX_BUFFERS, b.buffers);

    // Vertex array
    glBindBuffer(GL_ARRAY_BUFFER, b.buffers[0]);
    glBufferData(GL_ARRAY_BUFFER, arraySize * sizeof(vec3), &vs[0][0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    ...

    // Texture Handle array
    glBindBuffer(GL_ARRAY_BUFFER, b.buffers[5]);
    glBufferData(GL_ARRAY_BUFFER, arraySize * sizeof(GLuint64), &ts[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(5);
    glVertexAttribLPointer(5, 1, GL_UNSIGNED_INT64_ARB, 0, 0);

    glBindVertexArray(0);
    return vao;
}

着色器使用:

顶点:

#version 450
#extension GL_ARB_bindless_texture : require
#extension GL_ARB_gpu_shader5 : require 
#extension GL_ARB_gpu_shader_int64 : require

layout (location = 0) in vec3 vertex;

...

layout (location = 5) in uint64_t texHandle;

flat out uint64_t TextureHandle;

void main(void)
{
    TextureHandle           = texHandle;

    ...

    gl_Position             = worldMVP * v;         
}

片段:

#version 450
#extension GL_ARB_bindless_texture : require
#extension GL_ARB_gpu_shader5 : require 
#extension GL_ARB_gpu_shader_int64 : require

flat in uint64_t TextureHandle;

layout (location = 0) out vec4 DiffuseOut; 

void main()                                 
{                           
    sampler2DArray MaterialMap = sampler2DArray(TextureHandle);

    ... 

    DiffuseOut = texture(MaterialMap, vec3(TexCoord0, 0));
}

问题是 glBufferData 不能接受指针向量。

我以这种方式设置我的数据,以便最后一个顶点属性数组是一个 Gluint64* 句柄数组,原因有两个: 1) 这样每个三角形的适当纹理就会从顶点着色器流到片段着色器,2) 这样我就可以提前创建数组并等待创建纹理并通过更新自动更新数组单独的底层指针

这可行,但向量需要从类型 GLuint* 更改为 GLuint(放下指针)。