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对象也可以不通过标签创建,然后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);
读书人借书之道,原文链接