ONB是在渲染器中看到的幾個概念,不過這玩意我仍是爲了放心在houdini可視化了下。框架
畢竟這玩意其實跟Houdini中copy的正交基徹底一個概念。創建up向量,造成正交矩陣.spa
ONB其實就是一個簡單的正交基,可是隻要是正交基就能表示在他做爲 基的狀況下的向量。 3個不相關向量 能夠 惟一的線性表示任何向量.code
做用:orm
(1),製做投射相機的投射光線方向blog
(2),lens_shader sampler points : 景深採樣點的變換,方便得出 透鏡與焦平面 光線投射方向get
下面主要看如何快速的將一些採樣點快速變換到 ONB座標架下(2):class
例如紅色球是攝像機的目標點(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向量構建的正交基.float
利用這個正交基能夠快速的將採樣點變換到這個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);