在3D遊戲中,我們經常能夠看到連綿起伏的山脈,當在夕陽西下一覽衆山之時,可曾想過這美景在3D世界中是如何呈現,前面講完了燈光和攝像機,本篇聊聊Silverlight3D遊戲的HeightMap,並從文件中取得高度圖信息形成下面的3D地形。
HeightMap是地形的輸入數據,可以理解爲位圖,一個2D矩陣,和位圖不同的是,把元素的顏色值映射爲高度值,現實中的地形是真實的,不是由三角平面模擬的,但是3D圖形圖像處理中常常使用三角形來代替地形的表面,每個三角形的頂點高度在山脈到山谷之間轉換,模擬自然地形。我們來看看HeightMap的原理:
使用HeightMap的原因是表示方便,存儲和修改容易,從數據的角度上,HeightMap一般是灰度圖,灰度圖的一個像素數據只需要0xFF一個字節就可以表示,如果變成三維座標,基本數據值類型就會變得大,不利於數據處理,同樣一些阻擋算法也可以通過HeightMap計算,這部分我相信專門研究3D算法的朋友有研究,在這裏就不做多講。形成HeightMap的算法也比較簡單,只是將頂點集合做好即可。
那麼在Balder 3D中如何實現HeightMap,在Balder.Objects.Geometries中提供了HeightMap類,可以通過簡單的設置就能到HeightMap
- Heightmap heightmap = new Heightmap();
- heightmap.Dimension = new Dimension() { Width = 120,Height = 120 };
- heightmap.LengthSegments = 16;
- heightmap.HeightSegments = 16;
- game.Children.Add(heightmap);
LengthSegments屬性是橫向面片數量
HeightSegments屬性是縱向面片數量
那麼橫縱相乘就是16*16 = 256面片,依據個人所需要的平滑度可以進行調整。
HeightmapArray屬性是高位數據,用Float類型表示,它達標了在Heightmap區域內的高位信息,這個數組可大可小,越大精度越高,越小精度越小,下面簡單生成一個數組看看實際的效果,代碼如下
- float[,] HeightmapArray = new float[5, 5]
- {
- {0,5,10,5,0},
- {0,10,20,10,0},
- {0,20,30,10,0},
- {0,10,20,20,0},
- {0,0,0,0,0}
- };
對照前面的實現原理,是否有意思了呢,這個數組的構建可以依據自己的需求做修改和開發,爲了滿足想進階的朋友,我下面寫了一個從位圖中創建HeightMap例子,以作參考。
- //從位圖中創建高度圖
- void CreateHeightMapFormBitmap(Uri uri)
- {
- BitmapImage bitmap = new BitmapImage();
- //從資源中取得BitmapStream
- StreamResourceInfo sri = Application.GetResourceStream(uri);
- bitmap.SetSource(sri.Stream);
- //生成WriteableBitmap
- WriteableBitmap writeablebitmap = new WriteableBitmap(bitmap);
- //創建高度圖數組
- float[,] HeightmapArray = new float[bitmap.PixelHeight,bitmap.PixelWidth];
- //將數組拷貝到高度圖數組
- for (int i = 0; i < bitmap.PixelHeight; i++)
- {
- for (int j = 0; j < bitmap.PixelWidth; j++)
- {
- int index = bitmap.PixelWidth * i + j;
- int pixel = writeablebitmap.Pixels[index];
- byte[] bytes = BitConverter.GetBytes(pixel);
- //計算:顏色越深則越低,顏色月淺則越高,50是最高的高度值
- HeightmapArray[i,j] = ((float)(bytes[0] + bytes[1] + bytes[2]) / 3) / 255 * 50 ;
- }
- }
- //賦值
- heightmap.HeightmapArray = HeightmapArray;
- }
在這裏使用了GetResourceStream資源讀取的方式,因此你需要將位圖引用到工程當中,下面是測試用高度位圖,工程中做了縮小修改,畢竟用不上這麼精細的位圖。
使用上述代碼實現即可,可以點擊直接下載工程瀏覽和測試,那麼運行的預覽效果如下:
工程中如果缺少Balder.dll請在這裏快速下載:SL4_Balder.rar
下一篇我們介紹材質的應用,如何對模型進行貼圖和更換貼圖,以及貼圖的屬性,同時可能還結合HeightMap依據地理信息製作真實地圖,那麼下次再見。