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 { width: 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 { width: 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 {
- width: 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/
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我不断的迭代!

支付宝

微信
Three.js基础学习【修改版】的更多相关文章
- JS基础学习——对象
JS基础学习--对象 什么是对象 对象object是JS的一种基本数据类型,除此之外还包括的基本数据类型有string.number.boolean.null.undefined.与其他数据类型不同的 ...
- JS基础学习——闭包
JS基础学习--闭包 什么是闭包 闭包的定义如下,它的意思是闭包使得函数可以记住和访问它的词法范围,即使函数是在它声明的词法范围外执行.更简单来讲,函数为了自己能够正确执行,它对自己的词法范围产生闭包 ...
- JS基础学习——作用域
JS基础学习--作用域 什么是作用域 变量的作用域就是变量能被访问到的代码范围,比如在下面的这个js代码中,变量a的作用域就是函数foo,因此在全局作用域内的console.log(a)语句不能访问到 ...
- JS 基础学习随想
2012年就已经接触过了js,给我的印象:这是一门谈不上复杂的语言.大概这就是所谓的学的越浅,用的越少,觉得自己会的东西好像得更多吧!开始做基础练习题的时候觉得好像都十分简单.可是后来在做到对象数组的 ...
- handlebars.js基础学习笔记
最近在帮学校做个课程网站,就有人推荐用jquery+ajax+handlebars做网站前端,刚接触发现挺高大上的,于是就把一些基础学习笔记记录下来啦. 1.引用文件: jquery.js文件下载:h ...
- JS基础学习1
1 JS 概述 一个完整的javascript实现是由以下3个不同部分组成的: (1) 核心(ECMAscript) (2) 文档对象模型(DOM) Document object ...
- JS基础学习篇(一)
近来一直在学习js和jquery.刚刚进入前端工作还没有多久,虽然大学里学习的是编程自认为也学的还可以,但前端接触的不多,一直认为前端十分简单.其实不然,特别是工作的时候要自己设计一个完整的项目前端, ...
- Node.js基础学习四之注册功能
前言:在Node.js学习(二)和(三)中介绍了如何在Node.js 中获取登录的用户名和密码与数据库进行验证并返回数据给客户端 需求:实现注册功能 为了区分登录和注册是两个不同的请求,在端口后面加上 ...
- 两万字Vue.js基础学习笔记
Vue.js学习笔记 目录 Vue.js学习笔记 ES6语法 1.不一样的变量声明:const和let 2.模板字符串 3.箭头函数(Arrow Functions) 4. 函数的参数默认值 5.Sp ...
随机推荐
- 杭电ACM2001--计算两点间的距离
计算两点间的距离 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- 【Oracle 11gR2】静默安装 db_install.rsp文件详解
#################################################################### ## Copyright(c) Oracle Corporat ...
- html 三列布局(两列自适应,一列固定宽度)
不做过多解释:主要是记录一个完整的布局样式,实现页面大致三列其中左右两列是自适应宽度,中间固定宽度效果. 不多少代码奉上: CSS样式代码: /******************** *公共标签样式 ...
- (5)Microsoft office Word 2013版本操作入门_标尺
1.标尺 :左缩进,右缩进,悬挂缩进,首行缩进,阴影部分 可以左右拖拽调整边缘. 1.1 左缩进:默认缩进所在的段落,要缩进多段则需要多段落选中, 后拖动左缩进. 1.2 首行缩进缩进或者突出所选的 ...
- with与上下文管理器
如果你有阅读源码的习惯,可能会看到一些优秀的代码经常出现带有 "with" 关键字的语句,它通常用在什么场景呢? 对于系统资源如文件.数据库连接.socket 而言,应用程序打开这 ...
- Javascript继承4:洁净的继承者----原型式继承
//原型式继承 function inheritObj(obj){ //声明一个过渡函数对象 function F(){} //过渡对象的原型继承父对象 F.prototype = obj; //返回 ...
- Excel通用类工具(一)
前言 最近项目中遇到要将MySQL数据库中的某些数据导出为Excel格式保存,在以前也写过这样的功能,这次就准备用以前的代码,但是看了一下,这次却不一样,因为在以前用到的都是导出一种或几种数据,种类不 ...
- linux 下修改mysql下root 权限来允许远程连接
MySQL默认只允许root帐户在本地登录,如果要在其它机器上连接mysql,必须修改root允许远程连接. 其操作简单,如下所示: 1. 进入mysql: /usr/local/mysql/bin/ ...
- linux防火墙相关 iptables
1. root用户查看防火墙状态(非root用户无权限查看) 查看防火墙状态: service iptables status 2.开启和关闭防火墙 //开启防火墙: service iptables ...
- java框架之spring
一.HelloWorld程序 导入四个核心包(core.beans.expression.context)和一个logging的包: 写一个类并在 xml 中配置相应的bean(两个重要属性 id 和 ...