Webgl笔记

1. webgl简介:

WebGL(全写Web Graphics Library)是一种3D绘图协议,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。显然,WebGL技术标准免去了开发网页专用渲染插件的麻烦,可被用于创建具有复杂3D结构的网站页面,甚至可以用来设计3D网页游戏等等。

WebGL和3D图形规范OpenGL、通用计算规范OpenCL一样来自Khronos Group,而且免费开放,并于2010年上半年完成并公开发布。Adobe Flash Player 11、微软Silverlight 3.0也都已经支持GPU加速,但它们都是私有的、不透明的。WebGL标准工作组的成员包括AMD,爱立信,谷歌,Mozilla,Nvidia以及Opera等,这些成员会与Khronos公司通力合作,创建一种多平台环境可用的WebGL标准,WebGL标准在2011年上半年首度公开发布,该标准完全免费对外提供。

WebGL完美地解决了现有的Web交互式三维动画的两个问题:第一,它通过HTML脚本本身实现Web交互式三维动画的制作,无需任何浏览器插件支持;第二,它利用底层的图形硬件加速功能进行的图形渲染,是通过统一的、标准的、跨平台的OpenGL接口实现的。

2. 工具three.js, WebStorm

什么是threejs,很简单,你将它理解成three + js就可以了。three表示3D的意思,js表示javascript的意思。那么合起来,three.js就是使用javascript 来写3D程序的意思。

地址是: https://github.com/mrdoob/three.js

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

3.使用three.js,一个例子

three.js有3个库three.js、three.min.js、three.module.js

一般使用第一个,这是个完整版的。

hree.js使用面向对象的方式来构建程序,包含3个基本对象: 场景(scene), 相机(camera), 以及一个渲染器(renderer)。

Three.js的架构支持多种camera,这里使用最常见的远景相机(PerspectiveCamera),也就是类似于人眼观察的方式。第一个属性75设置的是视角(field of view);第二个属性设置的是相机拍摄面的长宽比(aspect ratio),我们几乎总是会使用元素的宽除以高,否则会出现挤压变形;接下来的2个属性是近裁剪面(near clipping plane) 和 远裁剪面(far clipping plane)。

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 );
document.body.appendChild( renderer.domElement );

渲染器,使用的WebGLRenderer,three.js还支持一些其它渲染器,基本上只是用来回退处理那些不支持WebGL的旧式用户浏览器。

除了创建renderer实例,我们还需要设置渲染空间的尺寸,一般就使用目标屏幕的宽高(window.innerWidth和window.innerHeight),也可以给定一个小尺寸。 如果你想保持渲染空间的尺寸,但使用一个较低的分辨率,你可以在调用setSize的时候设置参数updateStyle为false,比如 setSize(window.innerWidth/2, window.innerHeight/2, false) 将使用1/2分辨率来绘制你的应用程序,假定<canvas>为100%的宽高。

最后,我们把 renderer 元素添加到HTML文档中。这里是一个 <canvas> 元素,渲染器用来显示场景。

对象:Plane\Cube\Sphere\Camera\Axes

  1. 创建一个HTML
  2. 写代码
  3. 在浏览器中打开
	<html>
		<head>
			<title>My first Three.js app</title>
			<style>
				body { margin: 0; }
				canvas { width: 100%; height: 100% }
			</style>
		</head>
		<body>
			<script src="//wow.techbrood.com/libs/three.r73.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 );
				document.body.appendChild( renderer.domElement );

				var geometry = new THREE.BoxGeometry( 1, 1, 1 );
				var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
				var cube = new THREE.Mesh( geometry, material );
				scene.add( cube );
	
				camera.position.z = 5;
	
				var render = function () {
					requestAnimationFrame( render );
	
					cube.rotation.x += 0.1;
					cube.rotation.y += 0.1;
	
					renderer.render(scene, camera);
				};
	
				render();
			</script>
		</body>
	</html>

4.HTML5 Boilerplate

HTML5 Boilerplate只是一个单纯的HTML模版。兼容很多浏览器,使用方便。

5.坐标与矩阵变换

向右X,向上Y。

Three.js 使用 matrices 来编码3D变换—位置平移(translations),旋转(rotations)和缩放(scaling)。每个 3D对象(Object3D) 有一个 matrix 用来保存该对象的位置、旋转和缩放因子。

有两个方法来完成对象的矩阵变换:

  1. 修改对象的 位置(position), 四元数(quaternion), 和缩放(scale) 属性,然后交由Three.js来根据这些属性重新计算对象矩阵:
object.position.copy(start_position);
object.quaternion.copy(quaternion); 

缺省情况下,matrixAutoUpdate 属性被设置为 true,这样矩阵将会被自动重新计算。 如果对象是静止的,或者你想手动控制计算过程来获得更好的性能,你可以设置该属性为false: object.matrixAutoUpdate = false; 在修改对象属性后,手动更新矩阵: object.updateMatrix();

  1. 直接修改对象的矩阵。Matrix4 类有多个方法用来修改矩阵:
object.matrix.setRotationFromQuaternion(quaternion);
object.matrix.setPosition(start_position);
object.matrixAutoUpdate = false;

注意,在这种情况下,matrixAutoUpdate 必须 被设置为 false,并且你应该要确保 不去 调用 updateMatrix。 否则手动修改会被自动计算所覆盖。

对象和世界矩阵(Object and world matrices)

对象的矩阵属性(matrix)保存了该对象相对于其父对象 parent 的变换,要获取世界坐标的变换,你必须访问对象的世界矩阵属性(3D对象(Object3D).matrixWorld)。

当父对象或子对象发生变换时,你可以通过调用请求子对象的 updateMatrixWorld 方法来更新 matrixWorld 属性。

参考:

  1. my coding.net
  2. 定义
  3. WebGL
  4. http://www.hewebgl.com/article/getarticle/27
  5. http://techbrood.com/threejs/docs/#使用指南/入门介绍/创建一个场景(Scene)