DirectX 7 著色方式

2021-06-22 06:49:10 字數 3277 閱讀 9596

在前面,我們已經講解了多個光照模型的方程,有了那些模型,讀者就能夠自己做出比較好看的demo了,如果想要更加精確,高階,好看的效果,讀者就需要自己去學習有關全域性光照系統的方法。使用全域性光照系統,需要掌握有關輻射著色的理論,這種理論難度很高,需要讀者有足夠的數學和物理理論知識,由於我自己在這方面也不是很了解,所以就不再講述這種更加精確的光照模型了。如果將來,我學會了這樣的知識,會在部落格中與大家一起分享的。期待吧!!!

在前面,我們都是在頂點著色器中進行光照計算的,讀者可能想知道,為什麼我們只是計算出了頂點的顏色,最後,整個三角形都具有了顏色了???這樣的功能是通過著色方法來實現的。所謂的著色方式,就是對某些量,在某乙個參考維度上進行插值計算,然後得到最後的結果。在下面將會向大家一一展示我自己目前掌握的幾種簡單的著色方法。

一般來說,在固定流水線中,一般支援如下的幾種著色方式:

固定著色,指的是,通過人為的,而不是通過光照計算來得到模型中多邊形的顏色,然後使用這個顏色,來填充整個三角形。這種方式,簡單,高效,但是,效果卻很不理想,基本上已經不使用了。

恆定著色,說的是通過光照計算,計算出每乙個多邊形的最終顏色,而不是通過人工指定,來給出每個多邊形的顏色,這樣的方法,使得物體整體看上去比較的逼真了。使用這樣的著色方法,對那些稜角分明的物體,比如立方體,長方體,這樣的物體進行著色,效果會很好,但是如果,要使用這樣的方法對比較圓潤的物體,比如球體進行著色,就會發現,效果很差。所以,恆定著色,一般也不用來使用,只有在某些效能要求上,才會使用恆定著色方法來對稜角分明的物體進行著色。

高洛德著色,是最常用的著色方法,也是我們前面幾個demo中使用的著色方法。下面,我們將詳細的講解高洛德著色方法。

gouraud shading 是法國計算機科學家henri gouraud發明的。這種著色方法,能夠產生出很平滑的3d圖形效果,大部分的3d遊戲都採用了這種著色方式來對物體進行著色。它的原理是通過光照計算,計算出三角形三個頂點的顏色值,然後使用插值方法,對三角形中所有的畫素進行插值計算,最後得到整個三角形的顏色值。如果讀者對這個文字描述,不是很清楚的話,那麼看下下圖:

上圖中,左邊的圖是乙個純紅的三角形,而右邊的三角形,看上去五顏六色。可是,如果讀者細心**的話,就會發現,它的頂點顏色實際上分別是紅色,綠色,和藍色。那它是通過怎麼樣的方式,最後形成這個樣子的了?

實際上,實現這樣功能的方法很簡單。只要通過簡單的線性插值計算,就可以得到了。

我們先來假設a點顏色為ac(255,0,0), bc(0,255,0), cc(0,0,255)。讀者應該對這種rgb表示方法很熟悉,所以不再解釋。

我們有了三角形三個頂點的顏色之後,我們自然也應該有這三個頂點的座標關係,如a(xa,ya), b(xb,yb), c(xc,yc)。

好了,有了這些資料之後,我們就可以計算插值了。

好了,說了這麼多,意思就是,我們在計算機中,繪製橫直線和縱直線要比繪製任意直線容易的多,也精確的多,而繪製橫直線比繪製縱直線,更加的容易點,所以,在三角形填充演算法中,一般都是使用橫向的掃瞄線,進行繪製。也就是說,只要我們獲得了這條橫向掃瞄線的左右端點的位置和顏色值,繪製這條直線就變的容易的多。事實上也的確是這樣的,但是有個問題,我們只是知道直線左右端點的位置和顏色而已,兩個端點之間的顏色該怎麼計算出來了?讀者,如果你這麼想,就明確了問題的關鍵部分了。我們解決這裡的問題,就是通過插值計算而來。

假設我們有一條橫向的直線,端點和顏色分別是s(xs,ys) , sc(sr,sg,sb), e(xe,ye) ec(er,eg,eb)

我們計算這兩個端點之間的步長:

x_step = xe - xs ;

有了步長之後,我們就可以使用這兩個端點的顏色值來對計算每乙個顏色分量上的步進值:

r_step = (er - sr) / x_step ;

g_step = (eg - sg) / x_step ;

b_step = (eb - sb) / x_step ;

在有了每乙個顏色分量的步進值之後,我們就可以按照,從s(起點)到e(終點),以每個畫素為單位進行插值了,即:

r_new = sr + r_step * (x_new - xs) ;

g_new = sg + g_step * (x_new - xs) ;

b_new = sb + b_step * (x_new - xs) ;

這樣,在這條直線上的x_new座標處,畫素顏色就為(r_new,g_new,b_new)了。如此反覆執行,整條直線就使用端點的兩種顏色插值計算出來了。

好了,我們掌握了對一條掃瞄線進行插值的方法之後,就可以來對三角形進行插值計算了。我們擁有三角形的三個頂點a,b,c和他們對應的顏色值ac, bc, cc。

繪製三角形的演算法有很多種,一般都是使用掃瞄線的方式,從上到下,繪製所有的掃瞄線。在我的部落格中講述了一種繪製三角形的方法,讀者可以到這裡來閱讀了解。

知道了如何對三角形進行填充之後,我們需要確定的就是每一條掃瞄線左右兩個端點的位置和顏色,然後使用直線插值演算法來對顏色進行插值,最後就能夠完整的繪製出整個插值的三角形了。

那麼如果獲取每一條掃瞄線的左右端點的顏色了?同樣的,我們也是使用插值的方法來進行。

yleft_step  = ya - yb ;

yright_step = ya - yc ;

在有了三角形左右兩邊的y軸步長之後,我們就可以來計算左右兩邊各個顏色分量的步進值了:

r_step_left =  (ar - br) / yleft_step ;

g_step_left = (ag - bg) / yleft_step ;

b_step_left = (ab - bb) / yleft_step ;

r_step_right = (ar - cr) / yright_step ;

g_step_right = (ag - cg) / yright_step ;

b_step_right = (ab - cb) / yright_step ;

好了,有了左右兩邊的步進值之後,我們就可以計算每條掃麵線的左右端點的顏色了,然後就可以用直線插值來進行繪製,最後整個三角形就被繪製出來了。

gouraud著色,就是使用這樣的方法來進行三角形的繪製,所以,我們在shader中,計算了頂點的顏色之後,它就會被插值,然後到畫素著色器中繪製正確的畫素顏色,從而達到很平滑的效果。

上面描述的幾種著色方式,在我自己編寫的軟體3d圖形渲染流水線中都支援,讀者可以從這裡看到一些截圖效果。

除了上面介紹的gouraud著色之外,還有一種著色方法,它的效果比gouraud著色效果更加的好,更加的逼真,這個將會在下篇文章中講解它的原理,以及如何使用shader來實現它。

好了,今天到這裡就結束了,下次再見!!!

Directx11 頂點著色器示例

以下是乙個簡單的頂點著色器實現 cbuffer cbperobject void vs float3 iposl position,float4 icolor color,out float4 oposh sv position,out float4 ocolor color 著色器是由hlsl 高...

Directx11教程37 紋理對映 7

本章是在教程35 36的基礎上來實現乙個光照紋理結合的程式,就是把場景中旋轉的cube加上紋理。lighttex.vs中頂點的結構現在為 struct vertexinputtype 紋理座標 output.tex input.tex 紋理座標不做任何變化,只是單純的從vs輸出到ps中。lightt...

WebGL關於著色器傳值的幾種方式總結

一 三個變數限定詞的概念 1 attribute 用途 傳輸那些和頂點資料有關的資料 例如,頂點位置 法向量 頂點顏色 每個頂點都對應乙個顏色 2 uniform 用途 傳輸那些對於所有頂點都相同 或者與頂點無關資料 例如 旋轉 平移 縮放的矩陣,每個頂點位置都要用到同樣的矩陣來獲取變換的位置,對於...