AlgebraMaster

Modern C++ 创造非凡 . 改变世界

导航

ONB视见坐标框架

ONB是在渲染器中看到的几个概念,不过这玩意我还是为了放心在houdini可视化了下。

毕竟这玩意其实跟Houdini中copy的正交基完全一个概念。建立up向量,形成正交矩阵.

 

ONB其实就是一个简单的正交基,但是只要是正交基就能表示在他作为 基的情况下的向量。 3个不相关向量 可以 唯一的线性表示任何向量.

作用:

(1),制作投射相机的投射光线方向

(2),lens_shader sampler points : 景深采样点的变换,方便得出    透镜与焦平面   光线投射方向

 

下面主要看如何快速的将一些采样点快速变换到 ONB坐标架下(2):

 

例如红色球是摄像机的目标点(target_point),蓝色点是眼睛的位置(eye)

蓝色的线可以看成一个向量,但是我们要的方向w是从 <红色点到蓝色的方向> 来建立 ONB坐标架.主要是满足右手坐标架

vector up = set(0,1,0);
vector target_pos = point(1,"P",0);


vector w = normalize(@P - target_pos);
vector u = cross(up,w);
vector v = cross(w,u);

v@ww = w;
v@uu = u;
v@vv = v;

现在可以看到ww,uu,vv向量构建的正交基.

 

 利用这个正交基可以快速的将采样点变换到这个ONB框架下.例如在 景深 这章。在单位圆(xy平面)的点要变换到这个坐标下:

 

 

 

vector eye = point(1,"P",0);
vector u = point(1,"uu",0);
vector v = point(1,"vv",0);

@P = eye + u*@P.x  + v*@P.y;

 

 

PBRT 2.2.5给出了一个从一个vector 构建一个coordinate system:

v1 是x轴向为图中的红色向量,v2是黄色,v3蓝色.

 

vector v1 = set(1,0,0);
v@v1 = normalize(v1);

if(abs(v1.x) > abs(v1.y)){

    float invLen = 1.f / sqrt(v1.x * v1.x + v1.z*v1.z);
    v@v2 = set(-v1.z * invLen , 0.f , v1.x*invLen);
    
}
else
{
    float invLen = 1.f / sqrt(v1.y * v1.y + v1.z*v1.z);
    v@v2 = set(0.0f, v1.z * invLen , -v1.y*invLen);
}

v@v3 = cross(@v1,@v2);

 

posted on 2019-06-12 18:51  gearslogy  阅读(645)  评论(0编辑  收藏  举报