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访问方法 在 ...
随机推荐
- web工作过程
了解浏览器与服务器进行通信和访问的过程 打开浏览器-输入URL地址 当我们访问一个网页时,如http://www.baidu.com,这个网址包含四个部分的内容: 1.第一部分:协议类型:这里是htt ...
- C语言之变量和数据类型
常量:程序在运行过程中无法对值进行更改. 变量:是在计算机内存空间一种表示,声明变量将会向计算机内存申请存储空间,用于保存数据,计算机的CPU会从内存中加载数据. 声明变量: 数据类型 变量名[=值 ...
- 一个可以控制提示框显示为top,bottom,left,right的小方法
html代码 <!doctype html><html><head><meta charset="utf-8"><title& ...
- python——爬虫&问题解决&思考(1)
最近刚接触python,找点小任务来练练手,希望自己在实践中不断的锻炼自己解决问题的能力.这个小爬虫来自慕课网的一门课程,我在这里记录的是自己学习的过程中遇到的问题和解决方法以及爬虫之外的思考. 这次 ...
- [Leetcode] Binary tree Zigzag level order traversal二叉树Z形层次遍历
Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to ...
- orcle :Could not initialize "D:\app\Administrator\product\11.2.0\dbhome_1\bin\oci.dll" Make sure you have the 32 bits Oracle Client installed.
服务器重启后,数据库登录信息为空 错误信息: ---------------------------(Not logged on) - PL/SQL Developer---------------- ...
- 【错误】undefined reference to `boost::....的解决
很多新手引用Boost库编程,在ubuntu下编译时候有时候会出现如下错误: test04.cpp:(.text+0x2c): undefined reference to `boost::progr ...
- 通过LOGBACK实现每个类、包或自定义级别
项实现LOGBACK对每个包或者类或者通过自定义级别的方式实现自定义输出的日志进入制定的文件.查阅了很多资料,都没有找到行之有效的解决方案,直到看到了这篇文章http://www.360doc.com ...
- 在项目中利用TX Text Control进行WORD文档的编辑显示处理
在很多文档管理的功能模块里面,我们往往需要对WORD稳定进行展示.编辑等处理,而如果使用微软word控件进行处理,需要安装WORD组件,而且接口使用也不见得简单易用,因此如果有第三方且不用安装Offi ...
- XManager5连接CentOS7
XManager5连接CentOS6的方法已经行不通了,那么如何用XManager5连接CentOS7 从Xmanger官网博客得知: "Gnome in CentOS 7 tries to ...