Three.js学习

Three.js

01-three.js

1.three.js资源

GitHub:https://github.com/mrdoob/three.js

官网:https://threejs.org/

相关库:

功能
Physijs Physijs是一款物理引擎,可以协助基于原生WebGL或使用three.js创建模拟物理现象,比如重力下落、物体碰撞等物理现
stats.js JavaScript性能监控器,同样也可以测试webgl的渲染性能
dat.gui 轻量级的icon形用户界面框架,可以用来控制Javascript的变量,比如WebGL中一个物体的尺寸、颜色
tween.js 借助tween.js快速创建补间动画,可以非常方便的控制机械、游戏角色运动
ThreeBSP 可以作为three.js的插件,完成几何模型的布尔,各类三维建模软件基本都有布尔的概念
2.学习three.js与webGl

Threejs是基于原生WebGl API和着色器封装得到的3D引擎,也就是一个js库。通过原生WebGL直接编写程序,会比较麻烦,一般开发项目直接使用Thre.js引擎。简单的项目一般也用不到底层WebGL知识,不过学习WebGl有助于深入理解Threejs,如果使用Thre.js开发项目需要自定义着色器的时候,肯定也是要学习底层WebGL和着色器GLSL知识。

02-three.js基础运用

1.程序结构

Three.js学习

2.创建场景
类别 内容
二维几何 PlaneGeometry 平面、 CircleGeometry 圆形、 ShapeGeometry 塑形
三维几何体 BoxGeometry 立方体(或叫三维方块)、 SphereGeometry 球体、 CylinderGeometry 柱体、 TorusGeometry 圆环 、TorusKnotGeometry 环面扭结、 PolyhedronGeometry 多面体、 IcosahedronGeometry 十二面体、 OctahedronGeometry 八面体、 TetrahedronGeometry 四面体
复杂几何体 ConvexGeometry 凸面体、 LatheGeometry 扫描面、 ExtrudeGeometry 拉伸几何体、 TubeGeometry 管状体、 ParametricGeometry 参数几何体、 TextGeometry 文本几何体
名称 内容 参数
MeshBasicMaterial MeshBasicMaterial是一种非常简单的材质,这种材质不考虑场景中光照的影响。使用这种材质的网格会被渲染成简单的平面多边形,而且也可以显示几何体的线框,对场景中的雾化会有反应。 color(颜色),wireframe(线框),wireframeLinewidth(线框宽度),wireframeLinecap(线框线段端点),wireframeLinejoin(线框线段连接点),shading(着色)、 vertexColors(顶点颜色),fog(雾化)
MeshPhongMaterial 该材料使用非基于物理的Blinn-Phong模型来计算反射系数。通过THREE.MeshPhongMaterial,可以创建一种光亮的材质,与在MeshLambertMaterial中使用的Lambertian模型不同,它可以模拟带有高光的闪亮表面(如漆木)。 color(颜色)、shininess(光滑度),specular(高光),ambient(环境色),emissive(发射颜色),metal(像素颜色计算),wrapAround(光照效果),wrapRGB(控制光)
MeshLambertMaterial 这种材质可以用来创建暗淡的并不光亮的表面。 无光泽表面的材质,无镜面高光。 这可以很好地模拟一些表面(如未经处理的木材或石头),但不能用镜面高光(如上漆木材)模拟光泽表面。 该材质非常易用,而且会对场景中的光源产生反应。 color、opacity、shading、blending、depthTest、depthWrite、wireframe、wireframeLinewidth、wireframeLinecap、wireframeLineJoin、vertexColors和fog
 //创建场景
            var scene = new THREE.Scene();
            //显示三维坐标轴
            var axes = new THREE.AxesHelper(20)
            //添加坐标系到场景中
            scene.add(axes)

            //创建平面几何
            var planeGeometry = new THREE.PlaneGeometry(60, 20)
            //几何体材质
            var planeMaterial=new THREE.MeshBasicMaterial({color:0xCCCCCC})
            //创建平面
            var plane=new THREE.Mesh(planeGeometry,planeMaterial)

            //物体位置旋转xyz 位置:xyz
            plane.rotation.x=-0.5*Math.PI
            plane.position.x=15
            plane.position.y=0
            plane.position.z=0

            //物体添加到场景中
            scene.add(plane)
3.创建相机
  //创建相机(透视)角度,长宽比,最近视野,最远视野
            var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 2000)
            //设定摄像机位置,指向场景中心
            camera.position.x=-30
            camera.position.y=40
            camera.position.z=30
            camera.lookAt(scene.position)
4.渲染
            //创建渲染
            var renderer = new THREE.WebGLRenderer()
            //设置渲染器初始颜色
            renderer.setClearColor(new THREE.Color(0xEEEEEE))
            //设置输出canvas画面大小宽,高
            renderer.setSize(window.innerWidth, window.innerHeight)
            //渲染
            document.getElementById('webgl-output').appendChild(renderer.domElement)
            renderer.render(scene,camera)

5.光源与阴影

阴影与光源有关,涉及函数包括castShadow,receiveShadow。投影物体与光源需要设置castShadow为true,

同时接受阴影的平面需要receiveShadow为true,注意投影平面不使用MeshBasicMaterial,否则可能存在投影不生效情况

 function init() {
            //创建场景
            var scene = new THREE.Scene();

            //创建阴影投射平面
            var planeGeometry = new THREE.PlaneGeometry(40, 40)
            var planeMaterial = new THREE.MeshLambertMaterial({color: 0xCCCCCC})
            var plane = new THREE.Mesh(planeGeometry, planeMaterial)
            plane.rotation.x = -0.5 * Math.PI
            plane.receiveShadow = true
            scene.add(plane) //物体添加到场景中

            //添加球体
            var sphereGeometry = new THREE.SphereGeometry(4, 20, 20)
            var sphereMaterial = new THREE.MeshLambertMaterial({color: 0xFFA500})
            var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial)
            sphere.position.set(0, 4, 2)
            sphere.castShadow = true//阴影
            scene.add(sphere) //物体添加到场景中


            //添加聚光灯
            var spotLight = new THREE.SpotLight(0xFFFFFF)
            spotLight.position.set(30, 30, -30)
            spotLight.castShadow = true
            spotLight.shadow.mapSize.width = 2048;	//阴影贴图宽度设置为2048像素
            spotLight.shadow.mapSize.height = 2048;	//阴影贴图高度设置为2048像素
            scene.add(spotLight)


            //创建相机(透视)角度,长宽比,最近视野,最远视野
            var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 2000)
            camera.position.set(30,40,30)//设定摄像机位置,指向场景中心
            camera.lookAt(scene.position)

            //创建渲染
            //设置渲染器初始颜色
            //渲染webGLRenderer
            //设置输出canvas画面大小宽,高
            var renderer = new THREE.WebGLRenderer({
                antialias: true,
                logarithmicDepthBuffer: true,
            })
            renderer.shadowMap.enabled = true
            renderer.setClearColor(new THREE.Color(0xEEEEEE))
            renderer.setSize(window.innerWidth, window.innerHeight)
            document.getElementById('webgl-output').appendChild(renderer.domElement)
            renderer.render(scene, camera)

        }

6.动画效果

旋转

1、requestAnimationFrame 会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧。

2、在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流

      function rotate() {
            renderer.render(scene, camera)
            sphere.rotateY(0.01)
            requestAnimationFrame(rotate)
        }

鼠标控制相关库为:OrbitControls

监听

    //创建控制器对象
        var control = new OrbitControls(camera, renderer.domElement)
        // 监听鼠标
        control.addEventListener('change', () => {
            renderer.render(scene, camera)
        })

requestAnimationFrame

		animate();
        var control = new OrbitControls(camera, renderer.domElement)
        function animate() {
            requestAnimationFrame(animate);
            renderer.render(scene, camera);
        }
上一篇:Kmp


下一篇:[ARC125D] Unique Subsequence