【笔记】《WebGL编程指南》学习-第2章WebGL入门(3-画一个点-版本1))
2017-09-19 23:10
501 查看
目标:绘制一个最简单的图形-点(位于原点(0.0,0.0,0.0)处,大小10像素)!
成果展示:其实这个这点是用矩形画的,而不是圆。
开始学习!
WebGL 依赖于一种新的称为称为着色器(shader)的绘图机制。着色器提供了灵活且强大的绘制二维或三维图形的方法,所有WebGL程序必须使用它。着色器不仅强大,而且更复杂,仅仅通过一条简单的绘图命令是不能操作它的
html文件与之前的 HelloCanvas 基本一致,就不多说了。
HelloPoint1.js
其实和上一篇文章的HelloCanvas.js相比,有很多都是一样的,但多了一个着色器的概念和画点的函数。
WebGL需要两种着色器:
顶点着色器(Vertec shader):定点着色器是用来描述顶点特性(如位置、颜色等)的程序。顶点(Vertex)是指二维或三维空间中的一个点,比如二维或三维图形的端点或焦点。
片元着色器(Fragment shader):进行逐元处理过程如光照(以后的篇章会讲)的程序。片元(fragment)是一个WebGL术语,你可以将其理解为像素(图像的单元)。
着色器后面会详细去学,这里就不多说了。简单来说,在三维场景中,仅仅靠线条和颜色把图形画出来是不够的,比如光线照上去,观察者的视觉发生变化,对场景的影响等等。着色器可以高度灵活地完成这些工作,提供各种渲染效果。
JS读取了着色器的相关信息,然后存在WebGL系统中使用着色器在浏览器上绘制图形,下图是从执行JS程序到在浏览器中显示结果的过程:
图的左侧是两个浏览器窗口。它们是同一个窗口,上面一个是执行JS程序之前的窗口,下面一个执行之后的。
程序执行的流程大概是:
运行JS程序,调用了WebGL的相关方法。
顶点着色器和片元着色器会执行,在颜色缓冲区内进行绘制,这时就清空了绘图区。
颜色缓冲区中的内容会自动在浏览器的 <canvas>上显示出来。
在以后的学习中,上面这个图会经常用到,所以我们会有一个简化版本,注意程序流程是从左到右的,最右边是颜色缓冲区而不是浏览器,因为颜色缓冲区的内容会自动显示在浏览器上。
本节示例程序的任务是,在屏幕上绘制一个10像素大小的点,它用到两个着色器:
顶点着色器指定了点的位置和尺寸。本例中,点的位置是(0.0, 0.0, 0.0),尺寸是10像素。
片元着色器指定了点的颜色。本例中,点的颜色是红色(1.0, 0.0, 0.0, 1.0);
这一段代码分别是顶点着色器程序和片元着色器程序,着色器程序代码作为字符串存储在变量 VSHADER_SOURCE 和 FSHADER_SOURCE 中。就像前面提到的它们是以JS字符串形式编写的着色器语言程序,这样主程序可以将他们传给W
bcf9
ebGL系统。
因为着色器程序代码必须预先处理成单个字符串的形式,所以我们用 + 号将多行字符串连成一个长字符串,可以在+号后面加上换行符 “\n” 。这样当着色器内部出错时,可以获得出错的行号,当然也可以不写。
与上一篇的流程相比,新增“初始化着色器”和 “绘制”。
初始化着色器,我们调用辅助函数 initShaders()(被定义在要下载的文件里)对字符串形式的着色器进行了初始化,这个函数的内部细节,在后面的篇章会讲。
initShaders()点的行为:
如图所示, WebGL系统由两部分在组成,即顶点着色器和片元着色器。在初始化着色器之前,顶点着色器和片元着色器都是空白的,我们需要将字符串形式的着色器代码从JS传给WebGL系统,并建立着色器,这就是 initShaders() 所做的事情。注意,着色器运行在WebGL系统中,而不是JS程序中。
WebGL程序包括运行在浏览器中的JS和运行在WebGL系统的着色器程序这两个部分。
就像JS一样,着色器程序使用 = 操作符为变量赋值。首先将点的位置赋值给 gl_Position 变量,然后将点的尺寸赋值给 gl_PointSize 变量,这两个变量是内置在顶点着色器中,而且有特殊含义;gl_Position 表示顶点的位置,gl_PointSize 表示点的尺寸。
在看代码的时候你可能会有疑问,好像在定义顶点着色器时的类型和JS不一样。那是因为GLSL ES是一种强类型的编程语言,也就是说,开发者必须明确指出某个变量是某种“类型”的。
下面是这一节出现在GLSL ES代码中的几种类型:
注意:如果向某类型的变量赋一个不同类型的值。就会出错,例如,gl_PointSize 是浮点型的变量,你就必须向其赋浮点型的值。
在赋值给 gl_Position 时,我们添加了1.0作为第4个分量。由4个分量组成的矢量被称为齐次坐标。因为它能够提高处理三维数据的效率,所以在三维图形中被大量使用。虽然齐次坐标是四维的,但如果其最后一个分量是 1.0,那么这个齐次坐标就可以表示“前三个分量为坐标值”的那各个点。所以,当你需要用齐次坐标表示顶点坐标的时候,只要将最后一个分量赋为 1.0 就可以了。
齐次坐标:
齐次坐标使用如下的符号描述:(x, y, z, w),齐次坐标(x, y, z, w)等价于三维坐标(x/w, y/w, z/w)。所以如果齐次坐标的第4个分量是1,你就可以将它当成三维坐标来使用。w 的值必须是大于等于0的。如果w 趋近于0,那么它所表示的点是趋近无穷远,所以齐次坐标系中可以有无穷的概念。齐次坐标的存在,使得用矩阵乘法来描述顶点变换成可能,三维图形系统在计算过程中,通常使用齐次坐标来表示顶点的三维坐标。
顶点着色器控制点的位置、大小,片元着色器控制点的颜色。如前所述,偏远就是显示在屏幕上的一个像素。
片元着色器的作用是处理片元,使其显示在屏幕上。
片元着色器将点的颜色赋给 gl_FragColor 变量,该变量是片元着色器唯一的内置变量,它控制着像素在屏幕上的最终颜色,对这个内置变量赋值后,相应的像素就会以这个颜色值显示,颜色值也是 vec4 类型。
gl.drawArrays()是一个强大的函数,它可以用来绘制各种图形:
示例函数调用该函数时,因为我么绘制的是单独的点,所以设置第1个参数为 gl.POINTS, 设置第2个参数为0,表示从第1个顶点(虽然只有1个顶点)开始画,第3个参数 count 为1,表示在这个简单的程序中仅绘制了1个点。
如图所示,WebGL 坐标系和 <canvas>绘图区的坐标系不同,需要将前者映射到后者。默认情况下,WebGL 坐标与 <canvas>坐标的对应关系如下:
<canvas> 的中心点:(0.0, 0.0, 0.0)
<canvas> 的上边缘和下边缘:(-1.0, 0.0, 0.0)和(1.0, 0.0, 0.0)
<canvas> 的左边缘和右边缘:(0.0, -1.0, 0.0)和(0.0, 1.0, 0.0)
好,运行成果
成果展示:其实这个这点是用矩形画的,而不是圆。
开始学习!
WebGL 依赖于一种新的称为称为着色器(shader)的绘图机制。着色器提供了灵活且强大的绘制二维或三维图形的方法,所有WebGL程序必须使用它。着色器不仅强大,而且更复杂,仅仅通过一条简单的绘图命令是不能操作它的
HelloPoint1.html
HelloPoint1.html<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Draw a point 1</title> </head> <body onload="main()"> <canvas id="webgl" width="400" height="400"> Please use a browser that supports "canvas" </canvas> <script src="../lib/webgl-utils.js"></script> <script src="../lib/webgl-debug.js"></script> <script src="../lib/cuon-utils.js"></script> <script src="HelloPoint1.js"></script> </body> </html>
html文件与之前的 HelloCanvas 基本一致,就不多说了。
HelloPoint1.js
先看代码(有个印象)HelloPoint1.js
//顶点着色器程序 var VSHADER_SOURCE = 'void main(){' + 'gl_Position = vec4(0.0, 0.0, 0.0, 1.0);'+ ' gl_PointSize = 10.0;'+ '}'; //片元着色器程序 var FSHADER_SOURCE= 'void main(){'+ 'gl_FragColor = vect4(1.0, 0.0, 0.0, 1.0);'+ '}'; function main() { //获取canvas元素 var canvas = document.getElementById("webgl"); if(!canvas){ console.log("Failed to retrieve the <canvas> element"); return; } //获取WebGL绘图上下文 var gl = getWebGLContext(canvas); if(!gl){ console.log("Failed to get the rendering context for WebGL"); return; } //初始化着色器 if(!initShaders(gl,VSHADER_SOURCE,FSHADER_SOURCE)){ console.log("Failed to initialize shaders."); return; } //指定清空<canvas>颜色 gl.clearColor(0.0, 0.0, 0.0, 1.0); //清空<canvas> gl.clear(gl.COLOR_BUFFER_BIT); //绘制一个点 gl.drawArrays(gl.POINTS, 0, 1); }
其实和上一篇文章的HelloCanvas.js相比,有很多都是一样的,但多了一个着色器的概念和画点的函数。
着色器是什么?
要使用 WebGL进行绘图就必须使用着色器。在代码中,着色器程序是以字符串的形式“嵌入”在JS文件中,在程序真正开始运行前它就已经设置好了。WebGL需要两种着色器:
顶点着色器(Vertec shader):定点着色器是用来描述顶点特性(如位置、颜色等)的程序。顶点(Vertex)是指二维或三维空间中的一个点,比如二维或三维图形的端点或焦点。
片元着色器(Fragment shader):进行逐元处理过程如光照(以后的篇章会讲)的程序。片元(fragment)是一个WebGL术语,你可以将其理解为像素(图像的单元)。
着色器后面会详细去学,这里就不多说了。简单来说,在三维场景中,仅仅靠线条和颜色把图形画出来是不够的,比如光线照上去,观察者的视觉发生变化,对场景的影响等等。着色器可以高度灵活地完成这些工作,提供各种渲染效果。
JS读取了着色器的相关信息,然后存在WebGL系统中使用着色器在浏览器上绘制图形,下图是从执行JS程序到在浏览器中显示结果的过程:
图的左侧是两个浏览器窗口。它们是同一个窗口,上面一个是执行JS程序之前的窗口,下面一个执行之后的。
程序执行的流程大概是:
运行JS程序,调用了WebGL的相关方法。
顶点着色器和片元着色器会执行,在颜色缓冲区内进行绘制,这时就清空了绘图区。
颜色缓冲区中的内容会自动在浏览器的 <canvas>上显示出来。
在以后的学习中,上面这个图会经常用到,所以我们会有一个简化版本,注意程序流程是从左到右的,最右边是颜色缓冲区而不是浏览器,因为颜色缓冲区的内容会自动显示在浏览器上。
本节示例程序的任务是,在屏幕上绘制一个10像素大小的点,它用到两个着色器:
顶点着色器指定了点的位置和尺寸。本例中,点的位置是(0.0, 0.0, 0.0),尺寸是10像素。
片元着色器指定了点的颜色。本例中,点的颜色是红色(1.0, 0.0, 0.0, 1.0);
使用着色器的WebGL程序的结构
//顶点着色器程序 var VSHADER_SOURCE = 'void main(){' + 'gl_Position = vec4(0.0, 0.0, 0.0, 1.0);'+ ' gl_PointSize = 10.0;'+ '}'; //片元着色器程序 var FSHADER_SOURCE= 'void main(){'+ 'gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);'+ '}';
这一段代码分别是顶点着色器程序和片元着色器程序,着色器程序代码作为字符串存储在变量 VSHADER_SOURCE 和 FSHADER_SOURCE 中。就像前面提到的它们是以JS字符串形式编写的着色器语言程序,这样主程序可以将他们传给W
bcf9
ebGL系统。
因为着色器程序代码必须预先处理成单个字符串的形式,所以我们用 + 号将多行字符串连成一个长字符串,可以在+号后面加上换行符 “\n” 。这样当着色器内部出错时,可以获得出错的行号,当然也可以不写。
初始化着色器
在研究着色器的内部细节之前,先看一下 main()函数的执行流程,大部分 WebGL 程序都会遵循这样的流程。与上一篇的流程相比,新增“初始化着色器”和 “绘制”。
初始化着色器,我们调用辅助函数 initShaders()(被定义在要下载的文件里)对字符串形式的着色器进行了初始化,这个函数的内部细节,在后面的篇章会讲。
initShaders()点的行为:
如图所示, WebGL系统由两部分在组成,即顶点着色器和片元着色器。在初始化着色器之前,顶点着色器和片元着色器都是空白的,我们需要将字符串形式的着色器代码从JS传给WebGL系统,并建立着色器,这就是 initShaders() 所做的事情。注意,着色器运行在WebGL系统中,而不是JS程序中。
WebGL程序包括运行在浏览器中的JS和运行在WebGL系统的着色器程序这两个部分。
顶点着色器
//顶点着色器程序 var VSHADER_SOURCE = 'void main(){' + 'gl_Position = vec4(0.0, 0.0, 0.0, 1.0);'+ ' gl_PointSize = 10.0;'+ '}';
就像JS一样,着色器程序使用 = 操作符为变量赋值。首先将点的位置赋值给 gl_Position 变量,然后将点的尺寸赋值给 gl_PointSize 变量,这两个变量是内置在顶点着色器中,而且有特殊含义;gl_Position 表示顶点的位置,gl_PointSize 表示点的尺寸。
在看代码的时候你可能会有疑问,好像在定义顶点着色器时的类型和JS不一样。那是因为GLSL ES是一种强类型的编程语言,也就是说,开发者必须明确指出某个变量是某种“类型”的。
下面是这一节出现在GLSL ES代码中的几种类型:
注意:如果向某类型的变量赋一个不同类型的值。就会出错,例如,gl_PointSize 是浮点型的变量,你就必须向其赋浮点型的值。
在赋值给 gl_Position 时,我们添加了1.0作为第4个分量。由4个分量组成的矢量被称为齐次坐标。因为它能够提高处理三维数据的效率,所以在三维图形中被大量使用。虽然齐次坐标是四维的,但如果其最后一个分量是 1.0,那么这个齐次坐标就可以表示“前三个分量为坐标值”的那各个点。所以,当你需要用齐次坐标表示顶点坐标的时候,只要将最后一个分量赋为 1.0 就可以了。
齐次坐标:
齐次坐标使用如下的符号描述:(x, y, z, w),齐次坐标(x, y, z, w)等价于三维坐标(x/w, y/w, z/w)。所以如果齐次坐标的第4个分量是1,你就可以将它当成三维坐标来使用。w 的值必须是大于等于0的。如果w 趋近于0,那么它所表示的点是趋近无穷远,所以齐次坐标系中可以有无穷的概念。齐次坐标的存在,使得用矩阵乘法来描述顶点变换成可能,三维图形系统在计算过程中,通常使用齐次坐标来表示顶点的三维坐标。
片元着色器
//片元着色器程序 var FSHADER_SOURCE= 'void main(){'+ 'gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);'+ '}';
顶点着色器控制点的位置、大小,片元着色器控制点的颜色。如前所述,偏远就是显示在屏幕上的一个像素。
片元着色器的作用是处理片元,使其显示在屏幕上。
片元着色器将点的颜色赋给 gl_FragColor 变量,该变量是片元着色器唯一的内置变量,它控制着像素在屏幕上的最终颜色,对这个内置变量赋值后,相应的像素就会以这个颜色值显示,颜色值也是 vec4 类型。
绘制操作
首先我们清空绘制区域,然后我们使用 gl.drawArrays()来进行绘制。gl.drawArrays(gl.POINTS, 0, 1);
gl.drawArrays()是一个强大的函数,它可以用来绘制各种图形:
示例函数调用该函数时,因为我么绘制的是单独的点,所以设置第1个参数为 gl.POINTS, 设置第2个参数为0,表示从第1个顶点(虽然只有1个顶点)开始画,第3个参数 count 为1,表示在这个简单的程序中仅绘制了1个点。
WebGL的坐标系统
如图所示,WebGL 坐标系和 <canvas>绘图区的坐标系不同,需要将前者映射到后者。默认情况下,WebGL 坐标与 <canvas>坐标的对应关系如下:
<canvas> 的中心点:(0.0, 0.0, 0.0)
<canvas> 的上边缘和下边缘:(-1.0, 0.0, 0.0)和(1.0, 0.0, 0.0)
<canvas> 的左边缘和右边缘:(0.0, -1.0, 0.0)和(0.0, 1.0, 0.0)
好,运行成果
相关文章推荐
- 【笔记】《WebGL编程指南》学习-第2章WebGL入门(4-画一个点-版本2))
- 【笔记】《WebGL编程指南》学习-第2章WebGL入门(1-用canvas画一个蓝色矩形)
- 【笔记】《WebGL编程指南》学习-第2章WebGL入门(2-WebGL的HelloWorld)
- 【笔记】《WebGL编程指南》学习-第2章WebGL入门(6-改变点的颜色))
- 【笔记】《WebGL编程指南》学习-第2章WebGL入门(5-通过鼠标点击画点)
- C# 从入门到精通 学习笔记1 第2章 使用变量、操作符和表达式
- 【零基础入门学习Python笔记012】一个打了激素的数组3
- MySQL学习笔记之中的一个 MySQL入门
- SharePoint【学习笔记】-- 【Upgrading&Version版本升级】:Content Type Feature(一.创建和部署一个基本的Content Type Feature)
- 【笔记】《WebGL编程指南》学习-第1章WebGL概述
- 【零基础入门学习Python笔记012】一个打了激素的数组3
- [置顶] 【第一部分-django论坛从搭建到部署】一个完整的Django入门指南学习笔记
- Python核心编程(第二版)学习笔记01 【第2章 快速入门】
- webgl+three.js,学习笔记,画一个立方体+解析
- django学习笔记【001】django版本的确定&创建一个django工程
- 【零基础入门学习Python笔记011】一个打了激素的数组2
- 学习笔记:发现一个IE版本判断的好方法
- Sharepoint学习笔记---Upgrading&Version版本升级:Content Type Feature(一.创建和部署一个基本的Content Type Feature)
- webgl学习笔记1--如何绘制一个基本图形