今天要講的也算是重構的一部分,但主要是渲染最佳化可以努力的方向~
我有限的小腦袋目前想到可以前進的方向有兩個:
總之就是使用者看不到的東西我們就沒有必要浪費資源去畫出來。
有點像是 windowing
的概念。
這邊第一個要解決的問題應該會是怎麼決定哪些東西在範圍內?
這個系列對相機視窗的形狀一直都有一個前提:它會是個矩形,所以我們這邊就不探討其他多邊形的視窗形狀。
怎麼判斷一個座標點是否在一個多邊形的範圍內有 2 個演算法。
如果要兩個都推導出來去解釋它背後的原理,這篇文章的篇幅可能會直接炸開。
我這邊是比較喜歡使用 Winding Number
,它的 JavaScript 跟 TypeScript 的實作可以直接去到這裡看。
但是其實大家可以直接套用 context
的 isPointInPath
。
詳細的 MDN 文件
if(isInViewPort){
//draw something
}
其實也有更好的辦法就是可能可以用 R tree 或是 Quadtree 再去最佳化,但是這兩種資料結構又是兩種不同的進路,但我就不在這裡示範了,就留給大家有更多東西可以在這個系列結束後去實作!
當使用者縮小到一個程度之後,有些東西會變得很難看見。
那些肉眼看不見的東西就可以變成一種簡化的圖樣去標示位置或是可以就直接不用畫了。
這個實作起來比較簡單,就是要作畫的時候需要參考相機的縮放倍率,然後判斷在這個縮放倍率下,我們要不要畫。
// 上略
const cameraZoomLevelThreshold = 0.5;
if(camera.zoomLevel > cameraZoomLevelThreshold){
// draw something
}
// 下略
這樣做的好處是每個不同的物件你都可以幫它定義一個縮放倍率的 threshold。
另外有時候你會不知道每個物件的 threshold 要怎麼訂,這時候就可以參考 Day 16 的內容,在不同的縮放倍率下這個東西在視窗中看起來會多大。
我們假設在視窗中看起來小於 1 我們決定就不用畫了。
那多少縮放倍率會讓物體寬度小於 1 呢? 我們就是用 1 / 物體寬度 = threshold zoomlevel ,去計算。
所以如果是一個 10 x 10 的正方形,在相機縮放倍率小於 0.1 的時候,我們就知道在視窗畫面看起來會小於 1 x 1 就不用畫了。
這邊題外話:我們也可以反過來操作,例如說我們需要讓一個東西的長寬在視窗中看起是多長,我們可以反過來推算需要的縮放倍率是多少。用剛剛的例子,就是如果我們要 10 x 10 的正方形在視窗中看起來像是 25 x 25 的正方形,我們需要的縮放倍率會是 25 / 10 = 2.5 。我們把相機的縮放倍率調整成 2.5 就可以讓這個正方形是看起來像 25 x 25 的樣子。
那今天就到這邊了!
今天是重構的最後一篇,所以其實重構內容好像也沒有很長只有兩篇 xD,希望大家可以從這兩篇得到一些方向。
沒有太多實作的細節是因為我知道重構跟最佳化的東西有時候是很主觀的,端看你想要解決什麼問題。
所以這系列的重構旨在提供一些方向而已,希望大家不會介意。
明天開始到系列結束都會是無限畫布可以怎麼應用的示範,應該是不會很水只貼一堆原始碼而已啦!應該...啦(小聲
明天是簡單的物理模擬打頭陣!
啊,對了!我接下來的應用會用到一些我自己額外寫的 library ,但是我都有放上 GitHub 也有發布到 npm,所以大家也可以跟著一起實作看看;然後後面的無限畫布我會使用我自己的 library board (“板班”)。這個系列幾乎實作了所有 board 的功能,所以其實大家可以自己選擇要拿現在的成果去應用還是要試試看我的 library 。(拜偷如果可以的話很歡迎大家試試看!
那我們明天見!