個人世界:一個村落(其一)

本文github地址javascript

本文是一篇three.js的入門文章,將介紹three.js的一些基本概念,並一步步搭建一個簡單的場景模型:html

village

在線預覽:
一個村莊java

場景元素

概念

用three.js構建場景,有三個不可或缺的場景元素:git

  • scene:能夠把它想象成一個容器,用來放置你場景中的全部元素(光源,物體)github

  • camera:即相機被相機拍攝到的物體才能最終被呈現出來瀏覽器

  • renderer:三維的物體最終要呈如今二維的畫布中,須要經過render來實現app

其中透視相機由四個必要參數控制:dom

透視相機

  • fov:決定了從相機位置能夠看到的場景大小oop

  • aspect:呈現場景水平尺寸與垂直尺寸的比值,對於須要全屏顯示場景該參數是window.innerWidth/window.innerHeight性能

  • near:物體呈現最小距離,小於該距離將再也不呈現

  • far:物體呈現的最大距離,超過該距離物體將再也不呈現

代碼實現

// 配置參數
var HEIGHT = window.innerHeight
var WIDTH = window.innerWidth
var aspect = WIDTH / HEIGHT
var fov = 35
var near = .1
var far = 1500

// 建立 scene
var scene = new THREE.Scene()

// 建立 camera
var camera = new THREE.PerspectiveCamera(fov,aspect,near,far)

// 設置相機位置
camera.position.set(0, 0, 20)

// 建立 renderer
renderer = new THREE.WebGLRenderer({

    // 透明
        alpha: true, 

    // 注意抗鋸齒會影響性能,請酌情使用
        antialias: true 
    })

// 定義了最終呈現的尺寸
renderer.setSize(WIDTH, HEIGHT)
// 須要分清該尺寸與相機中的aspect的區別
// 前者就比如一部電影能夠在電腦上看也能夠在手機上看(這裏的尺寸是最終呈現的尺寸)
// 後者比如一部電影我用綠幕拍和實景拍均可以(這裏的尺寸指物理空間的大小)
    
// 添加到DOM中
document.body.appendChild(renderer.domElement)

預覽

這時候打開瀏覽器就是一片白什麼也沒有,
由於scene裏面什麼都沒有

設置光源

光源是場景中重要的組成部分,一樣的場景使用不一樣的光源能夠達到迥然不一樣的效果
daytime
night

概念

  • AmbientLight:環境光可在場景中添加無差異的光,對整個場景與對象都有效

  • PointLight:點光源由一點散射出來的光

  • SpotLight:聚光燈由一點發出的光錐效果的光(自行腦補聚光燈吧)

  • DirectionalLight:一組平行光,一般被用來模擬太陽光

以上四種是比較經常使用的光

代碼實現

// 環境光
var ambientLight = new THREE.AmbientLight(0xffe8d8, 0.6)
// 主光
var mainLight = new THREE.DirectionalLight(0xffe8d8, .8)
mainLight.position.set(-50, 40, -40)

更多種類光源及其參數

預覽

這時候打開瀏覽器依舊是一片白什麼也沒有,
nani

不要打我,由於場景裏面尚未添加物體

添加物體

概念

不負責任地說,一個場景中的物體實際上是由兩部分組成的geometry和material

  • geometry:就是物體的骨架,決定了物體在三維空間中的形狀

  • material:就是物體的皮膚,決定了物體在三維空間的呈現(自身顏色,是否反光,是否透明)

three.js中的geometry
three.js中的material

代碼實現

var geometry = new THREE.BoxGeometry(1, 1, 1)
// 建立一個邊長爲1的立方體

var material = new THREE.MeshLambertMaterial({
    color:0x6699ff
    })
// 建立顏色爲0x6699ff的Lambert材質

var cube = new THREE.Mesh(geometry, material)
// 將骨架與材質合成物體

scene.add(cube)
// 添加這個物體

預覽

這樣在瀏覽器中就能夠看見一個物體了
cube

運動

這樣一個物體顯得單調乏味,想個辦法讓他動起來

概念

  • 幀:動畫都是一幀一幀呈現的,就意味着咱們須要一個循環,不斷地在畫布上繪製

  • requestAnimationFrame:它不是一個以時間爲基準的API,因此你沒必要設定調用時間,它會在瀏覽器準備好繪製幀的時候調用

代碼實現

改造一下render:

function loop() {
        renderer.render(scene, camera)
        // 每一幀都渲染一次
        
        cube.rotation.x += 0.01
        // 立方體繞x軸轉動
        
        cube.rotation.z += 0.05
        // 立方體繞z終轉動
        
        requestAnimationFrame(loop)
        // 循環
    }
    
    loop()

預覽

rotation

在瀏覽器中能夠看見立方體轉動起來了

後續

下一節將介紹模型中各物體如山坡,房子的構建,以及如何建立陰影

相關文章
相關標籤/搜索