WebGL学习第一天(上)

首先了解什么是WebGL

WebGL 是一种 3D 绘图标准,这种绘图技术标准允许把 JavaScript 和 OpenGL ES 2.0 结合在一起,通过增加 OpenGL ES 2.0 的一个 JavaScript 绑定,WebGL 可以为 HTML5 Canvas 提供硬件 3D 加速渲染,这样 Web 开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。

下面我们就开始写一个简单的。

代码如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>第一个WebGL尝试</title>
    </head>
    <body>
       <div>
            <!--WebGL 是JavaScript API, 内容都写在HTML5 的<canvas> 标签底下-->
            <canvas id="canvas" width="500" height="500"></canvas>    
       </div>
        <script type="text/javascript">
            var canvas = document.getElementById("canvas");
            var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
            if(!gl){
                console.log("该浏览器不支持WEBGL");
            }else{
                //设置清除颜色(红色,不透明)
                gl.clearColor(1.0, 0.0, 0.0, 1.0);
                //深度清理
                gl.clearDepth(1.0);
                //开启“深度测试”,Z-缓存
                gl.enable(gl.DEPTH_TEST);
                //设置深度测试,近的物体遮挡远的物体
                gl.depthFunc(gl.LEQUAL);
                //清理画布
                gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);
            }
        
        </script>
    </body>
</html>

效果运行如下:


图片.png

方法参数参照如下:

WebGLRenderingContext接口

1.HTMLCanvasElement.getContext()

2.WebGLRenderingContext.clearColor()

接着我们了解下一步:

WebGL 的出现使得在浏览器上面实时显示 3D 图像成为可能,WebGL 本质上是基于光栅化的 API ,而不是基于 3D 的 API。
WebGL 只关注两个方面,即投影矩阵的坐标和投影矩阵的颜色。使用 WebGL 程序的任务就是实现具有投影矩阵坐标和颜色的 WebGL 对象即可。可以使用“着色器”来完成上述任务。顶点着色器可以提供投影矩阵的坐标,片段着色器可以提供投影矩阵的颜色。
无论要实现的图形尺寸有多大,其投影矩阵的坐标的范围始终是从 -1 到 1 。

说起3D,我们需要对三维图形,也就是立体几何有个概念。当然对于矩阵也最好有些理解,
那么接下来先了解一下

矩阵
在3D中,一般使用4x4的矩阵。

矩阵

矩阵变换

相乘
矩阵相乘在3D图形中是一个非常重要的运算,在3D中无论是移动、旋转还是缩放大小,都是通过在当前矩阵的基础上乘以一个新的矩阵来达到目的。

单位矩阵
可以理解为常量中的1,任何矩阵乘于单位矩阵都不变。

逆矩阵
逆矩阵可以理解为倒数,即当前矩阵乘于其逆矩阵的结果为单位矩阵,需要注意的是,只有方阵(行列数量相等)才有逆矩阵,同时不是所有的方阵都有逆矩阵。

引入逆矩阵的原因之一是用来实现矩阵的除法。比如有矩阵X,A,B,其中XA = B,我们要求X矩阵的值。本能来说,我们只需要将B/A就可以得到X矩阵了。但是对于矩阵来说,不存在直接相除的概念。我们需要借助逆矩阵,间接实现矩阵的除法。具体的做法是等式两边在相同位置同时乘以矩阵A的逆矩阵,如下所示,XA(A的逆矩阵)=B(A的逆矩阵)。由于A(A的逆矩阵)=I,即单位矩阵,任何矩阵乘以单位矩阵的结果都是其本身。所以,我们可以得到X=B(A的逆矩阵)。

转置矩阵
转置矩阵是指将行列互换之后的矩阵,和逆矩阵常用于法线变换。

仿射变换
矩阵的仿射变换包含了主要包含了平移、旋转和缩放。

坐标系、向量

在我们现实世界中,每个东西都有它的长、宽、高等度量分量,那么我们对它进行建模的时候会使用到一个对象坐标系。将这个对象放入现实世界,那么它就存在于现实世界中的世界坐标系。我们将它显示在我们的系统设备上,则它存在于应用程序坐标系。

我们把应用程序中度量顶点位置的数值称为顶点坐标。

用显示器上单位度量出的数值起初叫做物理设备坐标或者叫设备坐标。对于光栅设备,我们使用的术语是窗口坐标或者屏幕坐标。屏幕坐标总是用某种整数类型来表示,因为帧缓存中任何像素中心都必须位于固定的网格点上。

然后就是

基本图元
在webgl中,所有的几何图元都是由点、线和三角形这样的基本图元组成。
webgl 提供了多种点和线段图元,相应的type参数如下:

点就只有一种类型:gl.POINTS。可以在顶点着色器中使用内置变量gl_PointSize设置点精灵的大小。

线

WebGL中绘制线有三种方式:gl.LINES(独立线)、gl.LINE_STRIP(线带)、gl.LINE_LOOP(线环)。

对于一系列点(v0、v1、v2、......),独立线每两个点组成一条线((v0,v1)、(v2,v3)、......);线带每次将当前线的后面一个顶点与下一个顶点组成三角形((v0,v1)、(v1,v2)、......);线环与线带类似,线环最后一个顶点与第一个顶点相连。

三角形

WebGL中绘制三角形有三种方式:gl.TRINGLES(独立三角形)、gl.TRINGLE_STRIP(三角形带)、glTRINGLE_FAN(三角形扇)。

对于一系列点(v0、v1、v2、......),独立的三角形每三个点组成一个三角形((v0,v1,v2)、(v2,v3,v4)、......);三角形带每次将当前三角形的后面两个顶点与下一个顶点组成三角形((v0,v1,v2)、(v1,v2,v3)、......);三角形扇除掉第一个顶点,后面的每两个顶点与第一个顶点组成三角形((v0,v1,v2)、(v0,v3,v4)、......)。

......

基本图元

综合起来基本就三种:
WebGl绘图基本图元

最后就了解到
Shader

着色器1.png

着色器 着色器作为WebGL核心主要分为:顶点着色器 和 片元着色器

顶点着色器

<script id="2d-vertex-shader" type="x-shader/x-vertex">
attribute vec2 a_position;

void main() {
  gl_Position = vec4(a_position, 0, 1);
}
</script>

片元着色器

<script id="2d-fragment-shader" type="x-shader/x-fragment">
void main() {
  gl_FragColor = vec4(0, 1, 0, 1);  // green
}
</script>   

如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>第二个WebGL尝试</title>
        <script src="webgl-utils.js"></script>
    </head>
    <body>
       <div>
            <!--WebGL 是JavaScript API, 内容都写在HTML5 的<canvas> 标签底下-->
            <canvas id="canvas" width="300" height="300"></canvas>    
       </div>
        <script id="2d-vertex-shader" type="x-shader/x-vertex">
            attribute vec2 a_position;
            void main() {
              gl_Position = vec4(a_position, 0, 1);
            }
        </script>
        <script id="2d-fragment-shader" type="x-shader/x-fragment">
            void main() {
              gl_FragColor = vec4(1, 0, 0, 1);  // red
            }
        </script>
        <script type="text/javascript">
            var canvas = document.getElementById("canvas");
            var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
            if(!gl){
                console.log("该浏览器不支持WEBGL");
            }else{
                var program = createProgramFromScripts(gl,["2d-vertex-shader", "2d-fragment-shader"]);
                gl.useProgram(program);
                
                var positionLocation = gl.getAttribLocation(program, "a_position");
                var buffer = gl.createBuffer();
                gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
                gl.bufferData(
                gl.ARRAY_BUFFER,
                new Float32Array([
                -1.0, -1.0,
                 1.0, -1.0,
                -1.0,  1.0,
                -1.0,  1.0,
                 1.0, -1.0,
                 1.0,  1.0]),
                gl.STATIC_DRAW);
                gl.enableVertexAttribArray(positionLocation);
                gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);

                // draw
                gl.drawArrays(gl.TRIANGLES, 0, 6); 
            }
        
        </script>

    </body>
</html>

createProgramFromScripts方法在外部webgl-utils.js中。

附录:

  1. WebGL 中文教程
  2. webgl-utils.js
  3. WebGL 基础概念
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,688评论 1 330
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,559评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,749评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,581评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,741评论 3 271
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,684评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,122评论 2 292
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,847评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,441评论 0 228
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,939评论 2 232
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,333评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,783评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,275评论 3 220
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,830评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,444评论 0 180
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,553评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,618评论 2 249

推荐阅读更多精彩内容

  • WebGL从2012年开始接触,后面因为开始专注前端其他方面的事情,慢慢地就把它给遗忘。最近前端开始又流行起绘画制...
    我不是传哥阅读 4,007评论 1 22
  • 转载请以链接形式标明出处:本文出自:103style的博客 OpenGL ES 3.0学习汇总 OpenGL ES...
    103style阅读 1,602评论 0 0
  • 弗洛伊德算法适用于为图中每一个顶点求最短路径,思路如下 检查图中任何一个 到 任何另一个点能否通过第一个点降低最短...
    RichardW阅读 917评论 0 1
  • 程序创建完之后,我们需要需要对着色器进行动态控制才能达到我们所需要的功能。(如不知道怎么创建WebGL,可参考上篇...
    三石青韦阅读 1,098评论 1 2
  • ​​​ 1. 前一段时间,妈妈跟一位阿姨在客厅聊天,刚开始聊的挺开心的,时不时的唠唠家常。不一会儿阿姨的“河东狮吼...
    明阳小妹阅读 791评论 2 5