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

本文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

在浏览器中能够看见立方体转动起来了

后续

下一节将介绍模型中各物体如山坡,房子的构建,以及如何建立阴影

相关文章
相关标签/搜索