3 回答

TA貢獻(xiàn)2021條經(jīng)驗 獲得超8個贊
豎起大拇指給datenwolf!我完全同意他的方法。要為每個頂點(diǎn)添加相鄰三角形的法線向量,然后進(jìn)行歸一化。我只想稍微介紹一下答案,并仔細(xì)研究具有x / y步長不變的矩形,平滑網(wǎng)格的特殊但很常見的情況。換句話說,每個點(diǎn)的高度都可變的矩形x / y網(wǎng)格。
這種網(wǎng)格是通過在x和y上循環(huán)并為z設(shè)置一個值來創(chuàng)建的,并且可以表示類似山丘的表面。因此,網(wǎng)格的每個點(diǎn)都由一個向量表示
P = (x, y, f(x,y))
其中f(x,y)是給出網(wǎng)格上每個點(diǎn)的z的函數(shù)。
通常要繪制這樣的網(wǎng)格,我們使用TriangleStrip或TriangleFan,但是任何技術(shù)都應(yīng)為生成的三角形提供相似的形貌。
|/ |/ |/ |/
...--+----U----UR---+--...
/| /| 2 /| /| Y
/ | / | / | / | ^
| / | / | / | / |
|/ 1 |/ 3 |/ |/ |
...--L----P----R----+--... +-----> X
/| 6 /| 4 /| /|
/ | / | / | / |
| /5 | / | / | /
|/ |/ |/ |/
...--DL---D----+----+--...
/| /| /| /|
對于atriangleStrip,每個頂點(diǎn)P =(x0,y0,z0)具有6個相鄰頂點(diǎn),表示為
up = (x0 , y0 + ay, Zup)
upright = (x0 + ax, y0 + ay, Zupright)
right = (x0 + ax, y0 , Zright)
down = (x0 , y0 - ay, Zdown)
downleft = (x0 - ax, y0 - ay, Zdownleft)
left = (x0 - ax, y0 , Zleft)
其中ax / ay分別是x / y軸上的恒定網(wǎng)格步長。在正方形網(wǎng)格上,ax = ay。
ax = width / (nColumns - 1)
ay = height / (nRows - 1)
因此,每個頂點(diǎn)都有6個相鄰的三角形,每個三角形都有自己的法向矢量(表示為N1至N6)??梢允褂枚x三角形邊的兩個向量的叉積來計算這些值,并小心執(zhí)行叉積的順序。如果法向矢量指向您的Z方向:
N1 = up x left =
= (Yup*Zleft - Yleft*Zup, Xleft*Zup - Xup*ZLeft, Xleft*Yup - Yleft*Xup)
=( (y0 + ay)*Zleft - y0*Zup,
(x0 - ax)*Zup - x0*Zleft,
x0*y0 - (y0 + ay)*(x0 - ax) )
N2 = upright x up
N3 = right x upright
N4 = down x right
N5 = downleft x down
N6 = left x downleft
每個點(diǎn)P的最終法向矢量為N1至N6之和。我們求和后歸一化。創(chuàng)建循環(huán),計算每個法線向量的值,將它們相加然后進(jìn)行歸一化非常容易。但是,正如Shickadance先生所指出的那樣,這可能會花費(fèi)相當(dāng)長的時間,尤其是對于大型網(wǎng)格物體和/或在嵌入式設(shè)備上。
如果我們仔細(xì)觀察并手動執(zhí)行計算,我們將發(fā)現(xiàn)大多數(shù)項相互抵消,從而為我們得出的向量N提供了非常優(yōu)雅且易于計算的最終解決方案。避免計算N1到N6的坐標(biāo),從而對每個點(diǎn)進(jìn)行6個叉積和6個加法運(yùn)算,從而加快了計算速度。代數(shù)幫助我們直接跳到解決方案,使用更少的內(nèi)存和更少的CPU時間。
我將不顯示計算的詳細(xì)信息,因為它很長但是很簡單,并且會跳到網(wǎng)格上任何點(diǎn)的法線向量的最終表達(dá)式。為了清楚起見,僅分解了N1,其他向量看起來相似。求和后,我們得到尚未歸一化的N:
N = N1 + N2 + ... + N6
= .... (long but easy algebra) ...
= ( (2*(Zleft - Zright) - Zupright + Zdownleft + Zup - Zdown) / ax,
(2*(Zdown - Zup) + Zupright + Zdownleft - Zup - Zleft) / ay,
6 )
你去!只要標(biāo)準(zhǔn)化此向量,就可以知道網(wǎng)格上任何點(diǎn)的法線向量,只要您知道其周圍點(diǎn)的Z值以及網(wǎng)格的水平/垂直步長即可。
請注意,這是周圍三角形法線向量的加權(quán)平均值。權(quán)重是三角形的面積,并且已經(jīng)包含在叉積中。
您甚至可以只考慮四個周圍點(diǎn)(上,下,左和右)的Z值來進(jìn)一步簡化它。在這種情況下,您會得到:
| \|/ |
N = N1 + N2 + N3 + N4 ..--+----U----+--..
= ( (Zleft - Zright) / ax, | /|\ |
(Zdown - Zup ) / ay, | / | \ |
2 ) \ | / 1|2 \ | /
\|/ | \|/
..--L----P----R--...
/|\ | /|\
/ | \ 4|3 / | \
| \ | / |
| \|/ |
..--+----D----+--..
| /|\ |
這更加優(yōu)雅,計算速度更快。
希望這可以使一些網(wǎng)格更快。干杯
- 3 回答
- 0 關(guān)注
- 1226 瀏覽
添加回答
舉報