原书中第2章很是长,若是整理成一个文档的话,得看好多天。为了浏览方便,我将其拆分红若干小节,方便你们学习。javascript
webgl采用HTML5中引入的canvas元素来定义页面的绘图区域。若是没有WegGL,js只能在canvas上绘制二维图形。html
在这一章中,咱们将经过建立若干个示例程序,一步步的介绍一些核心的webgl函数。java
咱们要开始编写最短的webgl程序,这个程序的主要功能是使用背景色清空canvas标签的绘图区。(这里的清空,是指用背景色填充的意思)web
html代码以下;编程
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>webgl学习</title>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script src="./index.js"></script>
</body>
</html>
复制代码
js代码以下:canvas
// 获取canvas
var canvas = document.getElementById('canvas')
// 获取webgl绘图上下文
var gl = canvas.getContext('webgl')
if (!gl) {
console.log('Failed to get the rendering context')
}
// 指定清空canvas的颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0)
// 清空canvas
gl.clear(gl.COLOR_BUFFER_BIT)
复制代码
示例程序的执行步骤以下:数组
点击查看效果浏览器
咱们经过getElementById获取canvas元素bash
var canvas = document.getElementById('canvas')
复制代码
这里传入的参数是‘webgl’而不是‘3d’。咱们之前使用canvas画2d图形的时候传入的是‘2d’。因此这里要注意下,不要传错了。编程语言
var gl = canvas.getContext('webgl')
复制代码
gl.clearColor(0.0, 0.0, 0.0, 1.0)
复制代码
gl.clearColor采用RGBA的方式设置背景色:
gl.clearColor(red,green,blue,alpha)
复制代码
参数 | 含义 |
---|---|
red | 指定红色值(从0.0到1.0) |
green | 指定绿色值(从0.0到1.0) |
blue | 指定蓝色值(从0.0到1.0) |
alpha | 指定透明度(从0.0到1.0) |
返回值 | 无 |
错误 | 无 |
若是任何值小于0或者大于1,那么就会被截断为0.0或者1.0
示例程序执行gl.clearColor(0.0, 0.0, 0.0, 1.0)
,背景色就被指定为了黑色。
咱们通常指定颜色时,颜色的值是0到255之间的,可是因为webgl是继承自OpenGL,因此它遵循传统OpenGL颜色份量的取值范围。
一旦指定的背景色,背景色就会驻存在WegGL系统中,在下一次调用gl.clearColor以前都不会改变。若是你未来还想用同一个颜色清空绘图区,就没必需要再指定一次背景色。
gl.clear(gl.COLOR_BUFFER_BIT);
复制代码
函数参数是gl.COLOR_BUFFER_BIT
,这是由于WebGL中,gl.clear()方法实际上继承自OpenGL,它基于多基本缓冲区模型。这比二维绘图上下文复杂的多。清空绘图区域,实际上在清空颜色缓冲区,传递参数gl.COLOR_BUFFER_BIT就是告诉WebGL清空颜色缓冲区。除了颜色缓冲区,WebGL还有其余种类的缓冲区,好比深度缓冲区和模板缓冲区。
gl.clear(buffer)
的用法
buffer是指定待清空的颜色缓冲区,位操做符OR(|)可用于指定多个缓冲区
参数 | 含义 |
---|---|
gl.COLOR_BUFFER_BIT | 颜色缓冲区 |
gl.DEPTH_BUFFER_BIT | 深度缓冲区 |
gl.STENCIL_BUFFER_BIT | 指定模板缓冲区 |
返回值 | 无 |
错误 | INVALID_VALUE 缓冲区不是以上三种类型 |
以前的章节,咱们学习如何创建一个wegl程序,以及如何使用一些简单的webgl函数。这一节咱们将进一步在一个示例程序中绘制一个最简单的图形,一个点。
注意这里的html比上一次的html多了一些script。这些script是一些工具函数,避免重复的写大量的代码。代码很简单,能够直接打开查看。这里就不解释了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>webgl学习</title>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<!-- 引入几个webgl帮助函数,这里的代码很简单,你能够直接点击查看 -->
<script src="https://mycode04-1252305175.cos.ap-guangzhou.myqcloud.com/webgl-lib/lib/webgl-utils.js"></script>
<script src="https://mycode04-1252305175.cos.ap-guangzhou.myqcloud.com/webgl-lib/lib/webgl-debug.js"></script>
<script src="https://mycode04-1252305175.cos.ap-guangzhou.myqcloud.com/webgl-lib/lib/cuon-utils.js"></script>
<script src="./index.js"></script>
</body>
</html>
复制代码
javascript代码:
// 顶点着色器 注意这里的\n不能省略。不然不符合语法
var VSHADER_SOURCE = ` void main(){\n gl_Position = vec4(0.0,0.0,0.0,1.0);\n gl_PointSize = 10.0;\n }\n `
// 片断(片元)着色器
var FSHADER_SOURCE = ` void main(){\n gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n }\n `
function main() {
// 获取canvas
var canvas = document.getElementById('canvas')
// 获取webgl绘图上下文
var gl = canvas.getContext('webgl')
if (!gl) {
console.log('Failed to get the rendering context')
retun
}
// 初始化着色器函数
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log("设置着色器失败")
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)
}
window.onload = function () {
main()
}
复制代码
要使用webgl进行绘图必须使用着色器,在代码中,着色器是以字符串的形式“嵌入”到js中的。
webgl的着色器分两种
在三维场景中,仅仅用线条和颜色把图形画出来是远远不够的,必需要考虑光照上去或者观察者视角发生变化时,对场景有什么影响。着色器能够高度灵活的完成这些工做。提供各类渲染效果。
上述程序执行流程:
initShaders()
,该函数定义在cuon.util.js中,是专为本书编写的一个工具函数。其用法说明以下:
initShaders(gl,vshader,fshader) | ||
参数 | 取值 | 含义 |
gl | vshader | 指定顶点着色器程序代码 |
fshader | 指定片元着色器程序代码 | |
返回值 | true | 初始化着色器成功 |
fase | 初始化着色器失败 |
var VSHADER_SOURCE = ` void main(){\n gl_Position = vec4(0.0,0.0,0.0,1.0);\n gl_PointSize = 10.0;\n }\n `
复制代码
顶点着色器必须和c语言同样,必须包含一个main函数。main前面的void表示这个函数不会有返回值。
首先将顶点位置赋值给gl_Position变量。
在将顶点尺寸赋值给gl_PointSize。
这两个变量内置在顶点着色器中,有特殊的含义。以下:
类型和变量名 | 含义 |
---|---|
vec4 gl_Position | 表示顶点的位置 |
float gl_PointSize | 表示顶点的尺寸 |
vec4 表示由4个浮点数组成的矢量。
注意:GLSL ES是一种强类型编程语言,比10是整型,10.0就是浮点数,传错类型就会报错。
gl_Position其类型为vec4,可是咱们只有3个浮点数(0.0,0.0,0.0),既x、y、z坐标值。须要用某种方式把它转为vec4类型的变量。好在着色器为咱们提供了内置函数vec4(),帮助你建立vec4类型的变量。(原书中这一段有错误,已纠正)
在赋值gl_Position的矢量中,咱们添加了1.0做为第4个份量。由4个份量组成的矢量称为齐次坐标。,由于它可以提升处理三维数据的效率。因此被大量使用。虽然齐次坐标是四维的,可是若是最后一个份量为1.0,那么齐次坐标就能够表示“前三个份量为坐标值”的那个点。
片元着色器是用来设置颜色的,这里设置为红色。
var FSHADER_SOURCE = ` void main(){\n gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n }\n `
复制代码
gl_FragColor的用法以下:
类型和变量名 | 含义 |
---|---|
vec4 gl_FragColor | 指定片元颜色(RGBA格式) |
咱们使用drawArrays()进行绘制。
gl.drawArrays(gl.POINTS, 0, 1)
复制代码
gl.drawArrays(mode,first,count)
参数 | 含义 |
---|---|
mode | 指定绘制的方式,能够接受如下常量符号: gl.POINTS ,gl.LINES ,gl.LINE_STRIP ,gl.LINE_LOOP ,gl.TRIANGLES ,gl.TRIANGLE_STRIP ,gl.TRIANGLE_FAN |
first | 指定从哪一个点开始绘制 |
count | 指定绘制多少个点 |
错误 INVALID_ENUM | 传入的mode参数不是前述参数之一 |
错误 INVALID_VALUE | 参数first或者count为负数 |
总结:以上咱们简单介绍了两个webgl程序,并初步认识了着色器。后续的章节咱们将学习webgl的坐标系统和更多着色器的相关知识。欲知后事如何,请动动你的手指,关注下我,我会继续带来webgl的分享,哈哈