You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenGL立方体透明混合问题:EBO索引排序错误排查

OpenGL立方体透明混合的面排序问题

已通过按正确顺序绘制实现多立方体的透明混合,但单立方体各面的混合效果始终异常。尝试通过重排EBO中的索引,让立方体的面按正确顺序绘制解决问题,但目前排序结果不正确。

排序实现代码

void GECCube::SortIndicies(glm::mat4 ModelMatrix)
{

glm::vec4 View = glm::vec4{0.0f, 0.0f, -3.0f, 0.f};
unsigned int NewIndices[36];
std::multimap<float, std::vector<unsigned int>> SortedMap;


for (int i = 0; i < 12; i += 2)
    {
    
glm::vec4 Tri1 = glm::vec4{
        (Vertices[Indices[i * 3] * 3] + Vertices[Indices[(i * 3) + 1] * 3] + Vertices[Indices[(i * 3) + 2] * 3]) / 3, //X
        (Vertices[Indices[i * 3] * 4] + Vertices[Indices[(i * 3) + 1] * 4] + Vertices[Indices[(i * 3) + 2] * 4]) / 3, //Y
        (Vertices[Indices[i * 3] * 5] + Vertices[Indices[(i * 3) + 1] * 5] + Vertices[Indices[(i * 3) + 2] * 5]) / 3, //Z
        0.f
        };

    glm::vec4 Tri2 = glm::vec4{
        (Vertices[Indices[(i + 1) * 3] * 3] + Vertices[Indices[((i + 1) * 3) + 1] * 3] + Vertices[Indices[((i + 1) * 3) + 2] * 3]) / 3, //X
        (Vertices[Indices[(i + 1) * 3] * 4] + Vertices[Indices[((i + 1) * 3) + 1] * 4] + Vertices[Indices[((i + 1) * 3) + 2] * 4]) / 3, //Y
        (Vertices[Indices[(i + 1) * 3] * 5] + Vertices[Indices[((i + 1) * 3) + 1] * 5] + Vertices[Indices[((i + 1) * 3) + 2] * 5]) / 3, //Z
        0.f
        };

    glm::vec4 PlaneMed = glm::vec4{(Tri1.x + Tri2.x) / 2, (Tri1.y + Tri2.y) / 2 , (Tri1.z + Tri2.z) / 2, 0 };

    float Distance = glm::length(View - (ModelMatrix * PlaneMed));


    std::vector<unsigned int> TransportVector = std::vector<unsigned int>{ Indices[i * 3] , Indices[(i * 3) + 1] , Indices[(i * 3) + 2],
        Indices[(i + 1) * 3] , Indices[((i + 1) * 3) + 1] , Indices[((i + 1) * 3) + 2] };


    SortedMap.insert(std::pair<float, std::vector<unsigned int>>(Distance, TransportVector));
    }


auto MapIterator = SortedMap.begin();
for (int i = 0; i < 12; i += 2)
    {

    NewIndices[i * 3] = MapIterator->second[0];
    NewIndices[(i * 3) + 1] = MapIterator->second[1];
    NewIndices[(i * 3) + 2] = MapIterator->second[2];
    NewIndices[(i + 1) * 3] = MapIterator->second[3];
    NewIndices[((i + 1) * 3) + 1] = MapIterator->second[4];
    NewIndices[((i + 1) * 3) + 2] = MapIterator->second[5];

    if (i != 10) { MapIterator++; }
    
    }


std::copy(std::begin(NewIndices), std::end(NewIndices), std::begin(Indices));

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
}

核心问题分析

相机固定在位置0,0,-3.0,未实现复杂相机逻辑。目前怀疑问题出在相机与平面的距离计算部分:

float Distance = glm::length(View - (ModelMatrix * PlaneMed));

最初直接用View - PlaneMed时,所有索引的距离值都相同,于是尝试将模型矩阵融入计算——认为既然着色器用模型矩阵确定绘制位置,那也能用它找到模型空间中平面的正确位置,但不确定这个逻辑是否错误。

多立方体绘制代码片段

...    
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, it->second * 0.9f * std::clamp((float) sinf(( float )SDL_GetTicks() / 1000.f) + 1.5f, 0.f, 3.f));
float angle = 20.0f * ((i + 1)/20) * ( float )SDL_GetTicks() / 200 * glm::radians(50.0f);
model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
    
OGLCMain->MainCube.SortIndicies(model);
            
int modelLoc = glGetUniformLocation(OGLCMain->ShaderProgram, "model");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
...

内容的提问来源于stack exchange,提问作者Grusen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 10:54:58