解释 Inigo Quilez 如何计算 SDF 框法线

问题描述 投票:0回答:0

Inigo Quilez 的网站有一个 3D 射线表面相交 页面,用于带符号的距离函数,其中一个用于基本的 3D 盒子:

// axis aligned box centered at the origin, with size boxSize
vec2 boxIntersection( in vec3 ro, in vec3 rd, vec3 boxSize, out vec3 outNormal ) 
{
    vec3 m = 1.0/rd; // can precompute if traversing a set of aligned boxes
    vec3 n = m*ro;   // can precompute if traversing a set of aligned boxes
    vec3 k = abs(m)*boxSize;
    vec3 t1 = -n - k;
    vec3 t2 = -n + k;
    float tN = max( max( t1.x, t1.y ), t1.z );
    float tF = min( min( t2.x, t2.y ), t2.z );
    if( tN>tF || tF<0.0) return vec2(-1.0); // no intersection
    outNormal = (tN>0.0) ? step(vec3(tN),t1)) : // ro ouside the box
                           step(t2,vec3(tF)));  // ro inside the box
    outNormal *= -sign(rd);
    return vec2( tN, tF );
}

除了计算交点外,它还计算交点处的表面法线。计算法线是我感兴趣的部分。我想了解它是如何做到这一点的,但该页面根本没有分解数学,而且我还没有找到任何其他来源(也不是理解这个过程限制了我对搜索内容的理解)。

有些部分在概念上是有意义的,比如计算射线的近/远交点。但是构成该计算的常数的计算对我来说是迷失的。例如,它似乎在做

ray_origin/ray_direction
,将一个位置除以一个(可能是归一化的)方向。这会产生什么样的结果?我原以为这是荒谬的。

我想了解它是如何工作的,而不是把它当作一个黑盒子。

我发现另一个版本,修改为只返回法线,但共享许多相同的计算。解释起来可能更容易,我只是希望我知道它是如何工作的。

vec3 boxNormal( in vec3 ro, in vec3 rd, vec3 boxSize)
{
    vec3 m = 1.0/rd;
    vec3 n = m*ro;
    vec3 k = abs(m)*boxSize;
    vec3 t1 = -n - k;
    return -sign(rd)*step(t1.yzx,t1.xyz)*step(t1.zxy,t1.xyz);
}
intersection raycasting normals
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.