300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Three.js 3D 动画场景搭建

Three.js 3D 动画场景搭建

时间:2022-08-05 21:32:05

相关推荐

Three.js 3D 动画场景搭建

最近看了一篇文章,用three.js写了一个很有趣的游戏场景,看了之后发现又想好好学一下three.js。

文章:/codrops//04/26/the-aviator-animating-basic-3d-scene-threejs/?utm_source=tuicool

对整个流程介绍的很是详细。拜读了这篇文章之后,决定也用three.js搭建一个场景试一试,感觉很有趣的样子。很喜欢狐妖小红娘这个国漫,真的很好看的国漫,安利一下。就尝试一下狐妖小红娘里面的相思树吧,能力有限,先做得粗糙一点,作为练习吧!以后有时间了,再好好做一下。

搭建简单的场景,用到了three里面的两种基础几何形状。

CylinderGeometry柱体类, 构造函数如下所示(radiusTopradiusBottom分别是顶面和底面的半径,由此可知,当这两个参数设置为不同的值时,实际上创建的是一个圆台;height是圆柱体的高度;radiusSegmentsheightSegments可类比球体中的分段;openEnded是一个布尔值,表示是否没有顶面和底面,缺省值为false,表示有顶面和底面);

THREE.CylinderGeometry(radiusTop, radiusBottom, height, radiusSegments, heightSegments, openEnded)

SphereGeometry是球体类, 构造函数如下所示 (radius是半径;segmentsWidth表示经度上的切片数;segmentsHeight表示纬度上的切片数;phiStart表示经度开始的弧度;phiLength表示经度跨过的弧度;thetaStart表示纬度开始的弧度;thetaLength表示纬度跨过的弧度), 其中需要注意的是在使用时可以根据经纬度切片数来定制球形外形, 可以通过经纬度弧度来定制球形起始形状;

THREE.SphereGeometry(radius, segmentsWidth, segmentsHeight, phiStart, phiLength, thetaStart, thetaLength)

尝试做一个简单的场景,图片如下:

用CylinderGeometry、SphereGeometry创建花朵,以及基本的树枝。主要用到了旋转、缩放和平移。由于要注意创建的柱状体的组合,需要计算在x、y、z方向的平移位置。

代码:

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title><script type="text/javascript" src="three.js"></script><script type="text/javascript" src="OrbitControls.js"></script><script type="text/javascript" src="CanvasRenderer.js"></script><script type="text/javascript" src="Projector.js"></script><style>#world {position: absolute;width: 100%;height: 100%;overflow: hidden;background: linear-gradient(#e4dcdc, #c0f2f7);}</style></head><body><div id="world"></div><script>//COLORSvar Colors ={white:'#f7fff3',flo1:'#e0c9e4',flo2:'#e4c4c0',flo3:'#e4a5a7',branch1:'#435516',branch2:'#55492c',blue:'#65f7e2',glass:'#95e9aa'};// THREEJS RELATED VARIABLESvar scene,camera, fieldOfView, aspectRatio, nearPlane, farPlane, renderer, container;//SCREEN & MOUSE VARIABLESvar HEIGHT, WIDTH;//INIT THREE JS, SCREEN AND MOUSE EVENTSfunction createScene() {HEIGHT = window.innerHeight;WIDTH = window.innerWidth;scene = new THREE.Scene();aspectRatio = WIDTH / HEIGHT;fieldOfView = 60;nearPlane = 1;farPlane = 10000;camera = new THREE.PerspectiveCamera(fieldOfView,aspectRatio,nearPlane,farPlane);scene.fog = new THREE.Fog('#f7fff3', 100,950);camera.position.x = 0;camera.position.z = 200;camera.position.y = 100;renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });renderer.setSize(WIDTH, HEIGHT);renderer.shadowMap.enabled = true;container = document.getElementById('world');container.appendChild(renderer.domElement);window.addEventListener('resize', handleWindowResize, false);}// HANDLE SCREEN EVENTSfunction handleWindowResize() {HEIGHT = window.innerHeight;WIDTH = window.innerWidth;renderer.setSize(WIDTH, HEIGHT);camera.aspect = WIDTH / HEIGHT;camera.updateProjectionMatrix();}// LIGHTSvar hemisphereLight, shadowLight;function createLights() {hemisphereLight = new THREE.HemisphereLight(0xaaaaaa,0x000000, .9);shadowLight = new THREE.DirectionalLight(0xffffff, .9);shadowLight.position.set(150, 350, 350);shadowLight.castShadow = true;shadowLight.shadow.camera.left = -400;shadowLight.shadow.camera.right = 400;shadowLight.shadow.camera.top = 400;shadowLight.shadow.camera.bottom = -400;shadowLight.shadow.camera.near = 1;shadowLight.shadow.camera.far = 1000;shadowLight.shadow.mapSize.width = 2048;shadowLight.shadow.mapSize.height = 2048;scene.add(hemisphereLight);scene.add(shadowLight);}function Land(){var geom = new THREE.SphereGeometry(600,80,80);geom.applyMatrix(new THREE.Matrix4().makeRotationX(-Math.PI/2));var mat = new THREE.MeshPhongMaterial({color:Colors.glass,transparent:true,opacity:0.8,shading:THREE.FlatShading});this.mesh = new THREE.Mesh(geom, mat);this.mesh.receiveShadow = true;}function Tree(){this.mesh = new THREE.Object3D();// 树干var trunk = new THREE.CylinderGeometry(25,40,120,60,3);var material1 = new THREE.MeshPhongMaterial({color:Colors.branch2,shading:THREE.FlatShading,transparent:true,opacity:0.8});var trunkMesh = new THREE.Mesh(trunk, material1);trunkMesh.castShadow = true;trunkMesh.receiveShadow = true;this.mesh.add(trunkMesh);//顶部var topB=new Branch();topB.mesh.scale.set(2,2,2);topB.mesh.position.y = 80;this.mesh.add(topB.mesh);//中层var len,moveX,moveY,moveZ,i;var numMiddele=6;var angleStepM=(Math.PI*2)/numMiddele;for(i=0;i<6;i++){var mid=new Branch();var sc0=2;mid.mesh.applyMatrix(new THREE.Matrix4().makeRotationZ(Math.PI/6));mid.mesh.applyMatrix(new THREE.Matrix4().makeRotationY(angleStepM*i));mid.mesh.scale.set(sc0,sc0,sc0);len=Math.cos(Math.PI/2-Math.PI/6)*sc0*14;moveX=-Math.cos(angleStepM*i)*len;moveY=85;moveZ=Math.sin(angleStepM*i)*len;mid.mesh.position.set(moveX,moveY,moveZ);// mid.mesh.position.y = 80;this.mesh.add(mid.mesh);}//底层var numBottom=10;var angleStepB=(Math.PI*2)/numBottom;for(i=0;i<numBottom;i++){var sc=2.5;var an=Math.PI/2-Math.PI/8*Math.random();var bom=new Branch();bom.mesh.applyMatrix(new THREE.Matrix4().makeRotationZ(an));bom.mesh.applyMatrix(new THREE.Matrix4().makeRotationY(angleStepB*i));bom.mesh.scale.set(sc,sc,sc);len=Math.cos(Math.PI/2-an)*sc*14;moveX=-Math.cos(angleStepB*i)*len;moveY=75;moveZ=Math.sin(angleStepB*i)*len;bom.mesh.position.set(moveX,moveY,moveZ);// mid.mesh.position.y = 80;this.mesh.add(bom.mesh);}}function Branch(){this.mesh = new THREE.Object3D();var trunk = new THREE.CylinderGeometry(1,2,28,12,1);var scrown = new THREE.SphereGeometry(20,6,5,0,Math.PI*2,0,Math.PI/3);var scale=[1.3,0.7,0.4];var rotate=[0,Math.PI/6,-Math.PI/4];var translation=[[0,0,0],[-6,-3,0],[4,-4,0]];var Ele=[];for (var i=1; i<=3; i++ ){var s=scale[i-1];var ro=rotate[i-1];var trans=translation[i-1];var crownMat = new THREE.MeshPhongMaterial({color:Colors['flo'+i], shading:THREE.FlatShading, transparent:true,opacity:0.8});var trunkMat = new THREE.MeshPhongMaterial({color:Colors.branch1, shading:THREE.FlatShading,transparent:true,opacity:0.6});var m1 = new THREE.Mesh(trunk.clone(), trunkMat);m1.castShadow = true;m1.receiveShadow = true;var m2 = new THREE.Mesh(scrown.clone(), crownMat);m2.position.set(0,10-Math.cos(Math.PI/3)*20,0);m2.castShadow = true;m2.receiveShadow = true;m1.add(m2);//先旋转 再缩放 再平移m1.applyMatrix(new THREE.Matrix4().makeRotationZ(ro));m1.scale.set(s,s,s);m1.position.set(trans[0],trans[1],trans[2]);this.mesh.add(m1);}}function MuitiFlo(){this.mesh = new THREE.Object3D();this.nFlowers = 50;var stepAngle = Math.PI*2 / this.nFlowers;for(var i=0; i<this.nFlowers; i++){var c = new Flower();var a = stepAngle*i;var h = 650 + Math.random()*200;c.mesh.position.y = Math.sin(a)*h;c.mesh.position.x = Math.cos(a)*h;c.mesh.position.z = -100-Math.random()*100;c.mesh.rotation.z = a - Math.PI/2;var s = 0.2+Math.random()*0.2;c.mesh.scale.set(s,s,s);this.mesh.add(c.mesh);}}//花朵function Flower() {this.mesh = new THREE.Object3D();var trunk = new THREE.CylinderGeometry(1, 2, 16);var petal=new THREE.CylinderGeometry(1, 1, 14);var trunkmat = new THREE.MeshPhongMaterial({color: Colors.branch1, shading: THREE.FlatShading});var trunkpetal = new THREE.MeshPhongMaterial({color: Colors.flo2, shading: THREE.FlatShading});var trunkpetal1 = new THREE.MeshPhongMaterial({color: Colors.flo3, shading: THREE.FlatShading});var tmesh = new THREE.Mesh(trunk, trunkmat);tmesh.castShadow = true;tmesh.receiveShadow = true;this.mesh.add(tmesh);var angleIndex=(Math.PI*2)/12;var len,moveX,moveY,moveZ,i;for (i = 0; i <12; i++) {var m = new THREE.Mesh(petal, trunkpetal);m.castShadow = true;m.receiveShadow = true;m.applyMatrix(new THREE.Matrix4().makeRotationZ(Math.PI/3));m.applyMatrix(new THREE.Matrix4().makeRotationY(angleIndex*i));len=Math.cos(Math.PI/6)*7;moveX=-Math.cos(angleIndex*i)*len;moveY=8;moveZ=Math.sin(angleIndex*i)*len;m.position.set(moveX,moveY,moveZ);this.mesh.add(m);}angleIndex=(Math.PI*2)/8;for (i = 0; i <8; i++) {var m1 = new THREE.Mesh(petal, trunkpetal1);m1.castShadow = true;m1.receiveShadow = true;m1.applyMatrix(new THREE.Matrix4().makeRotationZ(Math.PI/6));m1.applyMatrix(new THREE.Matrix4().makeRotationY(angleIndex*i));len=Math.cos(Math.PI/3)*7;moveX=-Math.cos(angleIndex*i)*len;moveY=8;moveZ=Math.sin(angleIndex*i)*len;m1.position.set(moveX,moveY,moveZ);this.mesh.add(m1);}}var land,tree,flos;function init(event){document.addEventListener('mousemove', handleMouseMove, false);//创建场景createScene();//创建光线createLights();land = new Land();land.mesh.position.y = -550;land.mesh.position.x = 80;land.mesh.position.z = -50;scene.add(land.mesh);tree=new Tree();tree.mesh.position.y = 50;tree.mesh.position.x = 80;scene.add(tree.mesh);//添加花朵flos = new MuitiFlo();flos.mesh.position.y = -550;scene.add(flos.mesh);loop();}//LOOPfunction loop(){renderer.render(scene, camera);flos.mesh.rotation.z += .002;tree.mesh.rotation.y+=0.001;requestAnimationFrame(loop);}// HANDLE MOUSE EVENTSvar mousePos = { x: 0, y: 0 };function handleMouseMove(event) {var tx = -1 + (event.clientX / WIDTH)*2;var ty = 1 - (event.clientY / HEIGHT)*2;mousePos = {x:tx, y:ty};}window.addEventListener('load', init, false);</script></body></html>

截图:

基础对象:

demo:https://ccessl.github.io/three-use/

先这样吧比较粗糙,作为自己的练习~~~~~~~

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。