WebGL绘制一个点
- 超文本语言HTML
- 脚本语言Javascript
- Canvas画布
- 着色器语言GLSL ES
- WebGL API
绘制点像素点的html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用WebGL绘制一个点</title>
</head>
<body>
<!--canvas标签创建一个宽高均为500像素,背景为蓝色的矩形画布-->
<canvas id="webgl" width="500" height="500" style="background-color: blue"></canvas>
<script>
//通过getElementById()方法获取canvas画布
var canvas=document.getElementById('webgl');
//通过方法getContext()获取WebGL上下文
var gl=canvas.getContext('webgl');
//顶点着色器源码
var vertexShaderSource = '' +
'void main(){' +
//给内置变量gl_PointSize赋值像素大小
' gl_PointSize=50.0;' +
//顶点位置,位于坐标原点
' gl_Position =vec4(0.0,0.0,0.0,1.0);' +
'}';
//片元着色器源码
var fragShaderSource = '' +
'void main(){' +
//定义片元颜色
' gl_FragColor = vec4(1.0,0.0,0.0,1.0);' +
'}';
//初始化着色器
var program = initShader(gl,vertexShaderSource,fragShaderSource);
//开始绘制,显示器显示结果
gl.drawArrays(gl.POINTS,0,1);
//声明初始化着色器函数
function initShader(gl,vertexShaderSource,fragmentShaderSource){
//创建顶点着色器对象
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
//创建片元着色器对象
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
//引入顶点、片元着色器源代码
gl.shaderSource(vertexShader,vertexShaderSource);
gl.shaderSource(fragmentShader,fragmentShaderSource);
//编译顶点、片元着色器
gl.compileShader(vertexShader);
gl.compileShader(fragmentShader);
//创建程序对象program
var program = gl.createProgram();
//附着顶点着色器和片元着色器到program
gl.attachShader(program,vertexShader);
gl.attachShader(program,fragmentShader);
//链接program
gl.linkProgram(program);
//使用program
gl.useProgram(program);
//返回程序program对象
return program;
}
</script>
</body>
</html>
演示效果
创建Canvas画布
Canvas画布,显示WebGL的渲染结果,canvas元素和div等元素一样是HTML的一个元素,只是Canvas画布具有2D和3D绘图功能
<!--canvas标签创建一个宽高均为500像素,背景为蓝色的矩形画布-->
<canvas id="webgl" width="500" height="500" style="background-color: blue"></canvas>
通过JavaScript获取上面创建的Canvas元素返回一个Canvas对象。
//通过getElementById()方法获取canvas画布对象
var canvas= document.getElementById('webgl')
canvas对象也可以不通过<canvas>
标签创建,然后id方式获取,也可以通过DOM直接创建
//通过getElementById()方法获取canvas画布对象
var canvas = document.createElement('canvas');
Canvas对象方法.getContext()
HTML的Canvas元素提供了2D和3D绘图两种功能,平时程序员之间交流所说的Canvas一词就是指Canvas的2D绘图功能,通过Canvas元素实现的3D绘图功能,也就是所谓的WebGL,或者说WebGL依赖于Canvas
元素实现。
执行canvas.getContext('2d')返回对象具有一系列绘制二维图形的方法,比如绘制直线、圆弧等API。
//通过方法getContext()获取Canvas 2D绘图上下文
var gl=canvas.getContext('2d');
c.moveTo(0,0);//直线起点坐标
c.lineTo(50,50);//直线第2个点坐标
c.lineTo(0,100);//直线第3个点坐标
c.stroke();//把点连成直线绘制出来
执行canvas.getContext('webgl');
返回对象具有一系列绘制渲染三维场景
的方法,也就是WebGL API
//通过方法getContext()获取WebGL上下文
var gl=canvas.getContext('webgl');
...
//调用WebGL API绘制渲染方法drawArrays
gl.drawArrays(gl.POINTS,0,1);
着色器语言GLSL ES
//顶点着色器源码
var vertexShaderSource = '' +
'void main(){' +
//给内置变量gl_PointSize赋值像素大小
' gl_PointSize=20.0;' +
//顶点位置,位于坐标原点
' gl_Position =vec4(0.0,0.0,0.0,1.0);' +
'}';
片元着色器定义了点的渲染结果像素的颜色值
//片元着色器源码
var fragShaderSource = '' +
'void main(){' +
//定义片元颜色
' gl_FragColor = vec4(1.0,0.0,0.0,1.0);' +
'}';
gl_PointSize、gl_Position、gl_FragColor都是内置变量
通过程序可以看出来顶点着色器源码vertexShaderSource、片元着色器源码fragShaderSource,都是只有一个主函数main,也就是入口函数。
给内置变量gl_Position赋值vec4(0.0,0.0,0.0,1.0),也就是设置顶点位置坐标,vec4代表的是一种数据类型, 在这里可以理解为vec4()是一个可以构造出vec4类型数据的构造函数,前三个参数表示顶点坐标值xyz。
给内置变量gl_FragColor赋值vec4(1.0,0.0,0.0,1.0),也就是设置会在屏幕上显示的像素的颜色,vec4()构造函数 前三个参数,表示颜色RGB值,最后一个参数是透明度A。在WebGL着色器中颜色值使用[0,1]区间表示。
你可以通过改变WebGL着色器代码内置变量gl_PointSize、gl_Position、gl_FragColor测试WebGL渲染效果的变化。
- gl_PointSize=50.0改为gl_PointSize=10.0,观察屏幕点的大小变化
- gl_Position =vec4(0.5,0.5,0.0,1.0)改为gl_Position =vec4(0.5,-0.8,0.0,1.0),观察屏幕点的位置变化
- gl_FragColor=vec4(0.0,1.0,1.0,1.0)更改为gl_FragColor = vec4(0.0,0.0,1.0,1.0)
理解gl_FragColor=vec4(r,g,b,alpha)
WebGL API
WebGL API指的就是gl=canvas.getContext('webgl')返回对象gl的一系列绘制渲染方法,通过WebGL API可以把一个三维场景绘制渲染出来。比如上面代码中gl.createShader()、gl.shaderSource()、gl.drawArrays()等方法就是WebGl API
初始化着色器函数initShader()
//声明初始化着色器函数
function initShader(gl,vertexShaderSource,fragmentShaderSource){
//创建顶点着色器对象
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
//创建片元着色器对象
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
//引入顶点、片元着色器源代码
gl.shaderSource(vertexShader,vertexShaderSource);
gl.shaderSource(fragmentShader,fragmentShaderSource);
//编译顶点、片元着色器
gl.compileShader(vertexShader);
gl.compileShader(fragmentShader);
//创建程序对象program
var program = gl.createProgram();
//附着顶点着色器和片元着色器到program
gl.attachShader(program,vertexShader);
gl.attachShader(program,fragmentShader);
//链接program
gl.linkProgram(program);
//使用program
gl.useProgram(program);
//返回程序program对象
return program;
}
绘制方法gl.drawArrays()
gl.drawArrays()方法的作用就是通知GPU执行着色器代码,然后根据着色器代码在Canvas画布上进行渲染绘制。
着色器代码放在script标签中
<!-- 顶点着色器源码 -->
<script id="vertexShader" type="x-shader/x-vertex">
void main() {
//给内置变量gl_PointSize赋值像素大小
gl_PointSize=20.0;
//顶点位置,位于坐标原点
gl_Position =vec4(0.0,0.0,0.0,1.0);
}
</script>
<!-- 片元着色器源码 -->
<script id="fragmentShader" type="x-shader/x-fragment">
void main() {
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
</script>
//顶点着色器源码
var vertexShaderSource = document.getElementById('vertexShader').innerText;
//片元着色器源码
var fragShaderSource = document.getElementById('fragmentShader').innerText;
//初始化着色器
var program = initShader(gl,vertexShaderSource,fragShaderSource);