介绍
WebGL是一种JavaScript API,用于在不使用插件的情况下在任何兼容的网页浏览器中呈现交互式2D和3D图形。WebGL完全集成到浏览器的所有网页标准中,可将影像处理和效果的GPU加速使用方式当做网页Canvas的一部分。WebGL元素可以加入其他HTML元素之中并与网页或网页背景的其他部分混合。WebGL程序由JavaScript编写的句柄和OpenGL Shading Language(GLSL)编写的着色器代码组成,该语言类似于C或C++,并在电脑的图形处理器(GPU)上运行。WebGL由非营利Khronos Group设计和维护。
全篇目录
搭建开发环境
■ create object
1 2 3
| mkdir mywebgl cd mywebgl npm init
|
■ project folder
1 2 3 4 5 6 7 8 9
| ▾ src/ ▸ assets/ index.fs index.js index.vs index.html package-lock.json package.json webpack.config.js
|
■ webpack.config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = { entry: './src/index.js', plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ title: 'Output Management', template: './index.html' }) ], module: { rules: [ { test: /\.(png|jpg|gif|svg)$/, use: [ { loader: 'file-loader', options: {} } ] }, { test: /\.(glsl|vs|fs|vert|frag)$/, exclude: /node_modules/, use: ['raw-loader'] } ] }, devtool: 'inline-source-map', devServer: { contentBase: './dist' }, output: { filename: 'main.js', path: path.resolve(__dirname, 'dist') }, resolve: { alias: { '~': path.resolve(__dirname, 'src/'), '~assets': path.resolve(__dirname, 'src/assets') } } };
|
■ package.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| { "name": "mywebgl", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "webpack-dev-server", "build": "webpack --config webpack.config.js" }, "devDependencies": { "clean-webpack-plugin": "^3.0.0", "file-loader": "^4.2.0", "html-webpack-plugin": "^3.2.0", "raw-loader": "^3.1.0", "webpack": "^4.41.2", "webpack-cli": "^3.3.10", "webpack-dev-server": "^3.9.0" }, "author": "", "license": "ISC" }
|
■ index.html
1 2 3 4 5 6 7 8 9
| <!doctype html> <html> <head> <title>webgl demo</title> </head> <body> <canvas id='webgl' width='400' height='400'></canvas> </body> </html>
|
■ 以上配置完成后npm i
然后 npm run start
开始
■ 绘图过程
canvas 2D绘制过程
页面添加canvas元素 -> 获取2D画笔 -> 设置好画笔等 -> 清空屏幕(如果需要) -> 绘制(相应API)
canvas WebGL绘制过程
页面添加canvas元素 -> 获取3D画笔 -> 设置好着色器等 -> 清空屏幕(如果需要) -> 绘制(相应API)
可以看出来,主要是【设置好着色器等】这一步和之前的绘制方法不一样,因此,我们先来说明一下,什么是着色器?
■ 着色器
绘制三维图形的时候(以绘制一个点为例),你需要告诉他点的位置、尺寸和颜色,当你设置好这些以后就类似2D设置好画笔了,就可以绘制了,而这三个的设置就是设置着色器的过程。
■ 着色器种类
着色器分为二类:顶点着色器和片段着色器,前者控制位置和尺寸,后者控制颜色。
定点着色器
顶点着色器有二个固定的属性gl_Position和gl_PointSize,分别表示位置和尺寸:
■ index.vs
1 2 3 4
| void main(){ gl_Position=vec4(0.0,0.0,0.0,1.0); gl_PointSize=100.0; }
|
片段着色器有一个固定的属性gl_FragColor表示颜色:
■ index.fs
1 2 3
| void main(){ gl_FragColor=vec4(1.0,1.0,0.0,1.0); }
|
准备好这两段字符串后开始执行js调用webgl api
■ index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| import vsSource from '~/index.vs'; import fsSource from '~/index.fs';
const canvas = document.getElementById('webgl'); const gl = canvas.getContext('webgl');
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vsSource);
gl.compileShader(vertexShader);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fsSource);
gl.compileShader(fragmentShader);
var glProgram = gl.createProgram();
gl.attachShader(glProgram, vertexShader); gl.attachShader(glProgram, fragmentShader);
gl.linkProgram(glProgram);
gl.useProgram(glProgram);
gl.drawArrays(gl.POINTS, 0, 1);
|
■ 清空画布
1 2 3 4
| gl.clearColor(0.5, 0.5, 0.5, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
|