欢迎光临杨雨的个人博客站!

杨雨个人网站-杨雨个人博客-杨照佳

杨雨个人博客网站

关注互联网和搜索引擎的个人博客网站

首页 > WEB开发 > html5案例分享 >

HTML5之WebGL 3D概述(上)—WebGL原生开拓开启网页3D渲染新期间

发布时间:2016-11-29  编辑:杨雨个人博客网站   点击:   

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元素作为渲染的容器。譬喻:


代码如下:
<bodyonload="start()">
<canvasid="glcanvas"width="640"height="480">
Yourbrowserdoesn'tappeartosupporttheHTML5canvaselement.
</canvas>
</body>

下面就是正式开始写剧本的时辰了,起首看一下措施进口以及整体布局:


代码如下:
functionstart(){
varcanvas=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
这个要领的代码如下:


代码如下:
vargl;
functioninitGL(canvas){
gl=null;
try{
//Trytograbthestandardcontext.Ifitfails,fallbacktoexperimental.
gl=canvas.getContext("webgl")||canvas.getContext("experimental-webgl");
}
catch(e){} //Ifwedon'thaveaGLcontext,giveupnow
if(!gl){
alert("UnabletoinitializeWebGL.Yourbrowsermaynotsupportit.");
}
}

这个要领很简朴,就是获取WebGL的绘制情形,必要把参数"webgl"传给canvas.getContext要领就行了,可是因为今朝WebGL的尺度没有最终定型,以是尝试阶段用的参数都是"experimental-webgl"。虽然你直接去挪用canvas.getContext("experimental-webgl")也是可以的,等尺度定下往后,你再修改一个代码。

步调二:初始化着色器Shaders - initShaders
着色器Shader观念较量简朴,说白了就是显卡运算指令。结构3D场景必要举办大量的颜色、位置等等信息的计较,假如这些计较由软件执行的话,速率会很慢。以是把这些运算让显卡去计较,速率就很快;怎样去执行这些计较,就是由着色器指定的。着色器代码是用一种叫做GLSL的着色器说话编写的,这个我们不去报告这个说话了。
着色器可以在Html中界说,在代码中行使。虽然了你在措施顶用一个字符串去界说着色器也是一样的。
下面先看界说的部门:


代码如下:
<scriptid="shader-fs"type="x-shader/x-fragment">
precisionmediumpfloat;
varyingvec4vColor;
voidmain(void){
gl_FragColor=vColor;
}
</script>
<scriptid="shader-vs"type="x-shader/x-vertex">
attributevec3aVertexPosition;
attributevec4aVertexColor;
uniformmat4uMVMatrix;
uniformmat4uPMatrix;
varyingvec4vColor;
voidmain(void){
gl_Position=uPMatrix*uMVMatrix*vec4(aVertexPosition,1.0);
vColor=aVertexColor;
}
</script>

这里有两个着色器:面着色器和极点着色器。
关于这两个着色器,这里有须要声名一下,计较机中的3D模子根基都是由点团结三角面片去描写的,极点着色器就是行止理赏罚这些点的数据,而面着色器就是通过插值的方法,行止理赏罚三角面片上点的数据。
上面界说的极点着色器就界说了极点的位置和颜色计较方法;而面着色器界说了插值点的颜色计较方法。现实的应用场景中,还会涉及到在着色器中处理赏罚光泽等结果。
界说了着色器,在措施中就可以查找到它们并可以去行使:


代码如下:
varshaderProgram;
functioninitShaders(){
varfragmentShader=getShader(gl,"shader-fs");
varvertexShader=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("Couldnotinitialiseshaders");
}
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文档,查找着色器的界说,拿到界说后建设着色器,这里就不细说了:


代码如下:
functiongetShader(gl,id){
varshaderScript,theSource,currentChild,shader;
shaderScript=document.getElementById(id);
if(!shaderScript){
returnnull;
}
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);
}elseif(shaderScript.type=="x-shader/x-vertex"){
shader=gl.createShader(gl.VERTEX_SHADER);
}else{
//Unknownshadertype
returnnull;
}
gl.shaderSource(shader,theSource);
//Compiletheshaderprogram
gl.compileShader(shader);
//Seeifitcompiledsuccessfully
if(!gl.getShaderParameter(shader,gl.COMPILE_STATUS)){
alert("Anerroroccurredcompilingtheshaders:"+gl.getShaderInfoLog(shader));
returnnull;
}
returnshader;
}

步调三:建设/加载模子数据 - initBuffers
这些小例子中,模子数据根基都是直接天生的,现实的措施中,这些数据应该都是从模子加载获得的:


代码如下:
vartriangleVertexPositionBuffer;
vartriangleVertexColorBuffer;
functioninitBuffers(){
triangleVertexPositionBuffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,triangleVertexPositionBuffer);
varvertices=[
0.0,1.0,0.0,
-1.0,-1.0,0.0,
1.0,-1.0,0.0
];
gl.bufferData(gl.ARRAY_BUFFER,newFloat32Array(vertices),gl.STATIC_DRAW);
triangleVertexPositionBuffer.itemSize=3;
triangleVertexPositionBuffer.numItems=3;
triangleVertexColorBuffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,triangleVertexColorBuffer);
varcolors=[
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,newFloat32Array(colors),gl.STATIC_DRAW);
triangleVertexColorBuffer.itemSize=4;
triangleVertexColorBuffer.numItems=3;
}

上面这段代码建设了三角形的极点和极点的颜色数据并放在缓冲区中。

步调四:渲染 - drawScene
筹备好了数据往后,交给WebGL去渲染就好了,这里挪用的是gl.drawArrays要领。看代码:


代码如下:
functiondrawScene(){
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

本文地址:http://itbyc.com/web/html5/13881.html
转载请注明出处。
分享是一种快乐,也是一种美德:
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
博客首页 | WEB开发 | 网站运营 | CMS使用教程 滇ICP备14002061号-1