THREE.js 学习笔记(一)
2011-11-03 12:42
716 查看
一. 获取THREE.js
three.js的代码托管在github上面,https://github.com/mrdoob/three.js/我们可以用git来获取代码,闲麻烦的话也可以直接下载zip文件。二. 目录结构
拿到代码后先看下three.js的目录结构|-build|-custom|-Three.js|-examples|-gui|-src|-cameras|-core|-extras|-lights|-materials|-objects|-renderers|-scenes|-textures|-Three.js|-utils|-compiler|-exporters|-build.bat|-build.sh|-build.xml|-build_all.bat|-build_all.shbuild目录下是源代码连接压缩过后的js文件,而连接和压缩源代码的工具放在utils目录下,在utils目录下还有一个exporters目录,是各种模型导出工具,插件,有blender和max的导出插件,还有把fbx转成THREE.js场景文件的python脚本。examples目录下都是three.js的示例,值得一提的是,里面有很多实用的shader脚本和js脚本可以拿来在自己的项目里用,比如js/ShaderExtra.js提供了很多现成的shader代码,js/postprocessing下提供了封装起来的几种常用的后处理的接口gui下面是一些封装后的ui接口src当然就是重头戏了,three.js的源代码都在这个目录下,src里下的各个子目录也很好的体现了three.js的构成,像camera,light,object这些都是一个场景(scene)的基础对象,而scenes下面则是对整个场景的管理代码,像scene graph的实现,renderers下是核心渲染器的实现,three.js对于场景和渲染器分离的还不错,可以用不同的renderer渲染同一个场景,当然对于一些WebGL支持的高级特性,使用其它的renderer肯定是不行的。还有一个extras目录是在核心代码之上的一些未程序提供便利的接口,比如提供了一些常用的camera,material,light。utils目录上面已提过三. example分析 - webgl trackballcamera earth
examples目录下有该示例在这个example里我们能够看到:一个最基本的three.js应用需要有的东西camera的创建以及camera control的添加基本形体的创建,材质的创建粒子系统的创建,这个会后面讲。这里不会逐行逐行代码的分析,而是对于每个特性挑出代码来讲。一个three.js应用的基本结构。不管用什么写3d应用,c++的ogre,flash的pv3d,js的o3d,又或者使用场景编辑器,一个3d场景所需要的最基本的东西都是一样的,一个主要的camera,一个主要的scene。当然一般的场景里都会有物体,有灯光,每个物体都有材质。我们在three.js中可以一个个手动创建,也可以直接加载一个记录场景数据的json文件。创建一个scene
scene = new THREE.Scene();创建一个摄像机
这段代码确定了一个摄像机的视锥,四个参数分别是摄像机的视锥角度,视口的长宽比,摄像机的近切面(Front Clipping Plane)和远切面(Back Clipping Plane),为什么要四个参数?其实摄像机本质上就是一个投影矩阵,而建立一个透视投影的矩阵(还有正交投影)需要这四个参数,形象点可以看下图camera = new THREE.PerspectiveCamera( 25, width / height, 50, 1e7 ); camera.position.z = radius * 7;
从图中可以看到,要唯一确定一个透视的视锥(Viewing Frustum)至少需要上述的四个参数。调整摄像机的位置和朝向创建一个摄像机还需要摆好这个摄像机的位置和朝向,three.js里可以用camera.lookAt函数来设置摄像机的朝向,用camera.position设置摄像机的位置这个demo里由于创建了一个实现轨迹球控制效果的TrackballControls,因此camera的变换都被封装在这里面了。如果看lookAt的代码,其实这些操作都是矩阵的操作,摄像机本质上和一个场景中的实体无异,都是使用变换矩阵来做变换。下面要为场景中添加一些东西了我们可以在演示中大概看到这个场景中有一个地球,一个月球,周围的太空,还有一个一直照着地球模拟太阳的光照,如果看得仔细点,我们还会发现其实地球外面还包着一层大气层。下面要一一在场景中添加进入这些东西1. 首先是地球在WebGL里创建一个object,我们需要的最基本的数据就是这个object的顶点位置,当然,如果需要这个物体能够入眼的话,我们还需要为它编写shader,需要传入顶点的法线数据,需要传入texcoord来完成纹理映射。说到shader,我们先看下WebGL中渲染一个物体的基本顺序:程序会先载入,编译和绑定shader代码,每个渲染批次,显卡都会将这些顶点数据传入流水线,在流水线中会通过Vertex Shader进行顶点位置的变换,光栅化,Fragment Shader中对每个像素计算颜色,最后深度测试等等后输出到屏幕。THREE.js中将物体顶点数据的管理封装成为geometry接口,将shader和shader中参数的管理封装成为material接口,每次编译加载绑定shader,传入顶点数据都会在WebGLRenderer中统一处理。
var materialNormalMap = new THREE.ShaderMaterial({ fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true });这里便是创建了一个材质,传入了fragmentShader和vertexShader的代码,uniforms是这两个shader里的参数。这两个都是可以拿来主义的
var shader = THREE.ShaderUtils.lib[ "normal" ], uniforms = THREE.UniformsUtils.clone( shader.uniforms ); uniforms[ "tNormal" ].texture = normalTexture; uniforms[ "uNormalScale" ].value = 0.85; uniforms[ "tDiffuse" ].texture = planetTexture; uniforms[ "tSpecular" ].texture = specularTexture; uniforms[ "enableAO" ].value = false; uniforms[ "enableDiffuse" ].value = true; uniforms[ "enableSpecular" ].value = true; uniforms[ "uDiffuseColor" ].value.setHex( 0xffffff ); uniforms[ "uSpecularColor" ].value.setHex( 0x333333 ); uniforms[ "uAmbientColor" ].value.setHex( 0x000000 ); uniforms[ "uShininess" ].value = 15;
于是这里创建了一个法线贴图的材质(关于法线贴图的原理,这里先不多讲),并且设置好了它的各个参数,其中tNnormal是法线纹理,tDiffuse是漫反射纹理,tSpecular是高光纹理,
tDiffuse,tSpecular和tNormaluDiffuseColor, uSpecularColor, uAmbientColor, uShininess这四个是Phong模型光照的参数,uDiffuseColor:漫反射颜色uSpecularColor:高光颜色uAmbientColor:环境光颜色uShininess:物体表面光滑度下面这段便是创建这个地球本身了,并且加入到场景里面
geometry = new THREE.SphereGeometry( radius, 100, 50 ); geometry.computeTangents(); meshPlanet = new THREE.Mesh( geometry, materialNormalMap ); meshPlanet.rotation.y = 1.3; meshPlanet.rotation.z = tilt; scene.add( meshPlanet );最后看一下这个添加到scene里的Mesh的组成图
2. 建月球和云层也是依法炮制,云层因为是png格式所以有半透明效果。3. 创建平行光创建一个光照是很简单的,tree.js的灯光对象主要就是保存灯光参数的作用,而光照的实际计算是放在shader里,我们暂时不用关心
dirLight = new THREE.DirectionalLight( 0xFFFFFF ); dirLight.position.set( -1, 0, 1 ).normalize(); scene.add( dirLight );场景的互动sample中我们可以使用鼠标控制摄像机的旋转,three.js为我们提供一些常用的摄像机控制接口,这个sample里用的是轨迹球
controls = new THREE.TrackballControls( camera, renderer.domElement );我们可以在src/extras/controls下面看到几个常用的摄像机控制渲染我们最后来看看render函数里的代码
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.2;controls.noZoom = false;
controls.noPan = false;controls.staticMoving = false;
controls.dynamicDampingFactor = 0.3;controls.minDistance = radius * 1.1;
controls.maxDistance = radius * 100;
var t = new Date().getTime(),这个函数主要做了每一帧都要做的几件事:计算这一帧的时间旋转地球计算月球位置更新摄像机控制渲染最后render函数里需要两个参数,scene和camera,我们如果看下render里的代码话就可以知道,每次render的时候,都需要遍历一遍scene graph,渲染里面每个需要渲染的对象,而摄像机的作用就只是提供一个视角变换矩阵和投影矩阵。这个以后看WebGLRenderer里的代码的时候会继续深入。这个函数会使用setInterval定时调用,来实现动画的效果。
dt = ( t - time ) / 1000;
time = t;meshPlanet.rotation.y += rotationSpeed * dt;
meshClouds.rotation.y += 1.25 * rotationSpeed * dt;var angle = dt * rotationSpeed;meshMoon.position = new THREE.Vector3(
Math.cos( angle ) * meshMoon.position.x - Math.sin( angle ) * meshMoon.position.z,
0,
Math.sin( angle ) * meshMoon.position.x + Math.cos( angle ) * meshMoon.position.z
);
meshMoon.rotation.y -= angle;controls.update();renderer.clear();
renderer.render( scene, camera );
相关文章推荐
- Three.js学习笔记 – “我和小伙伴都惊呆了”的特效和Three.js初探
- three.js学习笔记 obj模型加载问题
- Three.js学习笔记 – “我和小伙伴都惊呆了”的特效和Three.js初探
- Three.js学习笔记---我和小伙伴都惊呆了
- three.js 学习笔记之 混乱的矩阵
- three.js学习笔记(二)-基础知识①
- three.js学习笔记 为模型增添物理效果
- three.js学习笔记 用Tween.js做动画
- webgl+three.js,学习笔记,画一个立方体+解析
- THREE.js 学习笔记(前记)
- Three.js 学习笔记(1)--坐标体系和旋转
- three.js学习笔记 相机控件
- Three.js学习笔记 – “我和小伙伴都惊呆了”的特效和Three.js初探(转)
- three.js学习笔记 基础1_1
- three.js学习笔记 基于物理引擎的第一人称控件
- Three.js学习笔记——3dsmax 加载obj模型
- three.js学习笔记 dat.gui.js和stats.js
- Three.js editor 学习笔记(一)
- Three.js学习笔记04--纹理
- three.js学习笔记 光和影