WebGL 绘制多彩的三角形 可用F12 开发者工具查看元素及样式,可打开 codepen 在线编辑代码。
< html>
< canvas id = " canvas" > </ canvas>
</ html>
< style>
body {
margin : 0;
overflow : hidden;
}
#canvas {
background-color : #911b1b;
}
</ style>
< script id = " vertexShader" type = " x-shader/x-vertex" >
attribute vec4 a_Position;
attribute vec4 a_Color;
varying vec4 v_Color;
void main ( ) {
gl_Position= a_Position;
gl_PointSize= 5.0 ;
v_Color = a_Color;
}
</ script>
< script id = " fragmentShader" type = " x-shader/x-fragment" >
precision mediump float;
varying vec4 v_Color;
void main ( ) {
gl_FragColor= v_Color;
}
</ script>
< script>
function initShaders ( gl, vsSource, fsSource ) {
const program = gl. createProgram ( ) ;
const vertexShader = loadShader ( gl, gl. VERTEX_SHADER , vsSource) ;
const fragmentShader = loadShader ( gl, gl. FRAGMENT_SHADER , fsSource) ;
gl. attachShader ( program, vertexShader) ;
gl. attachShader ( program, fragmentShader) ;
gl. linkProgram ( program) ;
gl. useProgram ( program) ;
gl. program = program;
return true ;
}
function loadShader ( gl, type, source ) {
const shader = gl. createShader ( type) ;
gl. shaderSource ( shader, source) ;
gl. compileShader ( shader) ;
return shader;
}
const canvas = document. querySelector ( "#canvas" ) ;
canvas. width = 600 ;
canvas. height = 150 ;
const vsSource = document. querySelector ( "#vertexShader" ) . innerText;
const fsSource = document. querySelector ( "#fragmentShader" ) . innerText;
const gl = canvas. getContext ( "webgl" ) ;
initShaders ( gl, vsSource, fsSource) ;
const vertices = new Float32Array ( [
- 0.25 ,
- 0.25 ,
1 ,
0 ,
0 ,
1 ,
0 ,
0.25 ,
0 ,
1 ,
0 ,
1 ,
0.25 ,
- 0.25 ,
0 ,
0 ,
1 ,
1 ,
] ) ;
const elementBytes = vertices. BYTES_PER_ELEMENT ;
const verticeSize = 2 ;
const colorSize = 4 ;
const categorySize = verticeSize + colorSize;
const categoryBytes = categorySize * elementBytes;
const verticeByteIndex = 0 ;
const colorByteIndex = verticeSize * elementBytes;
const sourceSize = vertices. length / categorySize;
const vertexBuffer = gl. createBuffer ( ) ;
gl. bindBuffer ( gl. ARRAY_BUFFER , vertexBuffer) ;
gl. bufferData ( gl. ARRAY_BUFFER , vertices, gl. STATIC_DRAW ) ;
const a_Position = gl. getAttribLocation ( gl. program, "a_Position" ) ;
gl. vertexAttribPointer (
a_Position,
verticeSize,
gl. FLOAT ,
false ,
categoryBytes,
verticeByteIndex
) ;
gl. enableVertexAttribArray ( a_Position) ;
const a_Color = gl. getAttribLocation ( gl. program, "a_Color" ) ;
gl. vertexAttribPointer (
a_Color,
colorSize,
gl. FLOAT ,
false ,
categoryBytes,
colorByteIndex
) ;
gl. enableVertexAttribArray ( a_Color) ;
gl. clearColor ( 255 , 255 , 255 , 1 ) ;
gl. clear ( gl. COLOR_BUFFER_BIT ) ;
gl. drawArrays ( gl. TRIANGLES , 0 , 3 ) ;
</ script>
</ html>
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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
Demo 在线地址:https://codepen.io/东流/pen/OJGpzMJ (opens new window)
2D 与 3D 2D 和 3D 可能会被认为是世界不同等级维度,比如纸片人和三维空间,实际上它们主要是人们对于对象的不同特征的描述方式。
2D 表示对象的宽度和高度这两个平面特征,而 3D 除了表示对象的平面特征之外,还包含对象空间特征深度属性。比如下面两张图都只是一个平面上的图形,但是分别描述了对象的不同特征,从而给我们带来了不同的 2D 和 3D 视觉上的不同感受。
WebGL
和 Canvas
的比较 Canvas
: canvas
使用 2D 渲染上下文来绘制图形和图像,是基于像素的绘图系统,通过 Javascript 脚本控制渲染过程
WebGL
: 基于 OpenGL ES 标准的 Javascript API,可以利用 GPU 进行硬件加速的 3D 图像渲染,需要使用着色器编程(shaders
)
WebGL 介绍 WebGL
,即 Web Graphics Library,是一种 3D 绘图协议,这一技术标准允许把 JavaScript 和 OpenGL ES 2.0 结合在一起,为 HTML5 Canvas 提供硬件 3D 加速渲染
着色器语言 着色器用 GLSL ES
(OpenGL Shading Language)语言编写,是一种强类型编程语言,语法和 C 语言有些类似,是在 OpenGL 的基础上进行了一定的精简,开发者可以通过着色器控制 GPU 来进去前端图形的渲染。
着色器分为顶点着色器(Vertex shader
)和片元着色器(Fragment shader
)
顶点着色器:用于描述顶点特性如位置、颜色等
片元着色器:进行逐片元处理过程如光照的程序
示例中的着色器如下
< script id = " vertexShader" type = " x-shader/x-vertex" >
attribute vec4 a_Position;
attribute vec4 a_Color;
varying vec4 v_Color;
void main ( ) {
gl_Position= a_Position;
gl_PointSize= 5.0 ;
v_Color = a_Color;
}
</ script>
< script id = " fragmentShader" type = " x-shader/x-fragment" >
precision mediump float;
varying vec4 v_Color;
void main ( ) {
gl_FragColor= v_Color;
}
</ script>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
渲染管线 渲染管线,就是图形渲染的过程,主要分为五个阶段:
1.顶点着色器阶段(Vertex Shader Stage
):顶点着色器对传入的顶点数据进行处理,通常用来进行坐标变换、光照计算等操作。
2.几何着色器阶段(Geometry Shader Stage
):几何着色器可以对图元进行进一步处理,生成新的顶点数据或者直接生成图元。
3.光栅化阶段(Rasterization Stage
):将图元转换为屏幕上的像素点。
4.片元处理阶段(Fragment Processing Stage
):对每个像素点进行处理,包括应用纹理、光照计算、颜色插值等操作。
5.像素操作阶段(Pixel Operations Stage
):最后对像素进行深度测试、模板测试、颜色混合等操作。
三角形是怎样出来的 颜色值的内插 在顶点着色器中向 varying
变量 v_Color
赋上这两个颜色(红色和蓝色),WebGL
会自动地计算出线段上的所有点(片元)的颜色,并赋值给片元着色器中的varying
变量 v_Color
线段上的所有片元的颜色值都会被恰当地计算出来——这个过程就被称为内插过程(interpolation process)