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访问方法 在 ...
随机推荐
- spring mvc 存取值
(转) 1,使用HttpServletRequest获取 @RequestMapping("/login.do") public String login(HttpServletR ...
- be 动词
be 动词:表达人或事物的状态,即身份.性质.特征状态等 be动词 在翻译里面我们称之为缺项词,在我们的文化中很难找到一个具体的词汇与之像应对,我们只能用一个句子去解释它. be动词主要是用来表达人或 ...
- 一个想法照进现实-《IT连》创业项目:直觉型面试招聘的漏洞
前言: 创业转眼又过去了一个月,是时候抽时间写写文向大伙继续汇报进度了. 还记得上一篇创业文章,我还在说:创业时该不该用新手程序员. 嗯,然后,然后,报应就来了:所以这篇要写写自己在新人招聘上出现的问 ...
- Java IO流之缓冲流
一.缓冲流简介 二.BufferedInputStream 三.其他三种缓冲流
- 基于查表的整数霍夫变换方法实现(matlab)
暂时先用matlab把算法弄一下,这是基于查表的整数霍夫变换方法实现及解释. 接着再实现FPGA的霍夫变换. 霍夫变换原理和算法这里不多说,可参考以下链接: http://blog.csdn.net/ ...
- Ajax&jQuery教案总结
Ajax&jQuery教程总结 目录 第一章 Ajax入门 6 第1讲 传统表单提交存在的问题 6 课程内容 6 1. 问题的引入 6 2. 问题的解决 6 参考进度(0.5课时) 7 第2讲 ...
- 编写一个简单的Web Server
编写一个简单的Web Server其实是轻而易举的.如果我们只是想托管一些HTML页面,我们可以这么实现: 在VS2013中创建一个C# 控制台程序 编写一个字符串扩展方法类,主要用于在URL中截取文 ...
- C#简单构架之EF进行读写分离+多数据库(Mysql/SqlService)
最近因为项目需要,研究了下EF的读写分离,所以做了一个demo进行测试,下面是项目的结构 表现层view 主要提供Web.WebApi等表现层的解决方案 公共层public 主要提供项目公共类库,数据 ...
- 常用SHELL命令
1.查看版本号cat /proc/version; uname -a; uname -r 2.查看用户组cat /etc/group 3.查看当前用户组 groups 4.查看当前用户 whoami ...
- javascript学习笔记(一):词法结构
一:字符集 javascript程序是用Unicode字符集编写的. 二:区分大小写 javascript是区分大小写的语言,但需注意的是HTML不区分大小写 三:空格.换行符和格式控制符 javas ...