第一人稱在3D 中的用法要參考第一人稱在射擊遊戲中的使用,第一人稱射擊遊戲(FPS)是以第一人稱視角為中心圍繞槍和其他武器為基礎的視頻遊戲類型;也就是說,玩家通過主角的眼睛來體驗動作。自從流派開始以來,先進的3D和偽3D圖形已經對硬體發展提出了挑戰,而多人遊戲已經不可或缺。
Doom的截圖,這個流派的突破遊戲之一,展示了第一人稱射擊遊戲的典型視角
現在博物館或公司也常使用到3D 動畫做宣傳片等等,3D動畫演繹最大的優勢,便是在於內容與形式上給人的真實感受。它比平面作品更直觀,比2D 動畫更真實,所以更能給觀賞者以置身於廣告環境當中的感受,大大增強廣告的說服力。 3D 技術的發展甚至挑戰受眾的分辨能力,使受眾的判斷遊離於與虛擬和現實之間。
而且3D特效的應用為創意提供了更加廣闊的思維空間,並成為創意執行的可靠保證,並豐富了創意的形式和風格手段。根據廣告主題的表現訴求,可以營造出夢幻般的神奇氛圍來刺激打動受眾,從而起到與受眾溝通的目的。
3D動畫宣傳片將3D動畫、特效鏡頭、企業影片、照片、未來前景等內容透過後期合成、配音、解說形成一部直觀、生動、喜聞樂見的高品味的企業廣告宣傳片,讓社會不同層面的人士對企業產生正面的、正面的、良好的印象,從而建立對企業的好感與信任,並信賴該企業的產品或服務。
現在3D 發展地如此迅速也要感謝人類對於現實的追求,所以學好用好3D 是未來成功必不可少的一部分。
本文例子的想法是進入一個機房參觀,打開門的動作是再生動不過了, 再加上適當地轉彎,基本上完全模擬了人在機房中參觀的效果。還有一個好處就是,如果要示範給領導者看而又不用操作,這種酷炫的效果領導一定會很滿意!
http://www.hightopo.com/demo/room-walkthrough/index.html
介面上的reset和start兩個按鈕是直接加在body 本體中的button,並在這兩個按鈕上加入點擊事件:
<div></div><div></div>
整個場景由HT 封裝的3D 元件搭建形成的,建構這麼大的場景是需要一定量的程式碼的,為了簡化,我把場景單獨拿出來,並用HT 封裝的ht.JSONSerializer 類別將場景序列化為json,程式碼中只引入了生成後的json 文件,為了讓大家更明確,我這邊做個範例,假設已經搭建好3D 場景了:
dm = new ht.DataModel();g3d = new ht.graph3d.Graph3dView(dm);//.......建構好場景dm.serialize();//可以填入number參數,當空格縮進值
既然我們已經搭建好環境,轉成了json 文件,程式碼中不好控制,這種情況下我們會將DataModel 資料模型再反序列化,這個函數的功能就是將json 格式轉成對象,並將反序列化的物件傳入到DataModel 資料模型中,詳情請參考HT for Web 序列化手冊:
var g3d = window.g3d = new ht.graph3d.Graph3dView(), dataModel = g3d.dm(), view = g3d.getView(), path = null;g3d.setMovableFunc(function(data) { return false;}) ;g3d.setVisibleFunc(function(data) { if (data.getName() === path) { return false; } return true;});g3d.setEye([523, 5600, 8165]);g3d.setFar(60000);dataModel.deserialize(json);我們目前需要操作場景中的門、以及我們將要走的路線path,遍歷DataModel 資料模型,取得這兩個資料:
for (var i = 0; i < dataModel.size(); i++) { var data = dataModel.getDatas().get(i); if (data.getName() === 閘) {//json中設定的名稱window.door = data; } if (data.getName() === path) { path = data; } if (window.door && path) {//取得到door和path 的data之後就跳出循環break; }}這個例子簡單來說就只有四個動作,重置回到原點、開始動作、向前移動,停止。點選開始按鈕,在開始動作中我們只做了一個動作,開門動作,動作結束之後呼叫forward函數向前移動:
function startAnim() { if (window.isAnimationRunning) { return; } reset(); window.isAnimationRunning = true;//動畫是否正在進行ht.Default.startAnim({ frames: 30, // 動畫幀數,預設採用`ht.Default.animFrames`。動畫幀間隔,預設採用`ht.Default.animInterval`。動畫過程中的屬性變化。這邊的reset函數就是重置回到原點的功能,我們透過這個函數將所有變化過的都恢復到初始的位置,包括閘的位置:
function reset() { if (window.isAnimationRunning) { return; } g3d.setCenter([0,0,0]); g3d.setEye([523, 5600, 8165]); window.forwardIndex = 0tation; (0);}要移動,肯定需要走路的路徑,也就是我們剛剛取得到的path,透過window.points = path.getPoints()._as; 取得path中的所有元素,初始化window.forwardIndex = 0; 透過控制path中前後兩點來設定3D 場景中的Eye 和Center,這樣就能營造一個我們是第一個人的效果:
var point1 = points[forwardIndex], point2 = points[forwardIndex + 1];var distanceX = (point2.x - point1.x), distanceY = (point2.y - point1.y), distance = Math.sqrt(distanceX * distanceX + distanceY * distanceY)-200;//兩點之間的距離透過三角形勾股定理計算怕碰牆所以-200g3d.setEye([point1.x, 1600, point1.y]);//眼睛g3d.setCenter([point2 .x, 1600, point2.y]);//我
HT 中3D 組件有一個walk(step, anim, firstPersonMode)方法,該函數同時改變eye和center的位置,也就是eye和center在兩點建立的向量方向上同時移動相同的偏移量。 step為偏移的向量長度值。 firstPersonMode參數為空時則預設採用Graph3dView#isFirstPersonMode()目前值, 如果為第一人稱模式呼叫walk操作,函數會考慮Graph3dView#getBoundaries()邊界限制。
g3d.walk(distance, { frames: 50, interval: 30, easing: function(t) {return t; }, finishFunc: function() { forwardIndex += 1; if (points.length - 2 > forwardIndex) {/ /points.length = 5 g3d.setCenter([point2.x, 1600, point2.y]);//把結束點變成起始點g3d.rotate(Math.PI / 2, 0, { frames: 30, interval: 30, easing: function(t) {return t;}, finishFunc: function() { forward();} }); } else { var lastPoint = points[points.length - 1];//json 中path的points 的最後一個點g3d.setCenter([lastPoint.x, 1400, lastPoint.y]); g3d.rotate(-Math.PI / 2, 0, { frames: 30, interval : 30, finishFunc: function() { window.isAnimationRunning = false; } }); } }});不管path的點有多少個,這個判斷語句還是能運作,只在最後一個點是跳出finishFunc 動畫結束後調用的函數,並將window.isAnimationRunning 值設為false 停止startAnim 函數。如果不是最後一點,使用者旋轉之後,回呼forward 函數。至此,全部程式碼解釋完畢,很短的程式碼量,卻做了這麼大的工程!
總結以上所述是小編給大家介紹的基於HTML5的WebGL經典3D虛擬機房漫遊動畫,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回覆大家的。在此也非常感謝大家對VeVb武林網站的支持!