three.js 解決遠距離貼圖模糊 Texture blurer

在使用Three.js 開發網頁3D遊戲的過程中發現,部分材質貼圖在遠距離的時候會產生模糊(如下圖),在此寫個解決文章留作紀念,也供其他開發者參考。

遠距離貼圖模糊
遠距離貼圖模糊

 

方法1:Minification Filters

在Three.js 中,我們可以對Texture 物件修改兩項Texture Constants,例如:

var ObjectTexture = new THREE.TextureLoader(LoadingManager).load("textures/Billboard.png");
ObjectTexture.minFilter = THREE.NearestFilter;
ObjectTexture.magFilter = THREE.LinearFilter;

其中minFilter (Minification Filters) 指的是當貼圖3D顯示小於實際貼圖大小時(物件較遠或物件較小),所套用的縮圖方式;magFilter (Magnification Filters) 指的是當貼圖3D顯示大於實際貼圖大小時(物件非常近或物件很大) 所套用的放大方式。

magFilter 共有兩種參數:

  • THREE.LinearFilter
    預設值,以最近的四個座標點做加權平均,如果有設定wrapS、wrapT,也會從其他重複的部分做精確的取樣
  • THREE.NearestFilter
    以最靠近的座標點取樣

minFilter 比較多選擇,共有以下六種參數:

  • THREE.NearestFilter
    以最靠近的座標點取樣
  • THREE.NearestMipMapNearestFilter
    採用最接近顯示大小的一個mipmap,以mipmap 最靠近的座標點取樣 (等同於做NearestFilter)
  • THREE.NearestMipMapLinearFilter
    採用最接近顯示大小的兩個mipmap,兩個mipmap 各別最靠近的座標點取樣 (等同於各別做NearestFilter),最後這兩個值再加權平均
  • THREE.LinearFilter
    以最近的四個座標點做加權平均,如果有設定wrapS、wrapT,也會從其他重複的部分做精確的取樣
  • THREE.LinearMipMapNearestFilter
    採用最接近顯示大小的一個mipmap,以mipmap 最近的四個座標點做加權平均 (等同於做LinearFilter)
  • THREE.LinearMipMapLinearFilter
    預設值,採用最接近顯示大小的兩個mipmap,兩個mipmap 各別最近的四個座標點做加權平均(等同於各別做LinearFilter),最後再將兩個值再加權平均

 

NearestFilter
NearestFilter
NearestMipMapNearestFilter
NearestMipMapNearestFilter
NearestMipMapLinearFilter
NearestMipMapLinearFilter
LinearFilter
LinearFilter
LinearMipMapNearestFilter
LinearMipMapNearestFilter
LinearMipMapLinearFilter
LinearMipMapLinearFilter

 

由上方圖片所示,NearestFilter 會產生鋸齒;NearestMipMapNearestFilter 、NearestMipMapLinearFilter 以及LinearMipMapNearestFilter 雖然消除鋸齒但是貼圖破碎無法辨識文字。

由此得知只要經過NearestFilter 的取樣都會產生模糊甚至貼圖破碎,其中以LinearFilter 最清晰,但是會產生輕微鋸齒,若在Renderer 開啟抗鋸齒(antialias) 的環境中可能會看起來有些突兀。

 

方法2:Renderer Anisotropy

我們可以設定貼圖的mipmap 採樣數來解決模糊問題。

var Renderer = new THREE.WebGLRenderer();
var maxAnisotropy = Renderer.capabilities.getMaxAnisotropy();
ObjectTexture.anisotropy = maxAnisotropy;

先透過getMaxAnisotropy() 函數取得GPU所支援的採樣最大值(這個值為2的升幕),並修改貼圖的anisotropy 參數(預設為1),這個動作會影響貼圖在3D顯示時,不同距離所採用的mipmap 數量,並會影響效能。

maxAnisotropy
maxAnisotropy

 

最後結果

 

全部結果
全部結果

參考資料

  • https://threejs.org/docs/#api/en/constants/Textures
  • https://threejs.org/examples/webgl_materials_texture_anisotropy.html
  • https://threejs.org/examples/webgl_materials_texture_filters.html

發表迴響