1. 程式人生 > >3D繪圖過程及原理簡介

3D繪圖過程及原理簡介

Standard Primitives(標準幾何體)
 在建立命令面板的Geometry(幾何體)物件型別中有如下幾個次級分類專案:

· Standard Primitives(標準幾何體):相對簡單的幾何體,如立方體、球體和錐體等。 · Extended Primitives(擴充套件幾何體):相對複雜的幾何體,如倒角柱體和紡錘體等。 · Compound Objects(合成物體):通過合成方式產生物體,如連線、變形和離散等。 · Particle Systems(粒子系統):產生微粒屬性的物體,如雨、雪、噴泉和火花等。 · Patch Grids(網格面片):以面片方式建立網格模型,是一種獨特的區域性造型方法。 · NURBS Surfaces(NURBS曲面):用於建立複雜光滑的曲面,是一種全新的造型方法。 · AEC Extended(AEC擴充套件):用於建築、工程以及土地構建方面物件的建立。如樹木、欄杆和牆壁等。 · Dynamics Objects(動力學物件):用於建立具有動力學屬性的物體。 · Stairs(樓梯):用於樓梯物件的建立,有4種可選擇的樓梯型別。 · Doors(房門):使用者房門的建立。有3種類型可供選擇。 · Windows(窗戶):建立窗戶物件,有6種窗戶型別。 在3ds max 6中,提供了10種標準幾何體,分別為Box(立方體)、Sphere(球體)、Cylinder(柱體)、Torus(圓環)、Teapot(茶壺)、Cone(錐體)、GeoSphere(幾何球體)、Tube(管狀體)、Pyramid(四稜錐)和Plane(平面),如下圖所示。  頂點(vertexs) 圖元(
primitives) 片元(fragments,又叫片斷) 畫素(pixels)

階段1. ?頂點 ->圖元

    幾何頂點被組合為圖元(點,線段或多邊形),然後圖元被合成片元,最後片元被轉換為幀快取中的象素資料。

階段2.? 圖元? ->片元

    圖元被分幾步轉換為片元:圖元被適當的裁剪,顏色和紋理資料也相應作出必要的調整,相關的座標被轉換為視窗座標。最後,光柵化將裁剪好的圖元轉換為片元。

1裁剪

    在裁剪時點,線段和多邊形處理略微不同。對於點,要麼保留原始狀態(在裁剪體內部),要麼被裁掉(在裁剪體外部)。對於線段和多邊形來說,如果部分在裁剪體外部,則需要在裁剪點生成新的幾何頂點。對於多邊形,還需要在新增的頂點間增加完整的邊。不論裁剪了線段還是多邊形,都需要給新增幾何點賦予邊界標誌、法線、顏色和紋理座標資訊。

裁剪過程時兩步:

   a 應用程式指定裁剪(Application-specific clipping),一旦組合圖元完成後,如果在程式中用glClipPlane()函式定義了任意的裁剪面,就進行裁剪。

   b 視景體裁剪(View volume clipping),隨後,圖元被投影矩陣投影(進入裁剪座標系),被相應的視景體裁剪。投影矩陣可以由glFrustum() 或者glOrtho()定義,投影矩陣的操作和上面其他矩陣變換的操作相同。

2轉換到視窗座標

    座標在轉換為視窗座標之前,要除以規格化裝置座標(normalized device coordinates)的w值進行規範化。然後對這些規範化資料進行視口變換(

viewport)計算生成視窗座標。可以用glDepthRange()glViewport()控制視口大小,決定螢幕上顯示圖象的區域。

3) 光柵化

    光柵化是將一個圖元轉變為一個二維圖象(其實只是佈滿平面,沒有真正的替換幀快取區)的過程。二維圖象上每個點都包含了顏色、深度和紋理資料。將該點和相關資訊叫做一個片元(fragment。(yuyu注:這就是片元和畫素之間的關鍵區別,雖然兩者的直觀印象都是的畫素,但是片元比畫素多了許多資訊,在光柵化中紋理對映之後圖元資訊轉化為了畫素)在這個階段,物件素繪製和點陣圖進行操作需要用到當前柵格位置(用glRasterPos*()定義)。正如上面討論的,三種圖元的光柵化方法是不同的,另外,象素塊和點陣圖也需要光柵化。

   a)圖元

    採用glPointSize(), glLineWidth(), glLineStipple() glPolygonStipple()函式可以選擇圖元的光柵化維數和模式。另外,還可以用glCullFace(), glFrontFace()glPolygonMode()控制多邊形正反面不同的光柵化效果。

   b)象素

    有幾個函式實現象素儲存和轉換。函式glPixelStore*()用於記憶體中的象素是如何儲存的。glPixelTransfer*() and glPixelMap*()用於象素在寫入幀緩衝區前是如何處理的。glDrawPixels()定義了一個象素矩形。用glPixelZoom()實現象素的縮放。

   c)點陣圖

    點陣圖是具有特定片元模式的01的矩形。每個片元有相同的相關資料。可以用glBitmap()定義。

   d)紋理儲存

    紋理貼圖是將指定的部分紋理圖象對映到每個圖元上。每個片元(fragment)具有的紋理座標屬性,該座標與紋理圖象座標對應,得到紋理圖象該位置的顏色值來修改片元的RGBA顏色,從而完成這個對映過程。用glTexImage2D()glTexImage1D()來定義紋理圖象。glTexParameter*()glTexEnv*()來控制紋理如何解釋和應用到一個片元上。

   e)

    已經光柵化的片元具有紋理貼圖修正後顏色,可以採用融合因子再融合霧顏色,該融合因子大小根據視點和片元間的距離來定。用glFog*()指定霧化顏色和融合因子。

階段3.? 片元->畫素?

    OpenGL允許光柵化生成一個片元,只要該片元通過一系列檢測就可以修改幀緩衝區中對應象素。如果它通過測試,片元資料可以直接替換幀緩衝區中的已有值,或者和已有值合併,這取決於設定的模式。

    1)象素所有權(ownership)檢測

    第一個測試是判斷在幀緩衝區中的象素所對應的某個片元是否屬於當前OpenGL上下文。如果屬於,片元進行下一個測試。如果不屬於,視窗系統決定是否忽略該片元,或者是否進行下一步片元操作。

    2)裁剪檢測

    用glScissor()函式,可以定義一個任意螢幕校準矩形,在該矩形外的片元將被忽略。

    3Alpha檢測

    Alpha測試只能在RGBA模式下進行,如果片元的alpha值超出一個固定參照值,片元將被忽略,這個比較函式可以用glAlphaFunc()實現並設定參考值。

    4)模版檢測

    當模版緩衝區的值超出一個參照值,模版測試將有條件的忽略該片元。這個比較函式和固定值可以用glStencilFunc()實現。不論圖元通過或沒有通過模版測試,模版緩衝區中的值會根據glStencilOp()函式進行修改。

    5)深度檢測

    當深度緩衝區的值與參照值的比較失敗,深度測試忽略該片元。GlDepthFuc()用來執行這個比較命令。如果模版啟用,深度比較的結果會影響模版緩衝區值的更新。

    6)融合

    融合合併了一個片元RGBA值和儲存在幀緩衝區對應位置的這些值。融合只能在RGBA模式下實現,它的實現需要片元的alpha值和對應當前儲存象素,還需要RGB值。用glBendFun()控制,可以修改融合因子的源和目標。

    7)抖動

    如果啟動抖動,片元的顏色或者顏色索引採用抖動演算法。這個演算法只需要片元的顏色值和它的xy座標。

    8)邏輯操作

    最後,在片元和幀緩衝區對應值之間要進行一個邏輯操作,結果將替換當前幀緩衝區的值。用glLogicOp定義想要的邏輯操作。這個邏輯操作只能在顏色索引模式下執行,而不能在RGBA模式執行。

象素

OpenGL流水線的上個階段,片元轉換為幀緩衝區中的象素。幀緩衝區實際上是一組邏輯緩衝區——包括顏色緩衝區、深度緩衝區、模版緩衝區和累積緩衝區。顏色緩衝區包括左、前右、後左、後右和一些輔助快取值(auxiliary buffers)。可以直接從中讀取或者複製。對於OpenGL不同上下文,這些緩衝區可能不全

    1)幀緩衝區操作

    用glDrawBuffer為繪圖選擇一個顏色緩衝區。另外在預片元化(per-fragment)操作後,可以用四個不同函式保留寫入這些邏輯緩衝區的操作,glIndexMask(), glColorMask(), glDepthMask(), and glStencilMask()glAccum()對累積緩衝區進行操作。最後glClearColor(), glClearIndex(), glClearDepth(), glClearStencil()glClearAccum().對不同緩衝區中指定相對應的顏色值、顏色索引值、深度值、模板值和累積值。

    2)讀取和複製象素

    用glReadPixel()從幀緩衝區中把象素讀到記憶體中,進行各種操作,儲存處理結果。另外,可以用glCopyPixel()從幀緩衝區中複製一塊象素到另一個幀混存。glReadBuffer()可以讀取和複製顏色緩衝區中的象素。