Three-js 创建第一个3D场景
1.一个场景至少需要的三种类型组件
相机/决定哪些东西将在屏幕上渲染
光源/他们会对材质如何显示,以及生成阴影时材质如何使用产生影响
物体/他们是在相机透视图里主要的渲染队形:方块、球体等
2.浏览器兼容
Moziller Firefox:4.0版本以后开始支持;
Google Chrome:第9版以后开始支持
Safari:5.1版本开始支持;
Opera:12.00版本以后开始支持。要让Opera支持WebGL,你还需要打开opera:config文件,设置WebGL,并将Enable hardare Acceleration设置为1;
Inernet Explorer:从IE11开始支持WebGL
如果想让旧版本IE支持WebGL,可以使用iewebgl插件,下载网址是http://iewebgl.com/。
3.材质
Three.js里有两种材质对光源产生反应:MeshLambertMaterial和MashPhongMaterial。
4.添加阴影
添加阴影必须指定几个步骤。首先需要让渲染器支持阴影:
render.shadowMapEabled = true; // render为WebGLRenderer对象
其次需要设置哪些物体作为阴影源,哪些物体作为接受阴影:
plane.receiveShadow = true; // plane平面接受阴影
cube.castShadow = true; // cube立方体产生阴影
sphere.castshadow = true; // sphere球体产生阴影
最后需要置顶哪些光源可产生投影:
spotLight.castShadow = true // spotLight光源可产生阴影
5.检测动画帧频插件state.js
Three.js作者也写了一个显示每秒帧数(FPS)的插件,可用来统计渲染。首先在页面引入state.js文件。然后创建一个检测显示的div:
<div id="State-output"></div>
写一个初始化统计函数:
function initStats() {
var stats = new Stats();
stats.setMode(0); // 0: fps, 1: ms
// Align top-left
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
document.getElementById("Stats-output").appendChild(stats.domElement);
return stats;
}
在创建渲染对象时,我们也初始化state:
var state = initState();
在执行渲染的动画函数中,每次执行时都调用下state的update函数:
function render() {
stats.update();
...
requestAnimationFrame(render);
renderer.render(scene, camera);
}
6.使用dat.GUI库简化试验
Google几个人创建了一个名为dat.GUI的库,使用它,你很容易就可以创建一个简单的界面组件,用以修改代码中的变量。例如我们可以实时修改球体的弹跳速度,方块的旋转速度等等。
就像添加其他对象一样,首先需要引入dat.gui.js,接下来需要一定一个javascript对象,保存想通过dat.GUI库修改的那些变量,也可以绑定函数而调用对象函数。如定义一个controls对象:
var controls = new function(){
this.rotationSpeed = 0.02;
this.bouncingSpeed = 0.03;
}
定义了两个属性,以及设置了默认值。接下来把这个对象传递给dat.GUI对象,并定义两个属性的取值范围,如下所示:
(function(){
...
var gui = new dat.GUI();
gui.add(controls, 'rotationSpeed', 0, 0.5);
gui.add(controls, 'bouncingSpeed', 0, 0.5);
...
});
现在要做的是保证在render循环里直接饮用这两个属性。这样当我们在dat.GUI界面修改时可直接影响物体的旋转速度和弹跳速度。
function render(){
...
cube.rotation.x += controls.rotationSpeed;
cube.rotation.y += controls.rotationSpeed;
cube.rotation.z += controls.rotationSpeed;
step += controls.bouncingSpeed;
sphere.position.x = 20 + (10 * (Math.cos(step)));
sphere.position.y = 2 + (10 * Math.abs(Math.sin(step)));
...
requestAnimationFrame(render);
}
运行界面,在界面右上角可看到定义的两个属性,我们可以实时修改属性,查看界面动画效果。

7.Three.Scene常用函数和属性
scene.add(object):添加一个对象到场景对象汇总。包括Sphere、Box、Cube、Light等。
scene.remove(object):从Scene中删除一个对象
scene.getChildByName(name):通过名称获取Scene下的对象,名称可通过例如cube.name = 'cube-1'这种方式指定。
scene.children():获取场景中的所有子对象列表
scene.traverse(function(e){}):遍历scene下的子对象。我们可以通过例如e instaceof THREE.Mesh来判断类型进行过滤
scene.fog:通过该属性设置场景的雾化效果。它可以渲染出一层雾气,隐藏远处的物体
scene.overrideMaterial:通过这个属性,你可以强制场景中的所有物体使用同一个材质
8.雾化效果
three.js添加雾化效果很简单,第一种方式:
//new THREE.Fog(color, near, far)
scene.fog = new THREE.Fog(0xffffff, 0.015, 100);
包含三个参数,第一个参数color指定雾化颜色,第二个参数near指定近点位置,第三个far参数指定远点位置。第二种方式:
scene.fog = new THREE.FogExp2(0xffffff, 0.015);
这种方式不指定near和far属性,只给颜色和浓度。浓度也就是雾化因子,雾化因子也是通过near和far算出来的。
9.动态修改物体的顶点
three.js假设一个网格的几何体在其生命周期内不会改变。为了支持动态修改顶点坐标。我们需要在渲染的时候添加下面的代码:
mesh.children.forEach(function(e){
e.geometry.vertices = vertices;
e.geometry.verticesNeedUpdate = true;
e.geometry.computeFaceNormals();
});
verticesNeedUpdate属性指定顶点需要重新渲染,computeFaceNormals指定Face需要重新渲染。
10.网格Mesh常用函数和属性
position(位置)/决定该对象相对其父对象的位置。多数情况下,一个对象的父对象是THREE.Scene()对象
rotation(旋转)/通过这个属性你可以设置对象绕任何一个轴旋转弧度
scale(比例)/通过这个属性可以沿着x、y、z轴缩放对象
translateX(amout)/沿x轴将对象平移指定的距离。如果是负数则沿着x轴负方向
translateY(amout)/沿y轴将对象平移指定的举例。如果是负数则沿着y轴负方向
translateZ(amout)/沿z轴将对象平移指定的举例。如果是负数则沿着z轴负方向
11.正投影相机和透视投影相机
three.js提供了两种相机:THREE.PerspectiveCamera(透视投影相机)和THREE.OrthographicCamera(正投影相机)。首先看PerspectiveCamera构造函数new THREE.PerspectiveCamera(fov, aspect, near, far)参数:
fov/fov表示视场。这是从相机位置能够看到的部分场景。推荐默认值为45
aspect/长宽比,这是渲染结果输出区的横向长度和纵向长度的比值。默认推荐window.innerWidth/window.innerHeight。
near/近面,near属性定义的是three.js库从距离相机多斤的地方开始渲染场景。默认值推荐为0.1。
far/远面,far属性定义的而是相机可以从它所处的位置看多远。默认值推荐为1000.
正投影相机构造函数new THREE.OrthographicCamera(left, right, top, bottom, near, far)的参数:
left/左边界;right/右边界;top/上边界;bottom/下边界;near/近边界;far远边界。
创建了相机之后,我们需要指定聚集点的位置:
camera.lookAt(new THREE.Vector3(x, y, z));
12.Canvas Renderer和WebGL Renderer区别
HTML5 canvas renderer和WebGL renderer主要区别是,HTML5 canvas渲染器直接使用javascript在canvas上绘制3D场景。这种方式最主要的问题是糟糕的表现。而使用THREE.WebGLRenderer,我们可以通过硬件加速执行渲染。但THREE.CanvasRenderer对象,我们不得不完全依赖软件渲染,这导致了低性能呈现。另外一个缺点是,THREE.CanvasRenderer不能使用three.js提供的高级材质,而只有WebGL才可以使用。
Three-js 创建第一个3D场景的更多相关文章
- 第一章 用three.js创建你的第一个3D场景
第一章 用three.js创建你的第一个3D场景 到官网下载three.js的源码和示例. 创建HTML框架界面 第一个示例的代码如下: 01-basic-skeleton.html 位于 Learn ...
- 使用three.js创建大小不随着场景变化的文字
使用three.js创建大小不随着场景变化的文字,需要以下两步: 1.将文字绘制到画布上. 2.创建着色器材质,把文字放到三维场景中. 优点: 1.跟用html实现文字相比,这些文字可以被模型遮挡,更 ...
- 用 node.js 创建第一个Hello World
如果我们使用PHP来编写后端的代码时,需要Apache(xampp) 或者 Nginx 的HTTP 服务器,并配上 mod_php5 模块和php-cgi.从这个角度看,整个"接收 HTTP ...
- SceneKit一个3D场景角色的代码重构
SuperSpaceMan3D是一个以SceneKit为基础的小游戏项目,作者展示了用SceneKit开发3D游戏的强大威力.不过在实际运行时会发现有一些小bug,这里我们依次尝试将其修复 首先,当s ...
- 给js创建的一个input数组绑定click事件
<html> <body> <input type="button" name="input[]" value="按钮1 ...
- css3创建3D场景
浏览器本身是一个2维平面,对于3D的情况,实际上是增加了一个维度(深度),所以我们需要创建一个3D场景.这时浏览器不仅仅是一个平面了,更像是一个窗口,我们透过这个窗口去观察里面的三维世界.所谓的创建3 ...
- RecastNavigation(3D场景建模、网格导航)
一.RecastNavigation详解 RecastNavigation定义: RecastNavigation是一个导航寻路工具集,使用邻接的凸多边形集合描述一个3D场景,A*寻路算法使3D场景的 ...
- 基于 HTML5 WebGL 构建智能城市 3D 场景
前言 随着城市规模的扩大,传统的方式很难彻底地展示城市的全貌,但随着 3D 技术的应用,出现了 3D 城市群的方式以动态,交互式地把城市全貌呈现出来.配合智能城市系统,通过 Web 可视化的方式,使得 ...
- WPF疑难杂症之一(3D场景)
原文:WPF疑难杂症之一(3D场景) 最近2个月一直在学习WPF,在实际的开发中遇到下面一个3D场景有关的问题,我先给出问题代码:首先是在资源中定义了一个3D变换组:<Window x:Clas ...
随机推荐
- 【转】无后端(nobackend):前端优先的Web开发【译】
每个应用都由两样东西构成:该应用独有的功能和所有应用共有的功能,比方说用户注册.登录.忘记密码等.而从用户的角度出发,那些独有的功能归结起来就是用户界面以及系统的行为模式.而在视觉表象之后的功能,用户 ...
- java static class 静态类
一般情况下是不可以用static修饰类的.如果一定要用static修饰类的话,通常static修饰的是匿名内部类. 在一个类中创建另外一个类,叫做成员内部类.这个成员内部类可以静态的(利用static ...
- fiddler手机端抓包
1. 买个360随身wifi,插在台式机上生成热点,手机连上自己的wifi 如果电脑与手机本就在一个局域网,省略这一步 2. 在fiddler中如下设置: 3. 查看电脑无线连接属性 4. 在手机上设 ...
- UPNP
基本概念 UPnP 的应用范围非常大,以致足够可以实现许多现成的.新的及令人兴奋的方案,包括家庭自动化.打印.图片处理.音频 / 视频娱乐.厨房设备.汽车网络和公共集会场所的类似网络.它可以充分发挥 ...
- caffe中的错误与解决问题:
1.在使用draw_net.py的时候,提示如下错误: AttributeError: 'google.protobuf.pyext._message.RepeatedScalarConta' obj ...
- php模拟post提交数据,用处很多,可用来网站的采集,登陆等等
1. [代码][PHP]代码 <?php //以程序登陆一个论坛登录为例 function bbslogin($user_login, $password, $host, $port = &qu ...
- Unity---------Particle Effect详情
Effects:效果/特效. Particle System:粒子系统.可用于创建烟雾.气流.火焰.涟漪等效果. 在Unity3D 3.5版本之后退出了新的shuriken粒子系统: 添加组件之后 ...
- python模块之 - subprocess执行unix/linux命令
subprocess模块提供了一种一致的方法来创建和处理附加进程,与标准库中的其它模块相比,提供了一个更高级的接口,subprocess模块用来生成子进程,并可以通过管道连接它们的输入/输出/错误,以 ...
- 使用ssh-keygen和ssh-copy-id三步实现SSH无密码登录
ssh-keygen 产生公钥与私钥对. ssh-copy-id 将本机的公钥复制到远程机器的authorized_keys文件中,ssh-copy-id也能让你有到远程机器的home, ~./ss ...
- Remote SSH: Using JSCH with Expect4j
Now-a-days, we can see that whole world is moving around Clouds and virtualization. More and more ap ...