zoukankan      html  css  js  c++  java
  • Three.js基础学习【修改版】

       一、 Three.js官网及使用Three.js必备的三个条件

    1.Three.js 官网  https://threejs.org/

    2.使用Three.js必备的三个条件

    (To actually be able to display anything with Three.js, we need three things: A scene, a camera, and a renderer so we can render the scene with the camera.)


    大致意思是使用
    three.js可以实现任何显示的东西,必须满足三个条件: a scene场景、a camera相机、a renderer渲染器. 三者缺一不可。

       二、理解(a scene场景、a camera相机、a renderer渲染器)三者之间的原理关系

     



    如上图所示,来说明a scene场景、a camera相机、a renderer渲染器三者之间关系

       1.场景scene 是一个物体的容器【通俗理解装东西的嘛】,开发者可以将需要的角色放入场景中,例如苹果,葡萄。同时,角色自身也管理着其在场景中的位置。

     2.相机camera 的作用就是面对场景,在场景中取一个合适的景,把它拍下来。【可以想象成人的眼睛】

     3.渲染器renderer 的作用就是将相机拍摄下来的图片,放到浏览器中去显示

       三、通过上述理论来实践官网案例  

       效果图如下

           

     官网案例实现源码

    <html>
    	<head>
    		<title>My first three.js app</title>
    		<style>
    			body { margin: 0; }
    			canvas {  100%; height: 100% }
    		</style>
    	</head>
    	<body>
    		<script src="./lib/three.js"></script>
    		<script>
    		        //创建一个场景对象
    			var scene = new THREE.Scene();
    			//创建一个相机对象
    			var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
    			
    			//创建一个渲染器对象
    			var renderer = new THREE.WebGLRenderer();  
    			//设置画布尺寸
    			renderer.setSize( window.innerWidth, window.innerHeight );
    			//设置画布色
                            renderer.setClearColor(0x00AABB, 1.0);
                            //将渲染画布添加到浏览器中,以便后面剩放相机拍下的景
    		        document.body.appendChild( renderer.domElement ); 
    		    
    		        //创建一个几何体长、宽、高分别为1几何体对象
    			var geometry = new THREE.BoxGeometry( 1, 1, 1 ); 
    			//材料、皮肤
    			var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
    			//将material材料添加到几何体geometry,产生新的对象几何体cube
    			var cube = new THREE.Mesh( geometry, material );
    			//将几何体添加至场景中
    			scene.add( cube ); 
    			//设置相机z轴,垂直电脑屏幕位置
    			camera.position.z = 5;
                    
    			var render = function () {
    				/*requestAnimationFrame( render );  //循环渲染
    				cube.rotation.x += 0.1; //x轴每秒旋转60次
    				cube.rotation.y += 0.1;//y轴每秒旋转60次*/
    				renderer.render(scene, camera); //实时将相机拍下的几何体渲染到场景中
    			};
    			render();
    </script>
    	</body>
    </html>
    

    通过官网案例不难发现,camera 照相机默认观察方向是屏幕的方向(z轴负方向),当变化坐标以后,就要将照相机指向原点,才能观察到物体

      z轴负方向???因此这里很有必要说说三维坐标(如下图)

      照相机指向原点???来说说相机camera相机,<说明:相机指向原点[lookAt]官网案修改且设置相机朝向及相机位置、模块化代码有说明哦>

    camera相机很重要!!!想象一下人看不到东西是什么感觉).

    案例中采用透视相机(从视点开始越近的物体越大、远处的物体绘制的较小的一种方式、和日常生活中我们看物体的方式是一致的。)

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

    new THREE.PerspectiveCamera(fov, aspect , near,far)  透视相机
    视野角:fov 这里视野角(有的地方叫拍摄距离)越大,场景中的物体越小,视野角越小,场景中的物体越大
    纵横比:aspect
    相机离视体积最近的距离:near
    相机离视体积最远的距离:far
    

    综上,相信结合上述三维坐标、相机图理解相机、就应该变得很简单咯哦.接下来接着修改上述案例(说明 后面案例鼠标滚动放大缩小、三维旋转都是基于相机来实现的)

       四、将官网案修改且设置相机朝向及相机位置、模块化代码

    利用[lookAt]方法来设置相机的视野中心。 「lookAt()」的参数是一个属性包含中心坐标「x」「y」「z」的对象。
    设置相机的上方向为正方向y轴 camera.up.x = 0; camera.up.y = 1/*相机朝向--相机上方为y轴*/; camera.up.z = 0;

    官网修改——案例源码(官网案修改且设置相机朝向及相机位置、模块化代码)
    <html>
    	<head>
    		<title>3dmax update</title>
    		<style>
    			body { margin: 0; }
    			canvas {  100%; height: 100% }
    		</style>
    	</head>
    	<body>
    		<script src="./lib/three.js"></script>
    		<script>
    		   //集中声明变量 ,未初始化时默认值undefined
    		   var scene = null,  //场景
    		       camera = null, //相机
    		       renderer = null, //渲染器
    		       cube = null;  //几何体变量
    		       
    		    function initThree(){
    		  	  //创建一个渲染器对象
    			   renderer = new THREE.WebGLRenderer();  
    			   //设置画布尺寸
    			   renderer.setSize( window.innerWidth, window.innerHeight );
    			   //设置画布色
    	           renderer.setClearColor(0x00AABB, 1.0);
    	           //将渲染画布添加到浏览器中,以便后面剩放相机拍下的景
    			   document.body.appendChild( renderer.domElement ); 
    		    }
    		   
    		   //初始化场景
    		   function initScene(){
    		   	 //创建一个场景对象
    		   	 scene = new THREE.Scene();
    		   }
    		   
    		   //初始化相机
    		   function initCamera(){
    		   	   //视野角:fov   纵横比 aspect  相机离视体积最近的距离:near  相机离视体积最远的距离:far
    	           //var camera = new THREE.PerspectiveCamera( fov, aspect , near,far );
    	           //创建一个相机对象
    			   camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
    			   //相机距离X/Y/Z轴位置
    	           camera.position.x = 1;
    	           camera.position.y = 5;
    	           //设置相机z轴,垂直电脑屏幕位置
    			   camera.position.z = 2;
    			   //相机朝向
    			   camera.up.x = 0;
    			   camera.up.y = 1; //相机朝向--相机上方为y轴
    			   camera.up.z = 0;
    			   camera.lookAt({  //相机的中心点
    				  	x : 0,
    	                y : 0,
    	                z : 0
    	           });
    		   }
              //3d模型
    		  function initObject(){
    		  	  //创建一个几何体长、宽、高分别为1几何体对象
    			   var geometry = new THREE.BoxGeometry( 1, 1, 1 ); 
    			   //材料、皮肤
    			   var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
    			   //将material材料添加到几何体geometry,产生新的对象几何体cube
    			   cube = new THREE.Mesh( geometry, material );
    			   //将几何体添加至场景中
    			   scene.add( cube ); 
    		  }
    		 
    		//实时渲染   
    		function render() {
    			requestAnimationFrame( render );  //循环渲染
    			cube.rotation.x += 0.1; //x轴每秒旋转60次
    			cube.rotation.y += 0.1;//y轴每秒旋转60次*/
    			renderer.render(scene, camera); //实时将相机拍下的几何体渲染到场景中
    		};
    		
    		//初始化辅助网格
    		function initGrid(){ //辅助网格
                var helper = new THREE.GridHelper( 10, 2 );
                helper.setColors( 0x0000ff, 0x808080 );
                scene.add( helper );
            }
    			
    		function threeStart(){
                //初始化渲染器
                initThree();
                //初始化场景
                initScene();
                //初始透视化相机
                initCamera();
                //模型对象
                initObject();
                //初始化网格辅助线
                initGrid();
                //渲染成像
                render();
                //实时将相机拍下的几何体渲染到场景中
                //renderer.render(scene, camera); 
            }
    		//初始化函数
    		threeStart();
    		</script>
    	</body>
    </html>

        五、实现旋转立方体 

    旋转动画原理 相机围绕y轴旋转,不断修改相机x、z轴位置,并且保持场景中的物体一直再相机的视野中,实时将相机拍摄下来的图片,放到浏览器中去显示

    //相机围绕y轴旋转,不断修改相机x、z轴位置,并且保持场景中的物体一直再相机的视野中
    //实时渲染成像
    function animation(){
              var timer = Date.now()*0.0001;
              camera.position.x = Math.cos(timer)*100;
              camera.position.z = Math.sin(timer)*100;
              camera.lookAt(scene.position); //设置相机视野中心
              renderer.render(scene, camera);
              requestAnimationFrame(animation);//渲染回调函数
    }

    实现效果图如下所示

    旋转立方体——案例源码

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>旋转立方体 </title>
            <style>
                #canvas-frame {
                     100%;
                    height: 600px;
                }
            </style>
        </head>
        <body onload="threeStart()">
            <div id="canvas-frame" ></div>
        </body>
        <script type="text/javascript" src="./lib/three.js" ></script>
        <script type="text/javascript">
                var renderer, //渲染器
                    width = document.getElementById('canvas-frame').clientWidth, //画布宽
                    height = document.getElementById('canvas-frame').clientHeight; //画布高
                //初始化渲染器
                function initThree(){
                    renderer = new THREE.WebGLRenderer({
                         antialias : true
                         //canvas: document.getElementById('canvas-frame')
                    });
                    renderer.setSize(width, height);
                    renderer.setClearColor(0xFFFFFF, 1.0);
                    document.getElementById('canvas-frame').appendChild(renderer.domElement);
                    renderer.setClearColor(0xFFFFFF, 1.0);
                }
                //初始化场景
                var scene;
                function initScene(){
                    scene = new THREE.Scene();
                }
                var camera;
                function initCamera() {  //透视相机
                    camera = new THREE.PerspectiveCamera(45,  width/height , 1, 10000);
                    camera.position.x = 50;
                    camera.position.y = 150;
                    camera.position.z =150;
                    camera.up.x = 0;
                    camera.up.y = 1; //相机朝向--相机上方为y轴
                    camera.up.z = 0;
                    camera.lookAt({  //相机的中心点
                        x : 0,
                        y : 0,
                        z : 0
                    });
                    
                   // camera  正交相机
                    /*camera = new THREE.OrthographicCamera(-300, 300, 100, -100, 1, 10000);
                    camera.position.x = 250;
                    camera.position.y = 100;
                    camera.position.z = 1800;
                    camera.up.x = 0;
                    camera.up.y = 1; //相机朝向--相机上方为y轴
                    camera.up.z = 0;
                    camera.lookAt({  //相机的中心点
                        x : 0,
                        y : 0,
                        z : 0
                    });*/
                }
                 
                function initLight(){
                    // light--这里使用环境光
                    //var light = new THREE.DirectionalLight(0xffffff); /*方向性光源*/
                    //light.position.set(600, 1000, 800);
                    var light = new THREE.AmbientLight(0xffffff); //模拟漫反射光源
                    light.position.set(600, 1000, 800); //使用Ambient Light时可以忽略方向和角度,只考虑光源的位置
                    scene.add(light);
                }
                function initObject(){  //初始化对象
                     
                    //初始化地板
                    initFloor();
                }
                function initGrid(){ //辅助网格
                    var helper = new THREE.GridHelper( 1000, 50 );
                    helper.setColors( 0x0000ff, 0x808080 );
                    scene.add( helper );
                }
                 
                function initFloor(){
                    //创建一个立方体
                    var geometry = new THREE.BoxGeometry(80, 20, 80);
                     for ( var i = 0; i < geometry.faces.length; i += 2 ) {
                        var hex = Math.random() * 0xffffff;
                        geometry.faces[ i ].color.setHex( hex );
                        geometry.faces[ i + 1 ].color.setHex( hex );
                    }
                    var material = new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors} );
                    //将material材料添加到几何体geometry
                    var mesh = new THREE.Mesh(geometry, material);
                    mesh.position = new THREE.Vector3(0,0,0);
                    scene.add(mesh);
                }
          
                 
                //初始化页面加载
                function threeStart(){
                    //初始化渲染器
                    initThree();
                    //初始化场景
                    initScene();
                    //初始透视化相机
                    initCamera();
                    //初始化光源
                    //initLight();
                    //模型对象
                    initObject();
                    //初始化网格辅助线
                    initGrid();
                    //renderer.render(scene, camera);
                    //实时动画
                    animation();
                   
                }
                /*
                 * 旋转原理
                 * 相机围绕y轴旋转
                 * 不断修改相机x、z轴位置,并且保持场景中的物体一直再相机的视野中,
                 * 实时将相机拍摄下来的图片,放到浏览器中去显示
                 */
                function animation(){
                    //渲染成像
                    var timer = Date.now()*0.0001;
                    camera.position.x = Math.cos(timer)*100; //相机位置x轴方向
                    camera.position.z = Math.sin(timer)*100; //相机位置y轴方向
                    //设置相机视野中心
                    camera.lookAt(scene.position); 
                    //渲染成像
                    renderer.render(scene, camera);
                    //渲染回调animation函数
                    requestAnimationFrame(animation);
                }
        </script>
    </html>

    至此完毕,附上个人绘制思路流程图

    【参考资料】  

       http://www.hewebgl.com/article/getarticle/50

       http://www.xyhtml5.com/threejs-star-moving-particles.html

       https://read.douban.com/reader/ebook/7412854/

    作者:Avenstar

    出处:http://www.cnblogs.com/zjf-1992/p/6053349.html

    关于作者:专注于WEB前端开发

    本文版权归作者所有,转载请标明原文链接。

    如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我不断的迭代!

    支付宝

    微信

  • 相关阅读:
    PHP中的trait
    Laravel中的队列
    微信小程序开发常见问题
    python学习day1
    javaScript实现栈的创建,添加元素,检查栈是否为空,删除元素,查看栈顶元素,清空栈元素,toString方法,通过栈实现多种进制转换
    join&concat&splice&slice&indexOf&lastindexOf&charCodeAt&fromCharCode
    使用函数自动创建表格
    两种方式实现随机颜色
    多选全选框使用addEvenListener实现
    使用setInterval来控制正方形的移动的频率(每隔1秒),鼠标点击停止移动,当再次点击恢复移动
  • 原文地址:https://www.cnblogs.com/zjf-1992/p/6053349.html
Copyright © 2011-2022 走看看