首页 > 解决方案 > 如何使用 MDL 对边界框进行命中测试

问题描述

我正在尝试计算与 MDL 边界框的交集,我的代码基于 WM 在http://metalbyexample.com/picking-hit-testing/#more-738上的精彩文章

t0 应该是最近点的想法https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-sphere-intersection

https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-box-intersection

但这并没有发生

extension MDLAxisAlignedBoundingBox {

    func intersect(_ ray: Ray) -> float4? {

        var tmin = minBounds
        var tmax = maxBounds

        let inverseDirection = 1 / ray.direction

        var sign : [Int] = [(inverseDirection.x < 0) ? 1 : 0,(inverseDirection.y < 0) ? 1 : 0,(inverseDirection.z < 0) ? 1 : 0]


        var bounds : [float3] = [minBounds,maxBounds]


        var t0 = Float(minBounds.z)

        if ((tmin.x > tmax.y) || (tmin.y > tmax.x)){
            return nil
        }



        if (tmin.y > tmin.x){
             tmin.x = tmin.y;
        }


        if (tmax.y < tmax.x){
            tmax.x = tmax.y;
        }

        tmin.z = (bounds[sign[2]].z - ray.origin.z) * inverseDirection.z
        tmax.z = (bounds[1-sign[2]].z - ray.origin.z) * inverseDirection.z



        if ((tmin.x > tmax.z) || (tmin.z > tmax.x)){
            return nil
        }

        if (tmin.z > tmin.x){
            tmin.x = tmin.z
            t0 = tmin.x
        }

        if (tmax.z < tmax.x){
            tmax.x = tmax.z
            t0 = tmax.z
        }


        return float4(ray.origin + ray.direction * t0, 1)
    }
}

预计如果最后达到的结果应该是最短的向量。

先感谢您

标签: swift3dmetalmetalkit

解决方案


这是解决方案:

extension MDLAxisAlignedBoundingBox {

        func intersect(_ ray: Ray) -> float4? {

            var tmin = minBounds
            var tmax = maxBounds

            let inverseDirection = 1 / ray.direction

            var sign : [Int] = [(inverseDirection.x < 0) ? 1 : 0,(inverseDirection.y < 0) ? 1 : 0,(inverseDirection.z < 0) ? 1 : 0]


            var bounds : [float3] = [minBounds,maxBounds]


            var t0 = Float(minBounds.z)

            if ((tmin.x > tmax.y) || (tmin.y > tmax.x)){
                return nil
            }



            if (tmin.y > tmin.x){
                 tmin.x = tmin.y;
            }


            if (tmax.y < tmax.x){
                tmax.x = tmax.y;
            }

            tmin.z = (bounds[sign[2]].z - ray.origin.z) * inverseDirection.z
            tmax.z = (bounds[1-sign[2]].z - ray.origin.z) * inverseDirection.z



            if ((tmin.x > tmax.z) || (tmin.z > tmax.x)){
                return nil
            }

            if (tmin.z > tmin.x){
                tmin.x = tmin.z
                t0 = tmin.x
            }

            if (tmax.z < tmax.x){
                tmax.x = tmax.z
                t0 = tmax.z
            }


            return float4(ray.origin + ray.direction * t0, 1)

  }

}

你必须确保你指向正确的方向。

far / (near - far)

您的

eyeRayDir.z = -1

和相机位置

camera.position = [0, 0, 15]

在你的节点类中你应该有

var boundingBox = MDLAxisAlignedBoundingBox()
var size: float3 {
    return boundingBox.maxBounds - boundingBox.minBounds
}

希望有帮助


推荐阅读