一、 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渲染器. 三者缺一不可。

二、使用Three.js必备三个条件(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相机(很重要!!想象一下人看不到东西是什么感觉).

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

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/

作者:Avenstar

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

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

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

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

支付宝

微信

Threejs基础学习【修改版】的更多相关文章

  1. [C语言]声明解析器cdecl修改版

    一.写在前面 K&R曾经在书中承认,"C语言声明的语法有时会带来严重的问题.".由于历史原因(BCPL语言只有唯一一个类型——二进制字),C语言声明的语法在各种合理的组合下 ...

  2. HTML5零基础学习Web前端需要知道哪些?

    HTML零基础学习Web前端网页制作,首先是要掌握一些常用标签的使用和他们的各个属性,常用的标签我总结了一下有以下这些: html:页面的根元素. head:页面的头部标签,是所有头部元素的容器. b ...

  3. python入门到精通[三]:基础学习(2)

    摘要:Python基础学习:列表.元组.字典.函数.序列化.正则.模块. 上一节学习了字符串.流程控制.文件及目录操作,这节介绍下列表.元组.字典.函数.序列化.正则.模块. 1.列表 python中 ...

  4. Medoo个人修改版

    Medoo是一款轻量级的php数据库操作类,下面不会介绍Medoo的使用方法,想学习Medoo请前往官网自学:http://medoo.in/ 在接触Medoo之前,一直是用自己写的php数据库操作类 ...

  5. Oracle SQL 基础学习

    oracel sql 基础学习 CREATE TABLE USERINFO ( ID ,) PRIMARY KEY, USERNAME ), USERPWD ), EMAIL ), REDATE DA ...

  6. 转载:Eclipse+Spket插件+ExtJs4修改版提供代码提示功能[图]

    转载:Eclipse+Spket插件+ExtJs4修改版提供代码提示功能[图] ExtJs是一种主要用于创建前端用户界面,是一个基本与后台技术无关的前端ajax框架.功能丰富,无人能出其右.无论是界面 ...

  7. Perl实用中文处理步骤(修改版)

    发信人: FenRagwort (泽), 信区: Perl标  题: Perl实用中文处理步骤(修改版)发信站: 水木社区 (Mon Feb 14 12:52:14 2011), 转信 (修改版 感谢 ...

  8. TypeScript进阶开发——ThreeJs基础实例,从入坑到入门

    前言 我们前面使用的是自己编写的ts,以及自己手动引入的jquery,由于第三方库采用的是直接引入js,没有d.ts声明文件,开发起来很累,所以一般情况下我们使用npm引入第三方的库,本文记录使用np ...

  9. JavaScript 基础 学习 (一)

    JavaScript 基础 学习 获取页面中的元素的方法 作用:通过各种方式获取页面中的元素 ​ 比如:id,类名,标签名,选择器 的方式来获取元素 ​ 伪数组: ​ 长的和数组差不多,也是按照索引排 ...

随机推荐

  1. android中怎么调整字体的间距和行间距

    在网页中都是很轻松的就可以调整间距的.在android中,我个人并没有去设置过. 下面就来说说android中的间距问题. 原文:http://blog.csdn.net/fancylovejava/ ...

  2. QC邮件转发工具Mail Direct安装配置手册

    QC邮件转发工具Mail Direct安装配置手册 2010-06-11 10:00:56| 分类: 软件测试 | 标签: |举报 |字号大中小 订阅 QC邮件转发工具安装配置手册 由于公司没有独立的 ...

  3. ORACLE抽象数据类型

    ORACLE抽象数据类型 *抽象数据类型*/1,抽象数据类型 概念包含一个或多个子类型的数据类型不局限于ORACLE的标准数据类型可以用于其他数据类型中 2,创建抽象数据类型 的语法(必须用NOT F ...

  4. Object.prototype.propertyIsEnumerable

    语法: obj.propertyIsEnumerable(prop); 此方法返回一个布尔值,表明指定的属性名是否是当前对象可枚举的自身属性. 1.如果是用户自定义了对象的属性,将返回true,比如 ...

  5. myeclipse搭建svn插件

    在网上查了一下,安装的方法有几种,这里给大家推荐一种快速安装的方法. //第一步 : 下载 site-1.6.5.zip //===================================== ...

  6. 设置checkbox为只读(readOnly)

    方式一: checkbox没有readOnly属性,如果使用disabled=“disabled”属性的话,会让checkbox变成灰色的,用户很反感这种样式可以这样让它保持只读:设置它的onclic ...

  7. SQLSERVER数据库学习总结七(视图,索引)

    --视图的主意点:不能和表的名称相同,如果某一列为函数,表达式,常量或者与来自多张表的列名相同,必须为列定义名称,不能在试图上创建索引 if exists(select 1 from sys.syso ...

  8. Markdown 代码测试

    Mou Overview Mou, the missing Markdown editor for web developers. Syntax Strong and Emphasize strong ...

  9. Enterprise Architect UML 建模之活动图

    EA(Enterprise Architect) UML 建模之活动图   一.活动图的概念作用 活动图本质上是一种流程图,它描述活动的序列,即系统从一个活动到另一个活动的控制流. 活动图的作用:描述 ...

  10. HtmlParser的使用-爬虫学习(三)

    关于这个HtmlParser的学习资料,网上真的很匮乏,这个好用的东西不要浪费啊,所以我在这里隆重的介绍一下. HtmlParser是一个用来解析HTML文件的Java包,主要用于转换盒抽取两个方面. ...