Unity3D學習筆記9——加載紋理

1. 概述

理論上,Unity中加載紋理並沒有什麼難度,只需要將圖片放置在Assets文件夾內,就會被識別成紋理,從而可以加載到場景中。但是一旦有一些額外的需求的時候,就得使用其他的方式進行紋理加載。

2. 詳論

2.1. Resources方式

使用Resources機制來加載Unity的各種資源,包括紋理:

Texture2D texture = Resources.Load<Texture2D>("ImageDemo");

Resources是Unity程序自帶的的資源管理。Resources這個機制特別適用於遊戲,對於遊戲來說,所有的紋理、材質、Shader等都可以作爲遊戲的內置資源。

2.2. API方式

考慮這個情況:如果我們要處理的數據來自資源之外,也就是存在操作系統的資源文件夾中。這種情況Resources就無法使用了。這種情況我們應該瞭解一下紋理的使用原理:紋理圖片首先是存在硬盤空間中,然後通過CPU讀取到內存,最後數據交換到GPU的顯存中。

一種方法是可以借鑑圖像處理的辦法,如GDAL、OpenCV等(甚至可以自己通過File實現)組件,將圖像讀取到內存中,組織成Unity腳本類Texture2d需要的buffer:

int width = 512;
int height = 512;
texture = new Texture2D(width, height, TextureFormat.RGB24, false);

byte[] imgData = new byte[width * height * 3];

for(int yi = 0; yi< 128; yi++)
{
    for(int xi = 0; xi < 128; xi++)
    {
        int m = width * 3 * yi + 3 * xi;
        imgData[m] = 135;
        imgData[m+1] = 206;
        imgData[m+2] = 235;
    }
}

texture.SetPixelData(imgData, 0, 0);
texture.Apply(false, false);

我將內存buffer前128*128個像素buffer填充成藍色,最終顯示爲:
imglink1

也就是紋理buffer也是按照左下角起點的。

Apply()這個函數不能少,因爲這個函數是將內存的紋理數據上傳到GPU的顯存中,而且比較耗費性能。最好在更改像素值完成之後,才調用一次Apply()上傳到GPU。

2.3. Web方式

除了本地,資源有時候也會被放置到遠端服務器上。對此Unity提供了WWW類作爲訪問的接口,但是已經廢棄。現在Unity提供UnityWebRequest類作爲與Web服務器進行通信的接口,與訪問遠端Texture相關的類還有UnityWebRequestTexture。簡單研究了這一套接口,似乎還提供異步方法。

不過實際使用中我並沒有使用這套接口。因爲我想把一部分工作放到多線程中。我們知道Unity與渲染或者資源相關的內容是不能放置到多線程的,但是訪問遠端數據、並且讀取到內存這部分內容是可以放置到多線程的。所以改進方式也很簡單:

  1. 使用C#的WebRequest接口(其他網絡傳輸接口也行),一般網絡傳輸的接口是可以放置在多線程中的。
  2. 將獲取到的文件流進行解析,獲取RGB格式的內存Buffer。這一步也可以放置在多線程中。
  3. 在主線程將內存Buffer塞入到Texture2D中。

代碼地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章