http://www.cnblogs.com/dxy1982/archive/2012/08/01/2609582.html
WebGL开启了网页3D渲染的新时代,它允许在canvas中直接渲染3D的内容,而不借助任何插件。WebGL同canvas 2D的API一样,都是通过脚本操纵对象,所以步骤也是基本相似:准备工作上下文,准备数据,在canvas中绘制对象并渲染。与2D不同的就是3D涉及的知识更多了,例如世界、光线、纹理、相机、矩阵等专业知识。WebGL有一个很好的中文教程,就是下面使用参考中的第一个链接,所以这里不再班门弄斧,后面的内容只是简单的总结一下学习的内容。
浏览器的支持
由于微软有自己的图形发展计划,一直不支持WebGL,所以IE目前除了安装插件外,是无法运行WebGL的。其他的主流浏览器如Chrome、FireFox、Safari、Opera等,都装上最新的版本就可以了。除了浏览器要装最新的外,还要保证显卡的驱动也是最新的。
装上这些以后,可以打开浏览器,输入下面的网址验证一下浏览器对WebGL的支持情况:http://webglreport.sourceforge.net/。
在正常安装以上浏览器之后还是不能运行WebGL,那你可以强制开启WebGL支持试一试。开启方法如下:
Chrome浏览器
我们需要为Chrome加入一些启动参数,以下具体操作步骤以Windows操作系统为例:找到Chrome浏览器的快捷方式,右键点击快捷方式,选择属性;在目标框内,chrome.exe后面的引号后面,加入以下内容:
--enable-webgl --ignore-gpu-blacklist --allow-file-access-from-files
点击确定后关闭Chrome,然后用此快捷方式启动Chrome浏览器。
几个参数的含义如下:
--enable-webgl的意思是开启WebGL支持;
--ignore-gpu-blacklist的意思是忽略GPU黑名单,也就是说有一些显卡GPU因为过于陈旧等原因,不建议运行WebGL,这个参数可以让浏览器忽略这个黑名单,强制运行WebGL;
--allow-file-access-from-files的意思是允许从本地载入资源,如果你不是WebGL的开发者,不需要开发调试WebGL,只是想要看一下WebGL的Demo,那你可以不添加这个参数。
Firefox浏览器
Firefox的用户请在浏览器的地址栏输入“about:config”,回车,然后在过滤器(filter)中搜索“webgl”,将webgl.force-enabled设置为true;将webgl.disabled设置为false;在过滤器(filter)中搜索“security.fileuri.strict_origin_policy”,将security.fileuri.strict_origin_policy设置为false;然后关闭目前开启的所有Firefox窗口,重新启动Firefox。
前两个设置是强制开启WebGL支持,最后一个security.fileuri.strict_origin_policy的设置是允许从本地载入资源,如果你不是WebGL的开发者,不需要开发调试WebGL,只是想要看一下WebGL的Demo,那你可以不设置此项。
Safari浏览器
在菜单中找到“属性”→“高级”,选中“显示开发菜单”,然后到“开发”菜单,选中“开启WebGL”。
开发步骤
下面的代码只是简单总结一下相关的概念,它来源于参考中的中文教程,涉及较多的3D方面的知识。感兴趣的同学直接可以跳到实用参考中的中文教程中学习,比我这里讲解的要详细和准确的多。凑热闹的同学简单看看就可以了,不用深究每一行代码的含义。
准备工作
这个不用说了,就是在页面上添加一个canvas元素作为渲染的容器。例如:
<body onload="start()">
<canvas id="glcanvas" width="640" height="480">
Your browser doesn't appear to support the HTML5 canvas element.
</canvas>
</body>
下面就是正式开始写脚本的时候了,首先看一下程序入口以及整体结构:
function start() {
var canvas = document.getElementById("glcanvas");
initGL(canvas);
initShaders();
initBuffers();
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.enable(gl.DEPTH_TEST);
drawScene();
}
这里的几个方法代表了典型的WebGL的绘制步骤:
步骤一:初始化WebGL工作环境 - initGL
这个方法的代码如下:
var gl;
function initGL(canvas) {
gl=null;
try {
// Try to grab the standard context. If it fails, fallback to experimental.
gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
}
catch(e) {}
// If we don't have a GL context, give up now
if (!gl) {
alert("Unable to initialize WebGL. Your browser may not support it.");
}
}
这个方法很简单,就是获取WebGL的绘制环境,需要把参数"webgl"传给canvas.getContext方法就行了,但是由于目前WebGL的标准没有最终定型,所以实验阶段用的参数都是"experimental-webgl"。当然你直接去调用canvas.getContext("experimental-webgl")也是可以的,等标准定下以后,你再修改一个代码。
步骤二:初始化着色器Shaders - initShaders
着色器Shader概念比较简单,说白了就是显卡运算指令。构造3D场景需要进行大量的颜色、位置等等信息的计算,如果这些计算由软件执行的话,速度会很慢。所以把这些运算让显卡去计算,速度就很快;如何去执行这些计算,就是由着色器指定的。着色器代码是用一种叫做GLSL的着色器语言编写的,这个我们不去讲述这个语言了。
着色器可以在html中定义,在代码中使用。当然了你在程序中用一个字符串去定义着色器也是一样的。
下面先看定义的部分:
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec4 vColor;
void main(void) {
gl_FragColor = vColor;
}
</script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec4 aVertexColor;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
varying vec4 vColor;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vColor = aVertexColor;
}
</script>
这里有两个着色器:面着色器和顶点着色器。
关于这两个着色器,这里有必要说明一下,计算机中的3D模型基本都是由点结合三角面片去描述的,顶点着色器就是去处理这些点的数据,而面着色器就是通过插值的方式,去处理三角面片上点的数据。
上面定义的顶点着色器就定义了顶点的位置和颜色计算方式;而面着色器定义了插值点的颜色计算方式。实际的应用场景中,还会涉及到在着色器中处理光线等效果。
定义了着色器,在程序中就可以查找到它们并可以去使用:
var shaderProgram;
function initShaders() {
var fragmentShader = getShader(gl, "shader-fs");
var vertexShader = getShader(gl, "shader-vs");
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Could not initialise shaders");
}
gl.useProgram(shaderProgram);
shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
shaderProgram.vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor");
gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute);
shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
}
着色器是有了,但是怎么让显卡去执行,Program就是这种桥梁,它是WebGL原生的二进制码,它的作用基本上就是让显卡运行着色器代码去渲染指定的模型数据。
这里还用到一个辅助方法getShader,这个方法就是遍历html文档,查找着色器的定义,拿到定义后创建着色器,这里就不细说了:
function getShader(gl, id) {
var shaderScript, theSource, currentChild, shader;
shaderScript = document.getElementById(id);
if (!shaderScript) {
return null;
}
theSource = "";
currentChild = shaderScript.firstChild;
while(currentChild) {
if (currentChild.nodeType == currentChild.TEXT_NODE) {
theSource += currentChild.textContent;
}
currentChild = currentChild.nextSibling;
}
if (shaderScript.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (shaderScript.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
// Unknown shader type
return null;
}
gl.shaderSource(shader, theSource);
// Compile the shader program
gl.compileShader(shader);
// See if it compiled successfully
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert("An error occurred compiling the shaders: " + gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
步骤三:创建/加载模型数据 - initBuffers
这些小例子中,模型数据基本都是直接生成的,实际的程序中,这些数据应该都是从模型加载得到的:
var triangleVertexPositionBuffer;
var triangleVertexColorBuffer;
function initBuffers() {
triangleVertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
var vertices = [
0.0, 1.0, 0.0,
-1.0, -1.0, 0.0,
1.0, -1.0, 0.0
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
triangleVertexPositionBuffer.itemSize = 3;
triangleVertexPositionBuffer.numItems = 3;
triangleVertexColorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexColorBuffer);
var colors = [
1.0, 0.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
0.0, 0.0, 1.0, 1.0
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
triangleVertexColorBuffer.itemSize = 4;
triangleVertexColorBuffer.numItems = 3;
}
上面这段代码创建了三角形的顶点和顶点的颜色数据并放在缓冲区中。
步骤四:渲染 - drawScene
准备好了数据以后,交给WebGL去渲染就好了,这里调用的是gl.drawArrays方法。看代码:
function drawScene() {
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
pMatrix = okMat4Proj(45.0, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0);
mvMatrix = okMat4Trans(-1.5, 0.0, -7.0);
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, triangleVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexColorBuffer);
gl.vertexAttribPointer(shaderProgram.vertexColorAttribute, triangleVertexColorBuffer.itemSize, gl.FLOAT, false, 0, 0);
setMatrixUniforms();
gl.drawArrays(gl.TRIANGLES, 0, triangleVertexPositionBuffer.numItems);
}
这个函数首先设置了3D世界的背景为黑色,然后设置投影矩阵,设置待绘制对象的位置,然后根据缓冲中的顶点和颜色数据,绘制对象。这里还有一些生成投影矩阵和模型视图矩形的辅助方法(使用了Oak3D图形库中的矩阵辅助方法)与主题关系不大,这里就不详细解释了。
基本上流程就是这么多了,更复杂的纹理,光线等都是在这些基础上加入一些WegGL的特性实现的,这个请参看后面的中文教程,里面有详细的例子。
怎么样?使用原生的WebGL开发是一种什么感受?不仅需要有深厚的3D知识,还需要知道各种实现细节。WebGL这样做是为了灵活的适应各种应用场景,但是对于大多数像我这样非专业人士来说,很多细节是不需要知道的。这样就催生了各种辅助开发的类库,例如这节用到的Oak3D库(为了演示WebGL开发,例子中只用到了矩阵辅助方法)。下一节会介绍一个用的比较多的Three.js图形库。
实用参考:
中文教程:http://www.hiwebgl.com/?p=42
开发中心:https://developer.mozilla.org/en/WebGL
前面我们看到了使用原生的WebGL API开发是多么的累,正因为如此,大量的WebGL框架被开发出来。使用这些框架,你可以快速创建需要的3D场景。这些框架不同程度的封装了创建3D场景的各种要素,例如场景,相机、模型、光照、材质等等;使用这些封装起来的对象,就可以很简单的创建需要的3D场景,这样你就只需要把更多精力放在逻辑方面就可以了。
目前并没有哪一个具有能压倒其他框架的优势,选择什么样的框,还是看个人喜好吧,不过选择框架的时候,个人觉得还是多看看框架最后的更新时间,选择稳定更新的框架能让你始终能使用上最新的特性,使你的程序稳定性更好。
下面的例子就使用了Three.js框架进行开发。
Three.js是一个比较全面的开源框架,它良好的封装的3D场景的各种要素。你可以用它来很容易的去创建摄像机,模型,光照,材质等等。你还可以选择不同的渲染器,Three.js提供了多种渲染方式,你可以选择使用canvas来渲染,也可以使用WebGL或者SVG来进行渲染。
此外,Three.js可以加载很多格式的3D文件,你的模型文件可以来自Blender,Maya,Chinema4D,3DMax等等。而且内置了比较基础的东西:(球体)Spheres, (飞机)Planes, (立方体) Cubes, (圆柱体)Cylinders。Three.js创建这些物体会非常的容易。
好了,不废话了,直接看代码:
<!DOCTYPE html>
<html>
<head>
<title>threeJSDemo </title>
<meta charset="utf-8">
<style>
body
{
margin:0px;
background-color:#B0B0B0;
overload:hidden;
}
</style>
</head>
<body>
<script src="Three.js"></script>
<script>
var camera,scene,renderer;
var mesh;
init();
animate();
function init(){
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(70,window.innerWidth / window.innerHeight,1,1000);
camera.position.z = 400;
scene.add(camera);
geometry = new THREE.CubeGeometry(200,200,200);
material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );
mesh = new THREE.Mesh(geometry,material);
scene.add(mesh);
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth,window.innerHeight);
document.body.appendChild(renderer.domElement);
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.x += 0.05;
mesh.rotation.y += 0.05;
renderer.render( scene, camera );
}
</script>
</body>
</html>
这个是全部的代码,相对于前面使用WebGL的API的代码,这个简直就是太简单了。
代码很直观,就那么几步:
1. 创建场景scene。
2. 创建摄像机camera。
3. 创建/加载模型geometry。
4. 加载材质material。
5. 渲染模型对象mesh(是由geometry和material组成)。
6. 启用动画。
这是每个框架都提供的功能,使用不同的框架除了函数的名称可能不同以外,这些步骤基本都是一样的。下面的参考中列出了很多的框架学习文档,大家可以选几种学习一下。
针对模型数据,我还想说一点,因为JSON短小精悍,所以比较适合网络传输。未来它可能成为最适合WebGL的模型数据格式,所以很多的框架都开始支持JSON格式的模型数据。
实用参考:
开发中心:https://developer.mozilla.org/en/WebGL
精品在线开发工具:http://webglplayground.net/
各种框架基础教程:http://www.html5china.com/HTML5features/WebGL/
WebGL中文教程:http://www.hiwebgl.com/?p=42
Oak3D中文教程:http://www.hiwebgl.com/?cat=57
CubicVR3D官网: http://www.cubicvr.org/
Three.js图形库: https://github.com/mrdoob/three.js
各种框架的收集贴:http://www.appcrews.com/2011/07/129.html
分享到:
相关推荐
综上所述,Web3D简模的制作涉及3D建模、纹理和材质应用、模型导出、选择合适的Web3D框架、编程实现以及最终的部署和测试。这是一个融合艺术和技术的过程,需要对3D设计和Web开发都有一定的理解和技能。通过学习和...
然后,Web3D技术的实现通常需要结合各种框架和库。例如,Three.js是目前最流行的WebGL库,它提供了许多方便的函数和对象,简化了Web3D开发的复杂性。A-Frame则是一个基于HTML的VR框架,通过简单的HTML标签就可以创建...
《基于Three.js的3D框架:ThreeQuery深度解析》 Three.js是JavaScript中广泛使用的开源库,用于在Web浏览器中创建交互式的3D图形。它为开发者提供了丰富的API,简化了WebGL编程的复杂性,使得3D内容的创建变得更加...
Web3D技术是一种在网页上实现三维图形展示的技术,它允许用户通过浏览器体验交互式的三维内容,无需安装额外的插件或软件。Web3D技术的发展显著提升了网页的视觉效果和用户体验,尤其在游戏、虚拟现实、产品展示等...
标题 "6个顶级时尚的Web前端3D效果源码(六)" 提示我们这是一个关于Web前端开发的资源,特别是涉及到3D效果的实现。3D效果在现代网页设计中非常流行,它们能够为用户提供更加生动、立体的交互体验。在这一系列的...
标题中的“多个完全基于FLEX的WEB3D引擎例子源码及教程”表明这是一个关于使用Adobe Flex技术构建Web3D引擎的资源集合。Flex是一种开源的、基于ActionScript的框架,用于开发富互联网应用程序(RIA),它允许开发者...
在探讨Web App开发框架之前,我们首先回顾一下计算机应用程序与语言的发展历程,这将有助于我们更好地理解当前Web App开发框架的背景与趋势。 ### 计算机应用程序发展历程 计算机应用程序的发展经历了从大型机到...
本资料包“完全基于FLEX的WEB3D引擎例子源码及教程”正是针对这一领域的一份宝贵学习资源,旨在帮助开发者掌握如何利用Adobe Flex框架构建高效的Web3D应用。 Adobe Flex是一种用于创建富互联网应用程序(RIA)的...
【标题】"web_张学友3D播放器示例代码"揭示了这个项目的核心内容,即一个基于Web技术的3D播放器,用于展示张学友相关的3D内容。在Web开发领域,3D播放器是利用HTML5、CSS3和JavaScript等技术实现的一种可以在浏览器...
一款GIS软件框架cityDB,基于WEBGL技术体系,也是一种开源的城市GIS应用框架,源于德国慕尼黑大学的研究成果,通过Ctiydb地图客户端调研docker的镜像
WebGL是一种基于OpenGL标准的、在Web上运行的图形库,它使得开发者可以直接在浏览器中创建复杂的3D场景。在本项目中,通过WebGL,开发者能够利用GPU的硬件加速功能,高效地处理复杂的3D图形计算,提高渲染性能,使得...
此外,熟悉相关的库和框架(如Three.js、A-Frame等)也是必不可少的,它们能简化Web3D应用的开发过程。 总之,Web3D技术是互联网发展的前沿领域,它将3D图形的视觉冲击力与Web的便捷性相结合,为用户带来了全新的...
在详细解析这份关于“基于ArcGIS的Web3D应用开发全流程入门”的内容之前,需要明确几个核心概念:Web3D、ArcGIS以及Esri。 Web3D是网络三维图形技术的简称,它允许在网页上直接展示三维内容,为用户提供沉浸式的...
Cornerstone 是一个开源的Web PACS(Picture Archiving and Communication System)框架,专门用于医学影像的展示、处理和分析。这个框架的核心是提供强大的图像渲染和交互功能,使得开发人员可以构建高性能的医学...
5. 动画与交互:Three.js提供动画框架和事件监听,使3D物体可以动态移动、旋转,同时支持用户交互。 三、项目源代码学习路径 1. lj源码.rar:这是一个具体项目的源代码,包含了Three.js实现3D场景的所有文件,包括...
three.js是一个开源的JavaScript库,它为开发者提供了一套完整的框架来利用WebGL API创建3D场景。WebGL是一种基于OpenGL标准的JavaScript API,能够在浏览器中直接渲染3D图形。由于WebGL的复杂性,three.js通过封装...
项目文件包括网页界面、注册流程、数据库结构、说明文档、3D相关资源以及样式和图片资源,体现了项目的基本框架。对于有兴趣参与Web开发,尤其是3D技术应用的开发者来说,这是一个很好的实践和学习机会。
### AR(增强现实)框架支持Unity3D游戏引擎2 #### 知识点一:AR技术与Unity3D集成 **增强现实(AR)**是一种技术,它将虚拟信息叠加到用户的真实世界视图上,从而增强用户体验。AR在游戏、教育、营销等多个领域都...
Vizi框架是这个3D机房项目的基础,它是一个专门用于Web端3D图形渲染的库。Vizi框架利用 WebGL 技术,这是一种基于OpenGL标准的JavaScript API,允许在浏览器中进行硬件加速的3D图形渲染。WebGL使得开发者无需安装...