webgl自学笔记——几何图形
3D应用的基础元素:
1、canvas,它是渲染场景的占位符。标准html的canvas元素
2、Objects,这里指的是组成一个场景的所有3d实体。这些实体都由三角形组成。webgl中使用Buffer(vertex、index)来存储管理这些3d实体数据。
3、Lights,如果没有光照3d场景将看不到任何东西。webgl使用着色器来为场景中的光照建模。我们将会看到3d实体如何根据物理规律来反射和吸收光照,并讨论不同的光照模型。
4、Camera,摄像机作为3d世界的视口。我们通过摄像机来开发和看到一个3d场景。我们要理解如何根据不同的场景来使用不同的矩阵操作,这些操作可以利用相机原理来建模。
webgl中的数据类型:
webgl对图形有一种标准的处理方式,与我们拥有的表面的复杂性和顶点个数无关。只有两种基础的数据类型来表达3d物体的几何形状:vertices和indices(顶点和索引)。
Vertices: 代表3d物体的拐点,每一个顶点使用3个数字来表达想x,y,z;webgl中没有提供api来将独立的顶点传递到渲染管线中,因此我们需要将所有的顶点放在一个JavaScript数组中然后通过这个数组来构造一个webgl顶点缓冲区(vertex buffer)。
Indices: 索引是在一个给定3d场景的中的所有顶点的数字标识。索引告诉webgl如何有序的来链接顶点来生成一个表面。像顶点一样,索引也是存储在JavaScript数组中然后使用webgl索引缓冲区传递给webgl的渲染管线。
有两种webgl 缓冲区来描述和处理几何图形:
包含顶点数据的缓冲区:Vertex Buffer Objects(VBO)
包含索引数据的缓冲区:Index Buffer Objects(IBO)
webgl的渲染管线:

Vertex Buffer Objects
VBO包含了webgl要求来描述将要渲染的几何图形的数据。除了上面提到的顶点坐标外,还有vertex normal(顶点法线),颜色、纹理坐标等都可以用vbo来建模。
Vertex shader
顶点着色器将会来每个顶点上被调用,顶点着色器将用来操作之前的顶点数据,如顶点坐标、法线、颜色、文理坐标。这些数据将被顶点着色器内置的attributes变量来引用,每一个attribute指向一个他读取顶点数据的VBO。
Fragment shader
每三个顶点定义了一个三角形在三角形表面的每一个元素都需要被分配一个颜色,否则我们的表面将是透明的。
三角形表面的每一个元素成为一个片元(fragment)。因为我们处理的表面将被呈现在我们屏幕上,所以片元通常被理解为像素。
片元着色器的主要目的是为表面的每个独立像素来计算颜色。

Framebuffer
它是包含一个之前被片元着色器处理的片元二维的缓冲区。一旦所有的片元都被处理过后,一张二维图片将被构造并显示在屏幕上。framebuffer是渲染管道的最终点。
Attributes,uniforms,varyings是着色器编程中经常用到的三种类型的变量。
Attributes是顶点着色器中的输入变量,如顶点坐标、顶点颜色等。由于顶点着色器将会在每个顶点上都被调用,所以每次顶点着色器被调用时的输入变量attributes都是不同的。
Uniforms 是在顶点着色器和片元着色器中都能被使用的输入变量。在一个渲染循环中unifroms通常是不变的常量。如灯源位置。
Varyings用来由顶点着色器向片元着色器传递数据。
1、webgl缓冲区数据处理流程:
ver vertices = [];
var myBuffer = gl.createBuffer(); // 创建缓冲区
// 绑定缓冲区; 由于webgl是一个状态机,一旦绑定buffer,之后所有的缓冲操作都将在绑定的buffer上执行,直到解绑这个buffer或者绑定到另一个buffer上。
gl.bindBuffer(gl.ARRAY_BUFFER, myBuffer);
// 绑定缓冲区后我们需要为他分配内容,webgl不能直接使用JavaScript数组,而是使用类型数组,以便缓冲区对象能够使用原生二进制数据来加快图形处理速度。
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);// 清空缓存
2、将attributes连接到VBOs
VBO创建后,我们需要将这些缓冲区链接到顶点着色器的属性中。每一个顶点着色器的attribute将且仅将指向一个缓冲区对象。
通常来讲我们有以下对应关系。

缓冲区数据进入顶点着色器分为三步:
1)绑定一个缓冲区:gl.bindBuffer(gl.ARRAY_BUFFER, myBuffer)
2 ) 将一个attribute指向刚刚绑定的VBO:gl.vertexAttribPointer(Index, Size, Type, Norm, Stride, Offset);(该函数定义了一个从当前绑定缓冲区读取信息的指针;参数Index指的是将被匹配缓冲区的attribute的索引)
3)激活attribute:gl.enableVertexAttribArray(aVertexPosition)
下面的图表记录了匹配过程

3、渲染
定义完VBO对象并绑定到顶点着色器属性后,就可以准备渲染了。完成渲染过程我们可以使用两个API函数:drawArrays、drawElements
这两个方法都是用来像帧缓冲区中写入数据;drawArrays按照在缓冲区中的顶点数据的顺序来创建图形,相反drawElements使用索引来访问顶点缓冲区中的数据来创建图形。
drawArrays和drawElements仅接受 enabled arrays ,他们是被匹配到激活的顶点着色器attribute的vbo对象。
当索引信息无法获得时,我们使用drawArrays方法。在大多数情况下当几何图形很简单以至于定义索引是浪费资源时我们使用drawArrays方法,比如三角形、矩形。

使用drawArrays只适合非常简单的图形,如果是连续三角形,那么vbo中需要重复定义每个顶点,并且这些点都会在顶点着色器中被处理,浪费空间和性能。
gl.drawArrays(Mode, First, Count)
drawElements允许使用IBO来告诉浏览器如何去渲染图形。因为有了索引VBO中的数据不用像之前一样被重复定义,只需要定义一次,但可以通过索引来多次使用。这种方式减少内存和GPU的性能损耗。

使用drawElements至少需要两个Buffer:VBO和IBO;顶点着色器将在每一个VBO的顶点上执行,然后渲染管线使用IBO将几何图形聚集成三角形。(确保VBO、IBO都被绑定过)
gl.drawElements(Mode, Count, Type, Offset)
webgl作为一个状态机的buffer控制
我们可以拿到一些关于渲染管线状态的信息,比如:
getParameter(type)
ARRAY_BUFFER_BINDING取得一份关于最近绑定的VBO的引用
ELEMENT_ARRAY_BUFFER取得一份关于最近绑定的IBO的引用
getBufferParameter(type, parameter)
type: ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER
parameter: BUFFER_SIZE, BUFFER_USAGE
isBuffer(object)
基本步骤:
initProgram()
initBuffers()
drawSence()
创建着色器三步骤:
var shader = gl.createShader();
gl.shaderSource(shader, source);
gl.compileShader(shader);
gl.getShaderParameter(shader, gl.COMPILE\_STATUS);
initProgram步骤:
prg = gl.createProgram();
gl.attachShader(prg, shader); // vs fs
gl.linkProgram(prg);
gl.getProgramParameter(prg, gl.LINK\_STATUS)
gl.useProgram(prg);
prg.aVertexPosition = gl.getAttribLocation(prg, 'aVertexPosition');
webgl自学笔记——几何图形的更多相关文章
- webgl自学笔记——光照
在Webgl中我们使用顶点着色器和片元着色器来为我们的场景创建光照模型.着色器允许我们使用数学模型来控制如何照亮我们的场景. 最好有线性代数的相关知识. 本章中: 光源.法线.材料 光照和着色的区别 ...
- webgl自学笔记——矩阵变换
这章主要探讨矩阵,这些矩阵代表了应用在我们场景上的变换,允许我们移动物体.然而在webGL api中并没有一个专门的camera对象,只有矩阵.好消息是使用矩阵来取代相机对象能让webgl在很多复杂动 ...
- webgl自学笔记——深度监测与混合
这一章中关于webgl中颜色的使用我们将深入研究.我们将从研究颜色在webgl和essl中如何被组装和获取开始.然后我们讨论在物体.光照和场景中颜色的使用.这之后我们将看到当一个物体在另一个物体前面是 ...
- 《Linux内核设计与实现》课本第四章自学笔记——20135203齐岳
<Linux内核设计与实现>课本第四章自学笔记 进程调度 By20135203齐岳 4.1 多任务 多任务操作系统就是能同时并发的交互执行多个进程的操作系统.多任务操作系统使多个进程处于堵 ...
- 《Linux内核设计与实现》课本第三章自学笔记——20135203齐岳
<Linux内核设计与实现>课本第三章自学笔记 进程管理 By20135203齐岳 进程 进程:处于执行期的程序.包括代码段和打开的文件.挂起的信号.内核内部数据.处理器状态一个或多个具有 ...
- 《Linux内核设计与实现》课本第十八章自学笔记——20135203齐岳
<Linux内核设计与实现>课本第十八章自学笔记 By20135203齐岳 通过打印来调试 printk()是内核提供的格式化打印函数,除了和C库提供的printf()函数功能相同外还有一 ...
- python自学笔记
python自学笔记 python自学笔记 1.输出 2.输入 3.零碎 4.数据结构 4.1 list 类比于java中的数组 4.2 tuple 元祖 5.条件判断和循环 5.1 条件判断 5.2 ...
- ssh自学笔记
Ssh自学笔记 Ssh简介 传统的网络服务程序,如:ftp.pop和telnet在本质上都是不安全的,因为它们在网络上用明文传送口令和数据,别有用心的人非常容易就可以截获这些口令和数据.而且,这些服务 ...
- JavaScript高级程序设计之自学笔记(一)————Array类型
以下为自学笔记. 一.Array类型 创建数组的基本方式有两种: 1.1第一种是使用Array构造函数(可省略new操作符). 1.2第二种是使用数组字面量表示法. 二.数组的访问 2.1访问方法 在 ...
随机推荐
- IT培训行业揭秘(六)
2017年全国的IT职业培训机构的招生数量相比于去年同期都出现了大规模的下滑,虽然目前大学生毕业之后参加培训班的人数依然没有变化,但是目前中小培训机构像雨后春笋般的纷纷建立,他们纷纷抢占市场,为了招生 ...
- springboot + shiro + cas4.2.7 实战
1. 下载地址 https://github.com/apereo/cas/archive/v4.2.7.zip 2. 解压后, 用intellj idea 打开 3. 执行 gradle build ...
- .net 利用Emit将object转为DbParameter,DataTable转为List<>
先放测试结果图,测试的方法是拷贝了老赵的一个简单的性能计数器:CodeTimer.发现速度还是比利用反射来获取快了2倍左右的,将object转为DbParameter的反射方法我没写. ...
- 读书笔记-你不知道的JavaScript(上)
本文首发在我的个人博客:http://muyunyun.cn/ <你不知道的JavaScript>系列丛书给出了很多颠覆以往对JavaScript认知的点, 读完上卷,受益匪浅,于是对其精 ...
- bootstrapValidator 使用(包含入门demo,常用方法,以及常用的规则)
一 什么是bootstrapValidator? -- 一个基于 jquery,boostrap 的表单验证框架....简单实用上手快,页面美观还过得去,不废话了,直接撸. 二 boots ...
- 使用FlashWavRecorder实现浏览器录制wav音频和上传音频文件,兼容IE8以上浏览器
前言:本项目基于github开源插件实现,该插件使用flash实现,兼容IE8以上浏览器 感谢michalstocki的分享该项目,github项目地址:https://github.com/mich ...
- Windows系统如何使用sqlmap
使用方法:需要安装python,不能安装最新版本的python3.2.2只能安装2.6-3.0这些版本,包括2.6,3.0 这里,我提供一个Python的安装包.点击这里下载→ Python2.7 然 ...
- MYSQL导入数据报错|MYSQL导入超大文件报错|MYSQL导入大数据库报错:2006 - MySQL server has gone away
导SQL数据库结构+数据时,如果数据是批量插入的话会报错:2006 - MySQL server has gone away. 解决办法:找到你的mysql目录下的my.ini配置文件(如果安装目录没 ...
- 微信小程序 - 自定义创建
自定义创建与默认创建完全相同, 只是不要勾选quick start即可 淡定(不要看到报错就紧张, 一定要淡定) 看看它说了什么, no such file or directory(没有文件或目录) ...
- WCF入门的了解准备工作
了解WCF, 及WCF入门需要掌握哪里基本概念? 1.准备工作 >1.1 . XML >1.2 . Web Service >1.3 . 远程处理 (RPC) >1.4. 消 ...