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

BVH结构在着色器中无法检测三角形相交但CPP代码运行正常

我正在学习渲染技术,掌握光线追踪后尝试实现BVH加速结构。目前通过派发阴影射线检测三角形相交来测试:射线能成功与AABB盒相交,但无法检测到任何三角形相交;但把着色器代码复制到CPP中运行时,三角形相交检测却能正常工作。

BVH遍历(着色器代码)

void TraceRay(inout RayPayload Payload)
{
     float tMin = FLOAT_MAX;
    
    int Stack[MAX_STACK_SIZE];
    int StackPtr = 0;
       
    Stack[StackPtr++] = 0;

    while(StackPtr > 0)
    {
        int CurrentNode = Stack[--StackPtr];

        if (BVHStructure.nodes[CurrentNode].Primitive[0] != -1) // is a leaf
        {
            for (int i = 0; i < 20; i++)
            {
                if (BVHStructure.nodes[CurrentNode].Primitive[i] == -1)
                    break;
              
                if (IntersectTriangle(Payload, BVHStructure.nodes[CurrentNode].Primitive[i]))
                {
                    Payload.InLight = false;
                    return; 
                }
            }
        }
        else
        {
            int Child1 = BVHStructure.nodes[CurrentNode].LeftNode;
            int Child2 = BVHStructure.nodes[CurrentNode].RightNode;

            if (Child1 != -1)
            {
                float Distance1 = IntersectAABB(Payload, BVHStructure.nodes[Child1].BoundingBox);
                if (Distance1 != FLOAT_MAX)
                    Stack[StackPtr++] = Child1;
                   
            }

            if (Child2 != -1)
            {
                float Distance2 = IntersectAABB(Payload, BVHStructure.nodes[Child2].BoundingBox);
                if (Distance2 != FLOAT_MAX)
                    Stack[StackPtr++] = Child2;

            }
        }
    }
}

BVH构建(CPU端CPP代码)

void BVHBuilder::BuildBVH(int NodeIndex, int min, int max)
{
    if (max <= min)
        return;

    if (max - min <= 20)
    {
        size_t k = 0;
        BVHNode leafNode{};

        for (size_t i = std::max(min, 0); i < max; i++)
        {
            leafNode.BoundingBox.MinValue = glm::min(ComputeMinimum(m_TriangleData[i]), leafNode.BoundingBox.MinValue);
            leafNode.BoundingBox.MaxValue = glm::max(ComputeMaximum(m_TriangleData[i]), leafNode.BoundingBox.MaxValue);
            leafNode.Primitive[k] = i;
            k++;
        }

        m_Nodes.push_back(leafNode);
        m_Nodes[NodeIndex].RightNode = m_Nodes.size() - 1;
        
        return;
    }

    int median = (min + max) / 2;

    BVHNode LeftChild{};
    LeftChild.BoundingBox.MinValue = ComputeMinimum(m_TriangleData[min]);
    LeftChild.BoundingBox.MaxValue = ComputeMaximum(m_TriangleData[median]);

    m_Nodes.push_back(LeftChild);
    m_Nodes[NodeIndex].LeftNode = m_Nodes.size() - 1;
    

    BVHNode RightChild{};
    RightChild.BoundingBox.MinValue = ComputeMinimum(m_TriangleData[median]);
    RightChild.BoundingBox.MaxValue = ComputeMaximum(m_TriangleData[max]);

    m_Nodes.push_back(RightChild);
    m_Nodes[NodeIndex].RightNode = m_Nodes.size() - 1;

    BuildBVH(m_Nodes[NodeIndex].LeftNode, min, median);
    BuildBVH(m_Nodes[NodeIndex].RightNode, median, max);
}

阴影射线派发(着色器代码)

RayPayload DispatchShadowRay(in ivec2 Coordinate, in vec3 LightDirection)
{ 
    RayPayload Payload;
    Payload.Valid = true;
    Payload.InLight = true;

    
    vec2 NormalizedCoord = vec2(Coordinate) / vec2(WINDOW_WIDTH, WINDOW_HEIGHT);
    float DepthValue = texture(DepthBuffer, NormalizedCoord).r;

    if(DepthValue >= 1.0 - EPSILON)
    {
        Payload.Valid = false;
        return Payload;
    }

    DepthValue = DepthValue * 2.0 - 1.0;
    vec4 ViewSpace = InverseProjection * vec4(NormalizedCoord * 2.0 - 1.0, 
                                                       DepthValue, 1.0);

    ViewSpace /= ViewSpace.w;
    vec4 WorldSpace = InverseView * ViewSpace;
    Payload.Origin = WorldSpace.xyz;

    Payload.Direction = normalize(-LightDirection);
    Payload.Origin += Payload.Direction * 0.001;


    TraceRay(Payload);

    return Payload;
}

已做排查:

  • 修复着色器存储缓冲区数据对齐问题,无效
  • 核对世界空间坐标计算逻辑,未发现错误
  • 反复检查AABB相交和IntersectTriangle函数实现,未发现问题
  • 使用Nsight、Renderdoc调试,除存储对齐外无有效线索
  • BVH由CPU递归构建,三角形已在CPU上完成排序;不确定BVH遍历逻辑是否正确,该逻辑参考资料实现

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 23:00:41