1.使用requestAnimationFrame()來驅動動畫編程
從前,Web應用使用定時器(timer)來控制頁面內容動畫,經過setTimeout()或setInterval()這兩個函數。隨着Web瀏覽器
應用開始包含更復雜的動畫和交互,這種方式明顯遭遇到一些關鍵問題。函數
1).定時器也設置好的恆定間隔來調用函數,不管是不是繪製圖形的最佳時機。oop
2).在定時器回調中執行的Javascript代碼沒法與其餘瀏覽器計算產生的動畫時間軸同步。優化
3).不管頁面或者標籤是否可見,或瀏覽器窗口是否被最小化,定時器都會被重複執行,這會形成潛在的繪圖資源浪費。動畫
4).Javascript應用代碼不知道顯示器的刷新率,因此只能主觀地設定定時器間值。例如將其設置爲1/24秒,那麼使用60Hz刷新率的用戶將沒法感覺到流暢的視覺效果。spa
requestAnimationFrame()函數被設計用來解決以上問題。使用它的好處。設計
第一,瀏覽器能夠按照所需進行頻繁或不頻繁的調用。當瀏覽器還有足夠的空閒時間時,它能夠試着提升幀頻來遇上顯示器的刷新率。相反,若是頁面或頁籤隱藏了,或整個瀏覽器最小化了,它能夠減小回調函數執行次數,優化電腦或設備的資源使用。第二,瀏覽器能夠批量處理用戶繪圖操做,從而減小繪製屏幕的次數,節省資源。第三,在requestAnimationFrame()中執行的全部繪製代碼最終會與其餘繪圖操做進行合併。最終產生更平滑、更快速、更高效的頁面繪製以及動畫。code
2.建立3D動畫的幾種方式blog
1).使用程序更新屬性的方式來構建動畫。
2).使用補間來進行動畫過分。
3).使用關鍵幀來實現複雜動畫。
4).使用曲線和路徑建立平滑天然的運動。
5).使用變形目標來建立人物和麪部動畫。
6).使用蒙皮來構建角色動畫。
7).使用着色器來進行動畫。
3.使用程序更新屬性的方式構建動畫
在WebGL場景中啓動一個動畫最簡單的方式是編寫代碼,在運行循環每次執行的時候更新某個物體的屬性值。這個概念能夠延伸到給場景中的任意東西添加動畫:位置、旋轉、縮放、材質顏色、透明度,等等。經過使用Javascript代碼來更新熟悉,咱們能夠進行任意的計算更新。數學公式、布爾邏輯、統計值、數據流、實時傳感器輸入等均可以用來驅動動畫。
4.使用補間來進行動畫過分
補間指的是計算一對值中間插入的其餘數值的過程。有了補間,動畫繪製者值需提供動畫的起始值和結束值,用於動畫時間過程當中的中間值(補間)有引擎自動計算生成。補間是實現由一個狀態切換到另外一個狀態的一次性簡單動畫的完美選擇,如點擊鼠標移動一個物體。
補間經過一項被稱爲插值(interpolation)的數學技術來實現。插值指的是基於一個標量輸入(如時間或者分數值)來計算兩個值之間的一個值。
自動實現簡單的補間是很是容易的事。儘管如此,當你須要非線性的插值函數,或者其餘像淡入/淡出這類花哨的效果時,問題就變得複雜了。你須要一個現成的庫,而非構建本身的補間體系。Tween.js是一個流行的開源補間通用庫。它被用於許多流行的WebGL工程中。
5.使用關鍵幀來實現複雜動畫
補間很是適用於來建立簡單的過分效果。更復雜的動畫經過使用關鍵幀,將補間的概念上升了一個層次。關鍵幀動畫包括一系列的值,以及可能各部相同的值與值之間的間隔時間,而非指定一對單值來進行補間。關鍵幀數據由兩部分組成:一個時間(鍵)列表和一個值列表。值列表表示在相應鍵的時間點會被使用的屬性值; 動畫系統基於一對鍵之間的間隔事件值計算補間。
儘管補間和關鍵幀動畫都採用插值,但它們之間存在兩個主要的不一樣點:關鍵幀動畫能夠包含兩個以上的值,不一樣關鍵幀之間的時間間隔能夠不一樣。這使得更強大的效果得以實現。下面是一個關鍵幀配置示例:
lightAnimator = new KF.KeyFrameAnimator; lightAnimator.init({ interps: [ { keys:[0, .4, .6, .7, .8, 1], values:[ { r: 1, g : 1, b: 1 }, { r: 1, g : 1, b: 1 }, { r: .333, g : .333, b: .333 }, { r: 1, g : 1, b: 1 }, { r: .667, g : .667, b: .667 }, { r: 1, g : 1, b: 1 }, ], target:directionalLight.color }, ], loop: loopAnimation, duration:duration * 1000, }); lightAnimator.start();
6.使用曲線和路徑建立平滑天然的運動
關鍵幀數據不侷限於用來描述線性動畫。它也能夠被看做曲線上的一些點。動畫中最經常使用的曲線是樣條曲線(spline-curve)---一種光滑連續的曲線。被稱爲B樣條曲線的某類樣條曲線被普遍應用於計算機圖形中,由於他們能夠相對快速地被計算出來。
7.使用變形目標來建立人物和麪部動畫
關鍵幀和關節動畫很是適用於在場景中移動物體,但許多動畫還須要該案物體自己的集合形狀。用於實現這類效果的最經常使用方法是變形目標動畫(morph target animation),簡稱變形。變形使用基於頂點的插值來改變網格的頂點。一般,網格頂點的一個子集以及US噢因一塊兒,被當作即將用於在補間中的變形目標(morph target)存儲起來。變形目標各頂點值之間的插值,以及使用了這些插值的動畫,組成了網格頂點的變形。
變形不只僅能夠用於表現面部。Three.js工程目錄中的一些示例使用變形來構建整個角色的動畫。MD2格式是一個流行的基於變形的格式,它被用於遊戲中的玩家角色動畫。
8.使用蒙皮來構建角色動畫
關節動畫在表現無生命物體時很是出色,想機器人、汽車、機器,等等。但在表現郵寄運動的時候則並不理想。微風中搖曳的植物,蹦蹦跳跳的動物,以及跳舞的人們,全部這些都涉及網格的幾何形狀變化:肢體的流動,皮膚的延展。你幾乎不可能用關節動畫的模式來很好地模擬這些事務。所以咱們轉向另外一項被稱爲蒙皮動畫(skinned animation, skinning)的技術,這項技術有被稱爲骨骼動畫(skeletal animation),或但網格動畫(single mesh animation)。
蒙皮動畫涉及對網格(或者說,蒙皮)上的的當前頂點進行實時變換。動畫由一個唄稱爲骨骼的關節物體成績結構來驅動。骨骼僅僅被用做動畫的皮下機制,咱們不會再屏幕上看到它。
骨骼中的每根骨頭都和網格上的一個頂點集合以及每一個相關頂點的融合權重(blend weight,又稱頂點權重,vertex weight)相關聯。
9.使用着色器來進行動畫
關鍵幀、補間和蒙皮,都是能夠用Javascript來實現的,不過你也可使用GLSL可編程着色器來實現硬件加速的版本。Three.js中的動畫同時使用兩種策略:純Javascript的關鍵幀系統,以及做爲Three.js內置材質(如Phong 和 Lambert)的着色器代碼的一部分而實現的變形和蒙皮。