阅读 56

Three.js开发指南-阅读记录(第一章)

如何进行three.js项目开发

1.引入three.js文件

2.创建初始化函数,在页面加载完毕后执行

3.创建场景(scene)、摄像机(camera)、渲染器(renderer)

  • 场景:可以把场景当做一个环境空间,所以的我们要画的东西都必须在场景内包括摄像机
  • 摄像机:字面理解即可,需要设置摄像机的位置和摄像机指向场景中心
  • 渲染器:把画的东西渲染到页面,设置渲染器图像渲染大小

4.绘制图形

  • 平面:通过 PlaneGeometry(x,y) 方法设置图形
  • 立方体:通过 BoxGeometry(x,y,z) 方法设置图形
  • 球体:通过 SphereGeometry(r,x,y) 方法设置图形
  • 材质设置:MeshBasicMaterial(基本材质,对光源无反应)、MeshLambertMaterial(对光源有反应)、MeshPhongMaterial(对光源有反应)
  • 结合图形和材质:new THREE.Mesh(图形,材质)
  • 设置图形位置和旋转rotation、position
  • 最后添加到场景中:scene.add(图形)

5.把渲染器dom添加到页面中

document.getElementById("three").appendChild(renderer.domElement)
复制代码

执行渲染器:

renderer.render(scene,camera)
复制代码

光源设置

基本材质对光源无效,只对颜色有效,MeshLambertMaterial和MeshPhongMaterial渲染时会对光源产生反应

let spotLight = new THREE.SpotLight(0xffffff); //光源对象
spotLight.position.set(-40,60,-10);//设置光源位置
spotLight.castShadow = true //设置光源阴影
scene.add(spotLight)
复制代码

阴影的使用

  • 设置渲染器开启阴影渲染:renderer.shadowMapEnabled = true
  • 设置光源,对光源开启阴影设置:spotLight.castShadow = true 
  • 设置接收投射的阴影:plane.receiveShadow = true
  • 设置要投射的阴影:cube.castShadow = true

接下来我们看一下three几个简单辅助插件的使用

1. 坐标轴

let axes = new THREE.AxisHelper(20); //创建轴对象
scene.add(axes); //添加轴到场景
复制代码

2. FPS图形分析器

  • 引入Stats.js文件
  • 初始化 FPS图形分析器:
function initStats(){
     let stats = new Stats()
     stats.setMode(0)
     document.getElementById("stats").appendChild(stats.domElement);
     return stats
}
复制代码
  • 在渲染器函数中执行: stat.update() ,每次动画刷新都调用

3. 动画速度调试器

  • 引入dat.gui.js文件
  • 初始化:
let controls = new function(){
     this.rotationSpeed = 0.02
     this.bouncingSpeed = 0.03
}
let gui = new dat.GUI();
gui.add(controls,'rotationSpeed',0,0.5);
gui.add(controls,'bouncingSpeed',0,0.5);
复制代码
  • 使用:在渲染函数中 controls.rotationSpeed 和 controls.bouncingSpeed 表示旋转移动的值,范围定义为0-0.5

浏览器窗口自适应

  • 监听resize事件,调整渲染器和相机大小
window.addEventListener('resize',function(){
    camera.aspect = window.innerWidth/window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth,window.innerHeight)
},false)
复制代码

完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<style>
    *{
        margin: 0;
        padding: 0;
    }
    #stats{
        position: absolute;
        left: 0;
        top: 0;
    }
</style>
<body>
    <div id="stats"></div>
    <div id="three"></div>
<script src="three/libs/three/three.js"></script>
<script src="three/libs/util/Stats.js"></script>
<script src="three/libs/util/dat.gui.js"></script>
<script>

//调试动画速度
let controls = new function(){
    this.rotationSpeed = 0.02
    this.bouncingSpeed = 0.03
}

let gui = new dat.GUI();
gui.add(controls,'rotationSpeed',0,0.5);
gui.add(controls,'bouncingSpeed',0,0.5);

//初始化图形FPS
function initStats(){
    let stats = new Stats()
    stats.setMode(0)
    document.getElementById("stats").appendChild(stats.domElement);
    return stats
}

let camera
let renderer
let scene
window.onload = init
function init(){
    let stat = initStats()

    scene = new THREE.Scene(); //创建场景
    camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000); //创建摄像机
    renderer = new THREE.WebGLRenderer(); //创建渲染器

    renderer.setSize(window.innerWidth,window.innerHeight); //设置渲染大小
    renderer.shadowMapEnabled = true

    let axes = new THREE.AxisHelper(20); //创建轴对象
    scene.add(axes); //添加轴到场景

    let planeGeometry = new THREE.PlaneGeometry(60,20); //创建平面
    let planeMaterial = new THREE.MeshLambertMaterial({
        color:0xcccccc
    }); //设置材质、颜色、透明度
    let plane = new THREE.Mesh(planeGeometry,planeMaterial); //把平面和颜色合并

    //设置平面旋转和坐标位置
    plane.rotation.x = -0.5*Math.PI
    plane.position.x = 15
    plane.position.y = 0
    plane.position.z = 0
    plane.receiveShadow = true //设置接收投射的阴影
    scene.add(plane); //添加平面到场景中

    let cubeGeometry = new THREE.BoxGeometry(4,4,4); //创建立方体
    let cubeMaterial = new THREE.MeshLambertMaterial({
        color:0xff0000,
        wireframe:true //显示骨架
    });
    let cube = new THREE.Mesh(cubeGeometry,cubeMaterial)
    cube.position.x = -4
    cube.position.y = 3
    cube.position.z = 0
    cube.castShadow = true //设置投射阴影
    scene.add(cube)

    let sphereGeometry = new THREE.SphereGeometry(4,20,20)
    let sphereMaterial = new THREE.MeshPhongMaterial({
        color:0x7777ff,
        wireframe:true
    });
    let sphere = new THREE.Mesh(sphereGeometry,sphereMaterial);
    sphere.position.x = 20
    sphere.position.y = 4
    sphere.position.z = 2
    sphere.castShadow = true //设置投射阴影
    scene.add(sphere)


    //基本材质对光源无效,只对颜色有效,MeshLambertMaterial和MeshPhongMaterial渲染时会对光源产生反应
    let spotLight = new THREE.SpotLight(0xffffff); //光源对象
    spotLight.position.set(-40,60,-10);//设置光源位置
    spotLight.castShadow = true //设置光源阴影
    scene.add(spotLight)
    

    //设置摄像机位置
    camera.position.x = -30
    camera.position.y = 40
    camera.position.z = 30
    camera.lookAt(scene.position); //摄像机指向场景中心


    document.getElementById("three").appendChild(renderer.domElement)
    renderScene() //渲染

    var step = 0
    function renderScene(){
        cube.rotation.x += controls.rotationSpeed
        cube.rotation.y += controls.rotationSpeed
        cube.rotation.z += controls.rotationSpeed

        step += controls.bouncingSpeed
        sphere.position.x = 20 + (10*Math.cos(step))
        sphere.position.y = 2 + 10*Math.abs(Math.sin(step))

        stat.update();
        requestAnimationFrame(renderScene); //动画
        renderer.render(scene,camera); //渲染场景和相机到页面
    }
    
}


//适应浏览器窗口大小
window.addEventListener('resize',function(){
    camera.aspect = window.innerWidth/window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth,window.innerHeight)
},false)

</script>
</body>
</html>

复制代码

结束!

文章分类
前端
文章标签