Silverlight C# 遊戲開發:L7 HeightMap

來源:互聯網
上載者:User

在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);

 

Dimension屬性是表示的大小;

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}
    };

 

這是一個[5,5]的float數組,對其進行了簡單的資料填充,將這個數組賦值給HeightmapArray屬性,就可以得到下面的這個運行效果:

對照前面的實現原理,是否有意思了呢,這個數組的構建可以依據自己的需求做修改和開發,為了滿足想進階的朋友,我下面寫了一個從位元影像中建立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;
}

 

我使用了一個比較暴力的像素點取值演算法,將R、G、B三值進行平均,就能得到一個近似的灰階數值,然後除以255,乘以50換算成以50為最高的高度數組,當然了,這裡你可以依據要求從50修改成任何數字。關於圖形映像的演算法,及實現原理請參考Silverlight C# 遊戲開發:資源的處理,映像演算法(二)

在這裡使用了GetResourceStream資源讀取的方式,因此你需要將位元影像引用到工程當中,下面是測試用高度位元影像,工程中做了縮小修改,畢竟用不上這麼精細的位元影像。

使用上述代碼實現即可,可以點擊直接下載工程瀏覽和測試,那麼啟動並執行預覽效果如下:


工程中如果缺少Balder.dll請在這裡快速下載:SL4_Balder.rar

下一篇我們介紹材質的應用,如何對模型進行貼圖和更換貼圖,以及貼圖的屬性,同時可能還結合HeightMap依據地理資訊製作真實地圖,那麼下次再見。

推薦Silverlight遊戲開發部落格:深藍色右手

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.