地形繪製基礎

2021-08-25 09:06:52 字數 3563 閱讀 6468

地形繪製基礎

高度圖其實就是乙個陣列,該陣列的每個元素都指定了地形方格中某乙個特定頂點的高度值。(另外一種實現方式可能用該陣列中的每個元素來指定每個三角形柵格的高度)。我們將高度圖視為乙個矩陣,這樣高度圖中的元素就與地形柵格中的頂點一一對應。

高度圖被儲存在磁碟中,我們通常為其每個元素只分配乙個位元組的儲存空間,這樣高度只能在區間 [0, 255]

內取值。高度圖有多種可能的圖形表示,其中一種是灰度圖。地形中某一點的海拔越高,相應地該地點在灰度圖中的亮度就越大。

1. 高度圖

1) 建立高度圖

但我們建立影象時,便指定了一副灰度圖。一旦完成高度圖的建立,我們需要將其儲存為 8

位的 raw

檔案。 raw

檔案僅連續儲存了影象中以位元組為單位的每個畫素的灰度值。這就使得這類檔案的讀取操作非常容易。

注意:高度資訊不一定非要用 raw

格式的檔案來儲存,可根據需要選擇任意一種格式。 raw

僅僅是我們所使用的影象格式中的一種。

2) 載入 raw

檔案 由於 raw

檔案本質上是乙個連續的位元組儲存塊,我們可用如下方法讀取該位元組塊。

std::vector_heightmap; bool terrain::readrawfile(std::string filename)

注意:我們將位元組型向量複製到乙個整型向量中。這樣,我們就可以對高度值進行比例變換從而突破 0~255

的限制。

該方法唯一的限制就是所要讀取的 raw

檔案中包含的位元組數至少要與地形中的頂點綜述一樣多。所以如果要從乙個 256 * 256

的 raw

檔案中讀取資料,相應地,只能建立乙個至少有 256 *256

個頂點的地形。

3) 訪問和修改高度圖

int terrain::getheightmapentry(int row, int col) void terrain::setheightmapentry(int row, int col, int value)

這些方法允許我們通過行和列索引引用高度圖中指定的項,這些方法隱藏了如何訪問由線性陣列表示的矩陣。 2.

建立地形幾何資訊

1) 頂點的計算

為了計算三角形柵格的各個頂點,我們只需要自頂點 start

起,逐行生成每個頂點,保持相鄰頂點的行列間隔為單元間距,直至到達頂點 end

為止。這樣就給出了 x

和 z座標的定義。

注意:本例程中開闢了乙個很大的頂點快取用來儲存整個地形中的所有頂點,由於硬體的限制,這樣就可能會有問題。例如, 3d

裝置都預設了最大圖元數和最大頂點索引值。可以通過檢查 d3dcaps9

結構的 maxprimitivecount

和 maxvertexindex

成員變數,來獲知圖形裝置為上述值所指定的上限。

為了計算紋理座標,下圖給出了乙個簡單的紋理影象,從中我們可以看出與地形中位於( i, j

)的頂點相對應的紋理座標( u, v

)可由下述公式計算得到:

2) 索引的計算

為計算三角形柵格各頂點的索引,我們只需自左上角起直至右下角,依次遍歷每個方格,並計算構成每個方格的三角形麵片的頂點索引。

計算的關鍵是推導出乙個用於求出構成第 i

行、第 j

列的方格的兩個麵片的頂點索引的通用公式。借助上圖,我們可自行推導出該公式,我們發現,對於處在( i, j

)位置的方格,有:

3. 紋理對映

紋理對映有兩種方式: ø

載入乙個已建立好的紋理檔案,然後再應用該紋理資料。 ø

另外一種是按順序逐個計算出紋理內容,即我們首先建立乙個「空」紋理,然後再基於一些已定義的引數計算出紋理元的顏色。在地形繪製中,該引數為地形的高度該方法首先用 d3dxcreatetexture

建立乙個空紋理,然後再將頂層紋理(因為有多層紋理)鎖定。至此,開始遍歷每個紋理元並對其上色。上色的依據是座標方格所對應的近似高度。思路是:地形中海拔較低的部分上色為沙灘色,中等海拔的部分上色為綠色的丘陵顏色,高海拔的部分上色為雪山的顏色。我們用座標方格中左上角頂點的高度值近似表示該方格的整體高度。

為每個紋理元上色後,我們還可以依據太陽光(用方向光模擬)到達紋理元對應的座標方格時的入射角來調整每個紋理元的明暗度。

4. 光照

1) 概述

我們在計算地形的明暗時用到的光照技術很基本,也很常用,即漫射光。光的方向向量應為單位向量。

接下來為地形中的每個座標方格就算光向量和該方格的面法向量之間的夾角。

由下圖可見,上述夾角越大,座標方格的朝向偏離光源就越大,其所接收到的光照就越少。反之,上述夾角越小,座標方格的朝向偏離光源就越小,其所接收到的光照就越多。而且,一旦光向量與面法線的夾角超過 90

度,方格表面便接收不到任何光照。

借助光向量和方格的面法向量之間的角度關係,我們可以構造乙個位於區間 [0, 1]

內的明暗因子,以表示方格表面所接收到的光照量。這樣,我們就可以用乙個接近於 0

的因子值來表示這兩個向量的夾角很大。當一種顏色與該因子相乘時,顏色值就趨近於 0

,從而呈現出較暗的視覺效果。反之,接近於 1

的因子值表示這兩個向量夾角很小,所以當一種顏色與該因子相乘時,該顏色基本保持了原來的亮度。 2)

座標方格的明暗度計算

為了計算光源方向的單位向量與方格的法向量之間的夾角,我們首先需要求出方格的法向量。通過計算向量的叉積就可以求出。但我們需要先找出與該方格共面的兩個非零的互不平行的向量。

3) 對地形進行著色

一旦我們了解了如何對乙個特定的座標方格進行著色(也稱明暗處理),我們就可以對地形中的所有方格著色了。我們只需要遍歷每個座標方格,計算其明暗因子,然後將該方格對應的紋理元的顏色於該因子相乘。 5.

在地形中「行走」

地形建立好之後,我們還想移動攝像機以模擬我們在場景中的行走過程。為了實現這一點,我們首先需要根據給定的 x

和 z座標找到我們所處的座標方格。

首先,我們進行平移變換,將頂點 start

平移至座標原點。然後通過縮放因子為單元間隔的負倒數的比例變換將座標方格的單元間隔歸一化。這樣,我們就轉換到了乙個新的參考係中,其中 z

軸方向向「下」。當然,程式**並沒有改變座標系框架本身,我們只是將 z

軸正方向理解為向下。下圖以圖形化的方式展示了該變換過程:

可以看出,經過變換的座標系與矩陣的順序儲存了一致。即左上角為原點,列索引和行索引分別沿著向右方向和向下方向遞增。這樣,由於目前單元間距為 1

,我們便可迅速求出當前我們所處的座標方格的行列索引。

既然我們已經知道了當前所處的座標方格,就可以求出構成該方格的 4

個頂點的高度。

此時,我們當前所處的方格位置以及構成該方格的 4

個頂點的高度均已知。現在我們來求攝像機位於任意的位置( x, z

)時,座標方格單元的高度。為了求取該高度,我們首先需要判斷攝像機當前位於哪個座標方格內。注意,記座標方格都是由兩個三角麵片的組合來繪製的。為了求出攝像機當前所處的三角形麵片,我們需要對當前所處的座標方格進行變換,使其左上角的頂點與座標原點重合。

OpenGL繪製地形

1.建立頂點緩衝區物件 vertexbuffer 2.建立索引緩衝區物件 indexbuffer 3.載入高度圖 heightmap 3.1把位影象素轉換為高度圖資料 頂點資料 高度圖在每個方向上都是1個單位寬,且其以x z平面上的位置 0,0 為中心,點陣圖的最上角將被對映到 0.5,0.5 右下...

學習OpenGL ES之繪製地形

地形模型一般是由nxn的網格構成,網格的點在y軸上的座標由灰度地形圖上相應的顏色決定。顏色越亮,高度越高。顏色每個通道的取值範圍可以是0 255,通過公式轉換,可以很容易的控制生成模型的高度。上篇文章中,我們使用三角帶生成圓柱體的中間部分。現在我們要用多個三角帶來生成地形。如何生成單個三角帶我就不贅...

實時繪製基於LOD的地形相關技術

lod levels of etails細節層次 是解決大規模地形實時渲染的一項關鍵技術。在地形中實現lod技術後大大加速了地形的渲染。其基本思想是 對地形生成具有不同層次 不同解析度 的多個版本,在繪製地形時依據視點來選擇合適的層次細節進行繪製。本文用基於四叉樹構建的地形來實現相關lod演算法,有...