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场景的更多相关文章

  1. 第一章 用three.js创建你的第一个3D场景

    第一章 用three.js创建你的第一个3D场景 到官网下载three.js的源码和示例. 创建HTML框架界面 第一个示例的代码如下: 01-basic-skeleton.html 位于 Learn ...

  2. 使用three.js创建大小不随着场景变化的文字

    使用three.js创建大小不随着场景变化的文字,需要以下两步: 1.将文字绘制到画布上. 2.创建着色器材质,把文字放到三维场景中. 优点: 1.跟用html实现文字相比,这些文字可以被模型遮挡,更 ...

  3. 用 node.js 创建第一个Hello World

    如果我们使用PHP来编写后端的代码时,需要Apache(xampp) 或者 Nginx 的HTTP 服务器,并配上 mod_php5 模块和php-cgi.从这个角度看,整个"接收 HTTP ...

  4. SceneKit一个3D场景角色的代码重构

    SuperSpaceMan3D是一个以SceneKit为基础的小游戏项目,作者展示了用SceneKit开发3D游戏的强大威力.不过在实际运行时会发现有一些小bug,这里我们依次尝试将其修复 首先,当s ...

  5. 给js创建的一个input数组绑定click事件

    <html> <body> <input type="button" name="input[]" value="按钮1 ...

  6. css3创建3D场景

    浏览器本身是一个2维平面,对于3D的情况,实际上是增加了一个维度(深度),所以我们需要创建一个3D场景.这时浏览器不仅仅是一个平面了,更像是一个窗口,我们透过这个窗口去观察里面的三维世界.所谓的创建3 ...

  7. RecastNavigation(3D场景建模、网格导航)

    一.RecastNavigation详解 RecastNavigation定义: RecastNavigation是一个导航寻路工具集,使用邻接的凸多边形集合描述一个3D场景,A*寻路算法使3D场景的 ...

  8. 基于 HTML5 WebGL 构建智能城市 3D 场景

    前言 随着城市规模的扩大,传统的方式很难彻底地展示城市的全貌,但随着 3D 技术的应用,出现了 3D 城市群的方式以动态,交互式地把城市全貌呈现出来.配合智能城市系统,通过 Web 可视化的方式,使得 ...

  9. WPF疑难杂症之一(3D场景)

    原文:WPF疑难杂症之一(3D场景) 最近2个月一直在学习WPF,在实际的开发中遇到下面一个3D场景有关的问题,我先给出问题代码:首先是在资源中定义了一个3D变换组:<Window x:Clas ...

随机推荐

  1. IIS时间格式设置

    IIS时间格式调整: (已解决)今天在用IIS7的时候发现一个关于时间格式的问题,当我在ASP中使用now()时间函数的时候,日期是以“/”来分隔,而不是以“-”来分隔的,使得我在运行程序的时候老出错 ...

  2. [lsof]lsof查看哪些设备/文件被占用或者打开

    转自:http://blog.csdn.net/yuzhihui_no1/article/details/51767516 最近在查一个Bug,应用程序kill之后重启,总是会出现adc的设备open ...

  3. pthread_cond_wait和pthread_cond_signal以及互斥变量的使用情况

    #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h& ...

  4. android开发(38) 使用 DrawerLayou t实现左侧抽屉式导航菜单

    最近流行 左侧抽屉式的导航条菜单,知乎,360,QQ都使用了这样的导航菜单,我们也了解下: Android Design 的流行趋势:Navigation Drawer 导航抽屉 参考这篇文章:htt ...

  5. 根据时间获取最新数据 SQL(每一个人或者每一项)

    -- 方法1 select a.* from table1 a from table1 b where b.name=a.name and b.gdtime>a.gdtime) -- 方法2 s ...

  6. 用stringr包处理字符串

    <Machine Learning for Hackers>一书的合著者John Myles White近日接受了一个访谈.在访谈中他提到了自己在R中常用的几个扩展包,其中包括用ggplo ...

  7. C++复合类型(结构体)

    其实c++的结构体可以理解为类似于python的字典,我个人理解, 但有区别 先看结构 #include <iostream> 关键字 标记成为新类型的名称 struct inflatab ...

  8. SAP 金税接口代码 供参考

    程序可以通过抓取 客户 开票信息等 下载文本 导出 需要事先创建好几个structure zc0000sdt0016, zc0000sdt0017 REPORT zc0000sdr0016 NO ST ...

  9. CI框架 -- 附属类

    有些时候,你可能想在你的控制器之外新建一些类,但同时又希望 这些类还能访问 CodeIgniter 的资源 任何在你的控制器方法中初始化的类都可以简单的通过 get_instance() 函数来访问 ...

  10. ubuntu -- 安装最新版的nodejs

    1.安装最新的nodejs和npm # apt-get update # apt-get install -y python-software-properties software-properti ...