3D Three.js初探 + 廣告業務的關聯思考

隨着5G大浪潮越演越烈,愈加越感受到VR、裸眼3D、全息投影等技術體驗離咱們普通人的生活愈來愈近。做爲廣告部門的一隻前端程序猿,也在思考Three.js在業務中能有什麼用。好在以前在大學作項目的時候接觸過OpenGL,渲染原理基本上都差很少,在初步學習完以後,列出一些本身的初步思考。這篇文章的前半部分會簡單介紹一下Three.js這個技術的基本原理,以及入門知識;然後半部分會聊一下本身認爲目前業務中的可能應用。感興趣的朋友們能夠留言,咱們一塊兒探索喲。


技術背景:
-什麼是Three.js
首先來聊一下什麼是Three.js。Three.js 是一款運行在瀏覽器中的 3D 引擎,你能夠用它建立各類三維場景,包括了攝影機、光影、材質等各類對象。簡單地來講,three.js的出現,使咱們這些小前端們能夠快速上手搭起3D程序,而非跟WebGL原生的API死磕到底。經過Three.js, 能夠建立三維圖形;在三維場景中生成動畫、移動物體;在物體上渲染紋理和材質;從三維建模軟件中加載圖形等。


-瀏覽器的支持性
由於Three.js實際上是一個基於WebGL的JavaScript的庫。因此只要是支持WebGL的瀏覽器,就能夠運行Three.js,以下圖所示(詳細信息請參閱 caniuse.com/#feat=webgl)。基本上,Three.js可在任何流行的瀏覽器上運行,除了IE的大部分版本,自IE11開始,微軟纔開始支持WebGL。



-Three.js的原理
Three.js主要有三大組件,場景(Scene), 相機(Camera)和渲染器(Render)。在場景裏咱們能夠定義各類物體和燈光,經過相機咱們能夠調整觀察者的視角;而渲染器是根據相機和場景的相對位置和關係,渲染出來在那種條件下,能夠看到的景象。這一過程,其實能夠比做拍電影,先佈置好場景,而後肯定好相機的位置,能夠看到的景象也就應運而生了。



-Three.js調用
若是想在項目中使用Three.js,加載庫的方式也很簡單。
能夠將three.js經過script tag加到HTML裏,也能夠直接經過NPM,直接以模塊方式在項目的javascript文件中調用。

<!-- index.html -->
<script src="path/to/three.js"></script>複製代碼

javascript

npm install three --save  // or use yarn add three.js alternatively
import * as THREE from 'three';複製代碼

若是想要把3D渲染的場景在HTML中展現,咱們就須要制定一個簡單的<div>元素,併爲其制定一個惟一的ID做爲鉤子。這個<div id="scene-container"/>被稱爲"divider element",它不會告訴瀏覽器會其內部會怎樣,或者會顯示什麼,只是起到將周圍其它元素與其內部隔開而已。scene-container這個ID,會被當作鉤子與相關的js代碼創建關聯,告訴js/app.js哪裏去放置渲染後的3D場景。
html

<body>
  <h1>廣告示例</h1>
  <div id="scene-container"> // This div will hold our scene
  </div>
  <script src="js/app.js"></script>
</body>function init() {
  container = document.querySelector('#scene-container'); // where to drawn  
  scene = new THREE.Scene();
  createCamera();
  createControls();
  createLights();
  createMeshes();
  createRenderer();
  renderer.setAnimationLoop(() => {
    update();
    render();
  });
}複製代碼

當app.js拿到鉤子的位置後,前端

container = document.querySelector('#scene-container')java

就會生成在其內部添加一個<canvas>元素。全部的three.js WebGL場景都會被畫到這個<canvas/>上。three.js會把控制權交給底層的WebGL,WebGL會調用顯卡(graphics card)來生成圖片或一些列圖片(若是有動畫效果的話),最後這些渲染結果會被在canvas上展現。
web



-Three.js基本組件

若是咱們想要生成下圖這個簡單的demo,應該怎麼來作呢?在上文中,咱們提到了Three.js主要有三大組件,場景(Scene), 相機(Camera)和渲染器(Render)。在這裏會以這個簡單的demo情形爲例子,講解一下從代碼細節上咱們怎麼可以實現這一渲染過程。基本要作的就是佈置好場景,建立物體,放好攝像機,開拍!npm




首先須要作的是建立一個場景,並給場景設置一個背景色。由於本人是個女孩子,就設置成我所偏心的紫色了。canvas

// create a Scene
scene = new THREE.Scene();
scene.background = new THREE.Color('#9370DB');複製代碼
有了場景以後,咱們就能夠往裏面增添物體啦!若是須要往場景裏添加物體,就調用
scene.add( object )複製代碼

反之,若是不想要某個物體了(作動畫效果時),就用瀏覽器

scene.remove( object )複製代碼

有了場景,就往裏面加物體了,其實物體能夠被理解爲咱們3D場景中的演員。3D計算機圖形中,物體一般是用Mesh來生成的。Mesh中又包括geometry,也就是須要聲明的物體的形狀;以及material,即物體的材質。經過下面的代碼,咱們製造出來一個長寬高分別爲2單位長度的正方體,給其附上了橙色的通常材質,並把它加入了場景中。bash

// create a geometry - here is a box
const geometry = new THREE.BoxBufferGeometry(2, 2, 2);
// create a orange Standard material
const material = new THREE.MeshStandardMaterial({ color: '#FF6347' });
// create a Mesh containing the geometry and material
mesh = new THREE.Mesh(geometry, material);
// add the mesh to the scene object
scene.add(mesh);複製代碼

在有了場景和演員以後,就要開始拍大片了。那麼,相機須要放在什麼位置,其視角又應該如何設定呢?相機配置的參數稍微有點複雜,咱們慢慢來看。app

首先須要明確的是,爲了在2D的瀏覽器上展現出人眼感受的3D圖像,咱們的相機就要模擬人眼的成像原理。這裏使用的是PerspectiveCamera,透視相機,基本成像原理用大白話來講,就是「近大遠小」。透視原理的相機,須要4個參數,來定義其能看到範圍(專業名稱叫viewing frustum)。這四個參數分別爲:fov, aspect, near, far。near是定義從相機多近的位置開始渲染場景,far是指相機能看到多遠,這兩個截面內的物體,才屬於相機的可視範圍。


fov是field of view的縮寫,定義了視場的角度。aspect是渲染輸出結果的橫向長度和縱向長度的比值。因爲這個例子會選用整個窗口做爲輸出界面,就用窗口的長寬比。這個長寬比決定了水平視場和垂直視場的比例關係。


// set up the options for a perspective camera
const fov = 35; // fov = Field Of View
const aspect = container.clientWidth / container.clientHeight;
const near = 0.1;
const far = 100;
camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
// every object is initially created at ( 0, 0, 0 )
// move the camera back a bit so that we can view the scene
camera.position.set(0, 0, 10);複製代碼

因爲在上面添加物體的時候,咱們並未聲明具體位置,因此物體就被放置在了默認的位置(0,0,0)。因此這裏,咱們須要把相機的位置稍微日後一點,這樣才能看到物體。


以後,咱們能夠再增長一個燈光,實現光照效果。燈光有不少效果能夠選擇,咱們這裏選用了最簡單的光照效果,DirectionalLight。該效果是模擬單一光源的,從某個位置向四處發射光線,例如太陽。

// Create a directional light
const light = new THREE.DirectionalLight(0xffffff, 3.0);
// move the light back and up a bit
light.position.set(10, 10, 10);
// remember to add the light to the scene
scene.add(light);複製代碼

在有了場景,物體,燈光後,就須要renderer來生成2D圖像了,並將其插入canvas元素內。當調用WebGLRenderer,會自動生成一個HTML <canvas/>。這裏須要用renderer.setSize()來定義canvas畫布的大小。在最初,這個canvas會被存在renderer.domElement裏。以後採用瀏覽器內置的方法appendChild,將其插入到上文提到的HTML的鉤子元素<div id="scene-container"/>中。

container = document.querySelector('#scene-container');
......
// create a WebGLRenderer and set its width and height
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(container.clientWidth, container.clientHeight);
renderer.setPixelRatio(window.devicePixelRatio);
// add the automatically created canvas element to the page
container.appendChild(renderer.domElement);複製代碼

以後要作的就是,告訴renderer咱們所創建的場景和相機,讓其渲染產生圖像。

renderer.render( scene, camera );複製代碼

代碼寫到這裏,咱們獲得了這樣的一個靜態2D圖像。


爲了達到3D動態效果,咱們須要讓物體或相機動起來。這裏,咱們用比較簡單的方法,讓正方體運動起來。在animate函數不停地調用本身,利用requestAnimationFrame來處理調用頻率。讓正方體在每次函數調用時,在X,Y,Z方向都旋轉一點點。而且每次都從新調用渲染函數,生成新的圖像。

這些連續變化的圖片連起來,就造成了咱們想要的動畫效果。

function animate() {
  // call animate recursively
  requestAnimationFrame(animate);
  // increase the mesh rotation each frame        
  mesh.rotation.z += 0.01;
  mesh.rotation.x += 0.01;
  mesh.rotation.y += 0.01;
  renderer.render(scene, camera);
}複製代碼



-Three.js廣告業務中的應用(我的瞎想...原創哦!!!)

在長篇介紹完Three.js以後,想必小夥伴們已經對它有了初步的瞭解。那麼如何把本身業餘時間的學習,與業務聯繫在一塊兒呢?在此,發揮腦洞的時刻到了。因爲本人是廣告部門的,因此就初步地瞎想了一些可能用到的場景,若是小夥伴們有更cool的想法,歡迎一塊兒討論。

下面是本身初步作的一些小demo,歡迎輕拍~~~

1. 3D banner 廣告 - 能夠把banner廣告立體化,用戶能夠從多角度來改變視角觀賞巨幅banner,就有種大街上廣告牌的感受。


2. 3D交互式廣告 - 能夠把廣告牌放置在一個3D空間裏,而後用戶探索式地去發現廣告

此處簡單地作了個例子,用戶駕駛着能夠飛的騎車,在浩瀚的太空中環遊,並瀏覽廣告


3. 3D動畫廣告 - 適合用在一些官網首頁,用於效果宣傳




4. 3D文字廣告 - 經過3D變化 加強觀看者對文字關鍵字的記憶



總的來講,我以爲Three.js在廣告業務中的應用能夠總結爲兩個方向(原創):

1)2D廣告的圖片直接依附於3D空間展現 - 由於2D空間是3D空間的一個子集,那麼目前比較流行的2D圖片廣告,其實能夠做爲3D空間的一個面,依附於3D空間裏。後續的開發基本就是增長各類物體與這個面的交互;

2)將廣告創意直接涉及到3D界面裏 - 讓3D場景中的物體表達出廣告的信息,例如後兩種廣告。更復雜的一點設想是,打造一個3D場景,例如城市街景,而後以遊戲探索的方式,把廣告加入進去。

以上就是我在業餘時間初步學習Three.js並基於業務的一些想法,由於也是剛剛利用業餘時間接觸這個技術捏,若是有不足的地方,歡迎指出!若是有感興趣的小夥伴,歡迎點贊留言我,咱們一塊兒探索!

相關文章
相關標籤/搜索