天天看點

Surface Normal Vector in OpenCascade

摘要abstract:表面上某一點的法向量(normal vector)指的是在該點處與表面垂直的方向。對于平面,其上各點的法向是一樣的,統一為這個平面的法向。對于曲面,各點具有不同的法向量。幾何對象的法向量定義了它在空間中的方向,法向量是在進行光照處理時的重要參數。是以在顯示造型算法離散曲面後的網格時,設定正确的法向量對場景的光照、光線追蹤效果有直接影響。本文結合opencascade中代碼,對其法向量的計算方法進行分析,稍加修改即可用到實際的程式中。 關鍵字key words:opencascade, normal vector, mesh normal, openscenegraph

surface normal vector in opencascade

[email protected]

摘要abstract:表面上某一點的法向量(normal vector)指的是在該點處與表面垂直的方向。對于平面,其上各點的法向是一樣的,統一為這個平面的法向。對于曲面,各點具有不同的法向量。幾何對象的法向量定義了它在空間中的方向,法向量是在進行光照處理時的重要參數。是以在顯示造型算法離散曲面後的網格時,設定正确的法向量對場景的光照、光線追蹤效果有直接影響。本文結合opencascade中代碼,對其法向量的計算方法進行分析,稍加修改即可用到實際的程式中。 

關鍵字key words:opencascade, normal vector, mesh normal, openscenegraph,  

表面上某一點的法向量(normal vector)指的是在該點處與表面垂直的方向。對于平面,其上各點的法向是一樣的,統一為這個平面的法向。對于曲面,因為它在計算機圖形中是由許多片小平面的多邊形逼近來表示的,是以每個頂點的法向量都不一樣。是以,曲面上每個點的法向量計算就可以根據不同的應用有不同的算法,則最後的顯示效果也是不同的。幾何對象的法向量定義了它在空間中的方向,法向量是在進行光照處理時的重要參數。因為法向量決定了該如何計算光照,決定了該點能夠吸收多少光照。 

opengl有很大的靈活性,它隻提供賦予目前頂點法向量的函數,并不在内部具體計算其法向量,這個值由程式設計者自己根據需要設定。盡管法向量并不需要指定為機關向量,但是如果所有表面法向量都使用機關法向量可減少計算量。使用下列指令可自動将所有非機關法向量機關化:glenable(gl_normalize),該指令也會對那些經過縮放或錯切等幾何變換的表面向量進行規範化。另一可用選項是指定一個法向量清單,與頂點數組混合使用。 

在很多應用程式中網格上的各頂點都需要一個表面法向量,它的用途很廣泛: 

l 計算光照; 

l 背面剔除; 

l 模拟粒子系統在表面的“彈跳”效果; 

l 對隻需要正面而加速碰撞檢測; 

通常我們在繪制幾何體時都會指定法向量。當得到一個模型本身沒有法向量時,則有必要通過現有的資料生成。通常表面法向量可能儲存于三角形級或頂點級,其中的一個技巧就是平均相鄰三角形的表面法向量,并将結果規範化。一般可以這樣假設三角形的頂點按逆時針排列,通過叉乘就可以得到外表面的法向量了。當然有些有情況下,頂點的順序是未知且比較混亂的,這樣就比較麻煩了。這個筆者也沒有仔細深入研究,推薦讀者看一下《計算非固定結構序列的多邊形的頂點法線》這篇論文。通過平均三角形法向量求得頂點法向量是一種經驗性的方法,不具有通用性,雖然很多情況下可以正确地工作,但有些情況下還是無法正常使用的。(以上内容摘自《openscenegraph三維渲染引擎程式設計指南》) 

opengl并不能自動計算幾何對象的法向量,而隻能由使用者顯式指定。法向量的計算是一個純粹的幾何和數學問題,這裡隻簡略地區分了幾種情況。 

首先,講述平面法向量的計算方法。在平面内,有兩條相交的線段,假設其中一條為矢量w,另一條為矢量v,且平面法向量為n。如圖2.1所示,則平面法向量就等于兩個矢量的叉積(遵循右手法則),即n=w x v。 

Surface Normal Vector in OpenCascade

figure 2.1 normal vector of plane 

比如計算一個三角形的法向就可以用它的三個頂點來計算,如圖2.2所示: 

Surface Normal Vector in OpenCascade

figure 2.2 finding the normal vector of a triangle 

解析曲面是由數學方程描述的平滑的、可微曲面。在opencascade中曲面是由geom_surface來用參數u, v來表示的,相當于曲面的數學方程,是曲面的精确表示。通過計算曲面上一點u,v對應的一次微分即可得到曲面在該點處的切線,如下圖所示: 

Surface Normal Vector in OpenCascade

figure 2.3 tangents on a surface 

關于參數u,v表示的bezier曲面的微分計算方法如下所示: 

Surface Normal Vector in OpenCascade

若需要計算參數對應點處的法向量,還需要對這兩個切向量進行叉乘即可,計算方法如下所示: 

Surface Normal Vector in OpenCascade
Surface Normal Vector in OpenCascade

figure 2.4 normal on a surface 

在opengl中,這種情況占了大多數。求平均多邊形的法向量,利用不在同一直線上的多邊形三個頂點v1, v2, v3,則兩個矢量的叉積((v2 - v1)x(v3 - v1))垂直于多邊形,即為該多邊形的法向量,計算後需要經過規範化處理。 

對于求多邊形網格上各頂點上的法向量,由于每個頂點同時位于幾個不同的多邊形邊界上,則需要求出周圍幾個多邊形的法向量,然後做權重平均。一般來說,可以使用每個多邊形的面積做為權重的權值。 

如下圖所示,曲面頂點p的法向就等于其相鄰的四個平面的法向平均值: 

Surface Normal Vector in OpenCascade

figure 2. 曲面頂點的平均法向計算 

注:當計算多邊形網格表示的曲面時,最好是使用平均法向的方法來計算。當曲面是用參數方程來表示時,就可以用求微分和叉乘的方法來直接計算法向量,不再需要使用平均法向了。 

在opencascade中将形狀資料儲存為stl格式時就涉及到了将形狀三角剖分及其法向量的計算實作。其計算方法如上所述,也是分成三種方式: 

l 參數方程表示的曲面; 

l 平面; 

l 網格; 

将其代碼列出如下: 

如果是參數方程表示的曲面,若不是平面,則根據切線的叉乘來計算各頂點處的法向量;若是平面,則隻計算一個頂點處理的法向量,減少計算量。 若是離散後的網格面,則根據三角形的法向量的計算方法來計算每個頂點處的法向量。 

生成頂點法向量(osgutil::smoothingvisitor)類繼承自osg::nodevisitor類,采用visitor模式,周遊場景中的幾何體,生成頂點法向量。osgutil::smoothingvisitor的使用很友善。對算法實作感興趣的讀者可以結合源程式來了解研究。 

opencascascade中有曲面的參數表示,是以對這類曲面可以得用參數方程計算出曲面上的頂點的準确法向量。對于沒有參數表示的網格曲面,可以用平均法向量的方法來計算出一個法向量。 

openscenegraph中也有快速計算網格曲面法向量的類osgutil::smoothingvisitor。 

1. kelly dempski, focus on curves and surfaces, premier press, 2003 

2. 王銳,錢學雷,openscenegraph三維渲染引擎設計與實踐,清華大學出版社 

3. 肖鵬,劉更代,徐明亮,openscenegraph三維渲染引擎程式設計指南,清華大學出版社 

pdf version: surface normal vector

繼續閱讀