iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 15
0
Modern Web

重新學習網頁設計系列 第 15

DAY 15. Three.js 渲染器 Renderer

  • 分享至 

  • xImage
  •  

DAY 15. Three.js 渲染器 Renderer

Three.js 初探文中, 我在最後寫了這麼一段程式來渲染整個場景

// 定義渲染器
let renderer = window.WebGLRenderingContext ? 
               new THREE.WebGLRenderer() : new THREE.CanvasRenderer()

// ... 略

// 渲染
renderer.render(scene, camera)

首先要認識的是, 在three.js中渲染器Render, 我們有以下幾個選擇

  • WebGLRender
  • CanvasRenderer
  • SVGRenderer (舊)

在普遍的情況下我們優先考慮WebGLRenderer, 另外兩個Renderer通常是在環境不支援WebGLRenderer時的替代方案, 原因是相較於WebGLRenderer, 其他Renderer可能渲染品質較差, 或是功能較少(例如不支援複雜的材質與陰影)

##requestAnimationFrame
在很久以前, Javascript渲染動畫的方式通常是使用全域計數器window.setInterval搭配CSS屬性來實現

/** css */
#exampleDom {
  position: relative;
  width: 50px;
  height: 50px;
  background: green;
  display: inline-block;
}
/** JavaScript*/
let el = document.getElementById('exampleDom')
let w = el.clientWidth

let timer = window.setInterval(() => {
  w = w += 1
  if(w >= 100) clearInterval(timer)
  el.style.width = `${w}px`
}, 30)

這樣的方式雖然能夠實現動畫效果, 但實際上會遇到遺失間隔與間隔之間的幀, 進而降低了秒張率FPS, 更多詳細解說可以查看這篇詳細的介紹

因此, 現代瀏覽器為了更好的體驗, 一致的實作requestAnimationFrame, 而我們也將使用此方法來渲染我們的3D內容

// 將原本的渲染放入函式, 在由 requestAnimationFrame 執行

function render() {
  renderer.render(scene, camera)
}

function animationRender() {
  render()
  requestAnimationFrame(animationRender)
}

// 開始執行 animationRender
animationRender()

另外我們可以使用RenderersetClearColor方法來設定場景背景色

// 將背景色設定為白色
renderer.setClearColor(new THREE.Color('rgb(255, 255, 255)'))

接著我們可以與先前的範例做結合

// 1.建立場景 Scene
let scene = new THREE.Scene()

// 2.建立相機 Camera
let camera = new THREE.PerspectiveCamera(
  75, window.innerWidth / window.innerHeight, 0.1, 1000
)

camera.position.x = 3
camera.position.y = 3
camera.position.z = 3
camera.lookAt(new THREE.Vector3(0, 0, 0))

// 3.建立渲染器 Renderer
let renderer = window.WebGLRenderingContext ? 
               new THREE.WebGLRenderer() : new THREE.CanvasRenderer()

// 4.設定渲染器渲染範圍以及背景顏色
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setClearColor(new THREE.Color('rgb(255, 255, 255)'))

// 5.將渲染元素加入 body
document.body.appendChild(renderer.domElement)

// 6.建立矩形 Geometry
let geometry = new THREE.CubeGeometry(1, 1, 1)

// 7.建立材質 Material
let material = new THREE.MeshNormalMaterial()

// 8.使用以上矩形與材質, 將其實例化成一個方塊
let cube = new THREE.Mesh(geometry, material)

// 9.將方塊加入場景
scene.add(cube)

// 10.執行動畫渲染
animationRender()

// 定義渲染器函數
function render() {
  renderer.render(scene, camera)
}

// 定義動畫渲染器
function animationRender() {
  cube.rotation.x -= .01
  cube.rotation.y -= .01
  render()
  requestAnimationFrame(animationRender)
}

如果測試這段程式, 畫面中將會呈現一個不停旋轉rotate的方塊cube且背景為白色的3D場景。

方塊cube會旋轉是因為在函式animationRender中我給方塊cube調整了旋轉rotation屬性, 使我們方便觀察出目前的場景已經由requestAnimationFrame不斷的渲染, 驗證動畫渲染的效果。

以上就是渲染器Render的介紹, 以及requestAnimationFrame的why and how,在實際使用的情境中, 我們很少會調整animationRender函式, 因為它的職責僅止於不斷的在每一幀渲染畫面。


上一篇
DAY 14. Three.js 初探
下一篇
DAY 16. Three.js 相機 Camera
系列文
重新學習網頁設計30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言