WebGL学习笔记(1)
基本的WebGL图形操作(详细参考教程:https://www.yiibai.com/webgl,需要1周左右熟悉webgl的对象方法以及着色器代码):
绘制三角形 drawElements gl.TRIANGLES
绘制矩形 drawElements 通过绘制两个三角形实现
绘制点 drawElements POINTS
绘制线 drawElements gl.LINE,LINE_STRIP,LINE_LOOP
将绘制的图形填充颜色(使用attribute color,main中传递给varying vColor,在片元着色器中赋值给gl_FragColor)
图形平移(使用uniform location变量,与gl_Position 相加)
图形缩放(使用uniform mat4矩阵,定义缩放大小矩阵,矩阵条目的每行数据乘以顶点的每列数据,矩阵相乘参考:https://blog.csdn.net/jacke121/article/details/68484813)
绘制代码流程记要(此处简单说明变量名及方法名,文章末尾包含了具体测试代码):
1. 声明顶点数组 vertices
2. 声明顶点索引 indices
3. 声明颜色数组 colors
4. 创建顶点/索引/颜色缓冲对象 gl.createBuffer,gl.bindBuffer(gl.ARRARY_BUFFER,new Float32Array(…), gl.STATIC_DRAW),gl.bufferData
5. 声明GLSL顶点/片段着色器代码
6. 创建顶点/片段着色器对象并创建着色程序与之关联 gl.createShader(gl.VERTEX_SHADER),gl.attachShader, gl.compileShader,gl.createProgram,gl.attachShader,gl.linkProgram,gl.useProgram
7. 写入缓冲对象数据到着色程序 gl.getAttribLocation, gl.vertexAttribPointer(position, 3, gl.FLOAT, flase,0,0),gl.getUniformLocation,gl.uniform4f
8. 绘制图形 gl.clearColor,gl.enable,gl.clear,gl.viewport,gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0),gl.drawArrays(gl.POINTS, 0, vertices.length/3 )
后续需要研究:
缩放
旋转
立方体旋转
交互式立方体
着重点笔记:
GSSL里的修饰符
attribute 每个顶点数据的顶点着色器与OpenGL ES 之间的链接,每次执行时变化
Uniform 平移位置:使用gl.getUniformLocation获取变量,使用gl.uniform4f(变量,向量) 改变位置,使用gl.uniformMatrix4fv(location, transpose(设置为false),值)设置矩阵
Varying 传递给顶点着色器的变量
GSSL里的数据类型
Vec3 :存储3个值的数组类型
vec4:存储4个值的数组类型
Mat3:存储3个vec3的矩阵类型
Mat4:存储4个vec4的矩阵类型
顶点着色器预定义变量
Highp vec4 gl_Position 保存顶点的位置
Mediump float gl_PointSize 保存变换点的大小
片元着色器代码注意添加 Precision mediump float;
示例GLSL代码:
var vertCode = `
attribute vec3 position;
attribute vec3 color;
varying vec3 vColor;
uniform vec3 translation;
void main(void){
gl_Position = vec4(position, 1.0)+ vec4(translation, 1.0);
gl_PointSize = 10.0;
vColor = color;
}
`
var fragCode = `
precision mediump float;
varying vec3 vColor;
void main(void){
gl_FragColor = vec4(vColor, 1.0);
}
`
测试代码,需要自己写一下html
var canvas = document.getElementById('my_Canvas')
var gl = canvas.getContext('experimental-webgl')
var vertices = [
-0.5, 0.5, 0.0,
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0,
]
var indices = [
0,1,2
]
var colors = [
0,1,1, ,0,1,1, 0,1,1
]
var vertex_buffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer)
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW)
gl.bindBuffer(gl.ARRAY_BUFFER, null)
var index_buffer = gl.createBuffer()
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer)
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW)
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null)
var color_buffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer)
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW)
gl.bindBuffer(gl.ARRAY_BUFFER, null)
var vertCode = `
attribute vec3 position;
attribute vec3 color;
varying vec3 vColor;
uniform vec3 translation;
uniform mat4 u_xformMatrix;
void main(void){
gl_Position = ( vec4(position, 1.0)+ vec4(translation, 1.0) ) * u_xformMatrix ;
gl_PointSize = 10.0;
vColor = color;
}
`
var fragCode = `
precision mediump float;
varying vec3 vColor;
void main(void){
gl_FragColor = vec4(vColor, 1.0);
}
`
var vertShader = gl.createShader(gl.VERTEX_SHADER)
gl.shaderSource(vertShader, vertCode)
gl.compileShader(vertShader)
var fragShader = gl.createShader(gl.FRAGMENT_SHADER)
gl.shaderSource(fragShader, fragCode)
gl.compileShader(fragShader)
var shaderProgram = gl.createProgram()
gl.attachShader(shaderProgram, vertShader)
gl.attachShader(shaderProgram, fragShader)
gl.linkProgram(shaderProgram)
gl.useProgram(shaderProgram)
//缩放
/*
三角形的3个顶点坐标mat4
vertices = [
-0.5, 0.5, 0.0, 1.0 //第1个顶点 ,在左上角,注意这里是1个gl_Position的position
-0.5, -0.5, 0.0, 1.0 //第2个顶点, 在左下角
0.5, -0.5, 0.0, 1.0 //第3个顶点,在右下角
]
第1个顶点坐标的vec4
position = [-0.5, 0.5, 0.0, 1.0]
缩放矩阵mat4与 顶点坐标vec4相乘,实现缩放
position * u_xformMatrix;
*/
var x = 1.5, y=1.5, z= 1
var xformMatrix = [
x, 0.0, 0.0, 0.0, // 乘顶点数据条目的第1个坐标位置
0.0, y, 0.0, 0.0, // 乘顶点数据条目的第2个坐标位置
0.0, 0.0, z, 0.0, // 乘顶点数据条目的第3个坐标位置
0.0, 0.0, 0.0, 1.0, // 此处相乘的是gl_Position里定义的一个1.0固定值, 即最后1个顶点的数组键值
]
/*
最终得到第1个顶点坐标的缩放结果为:
position = [-0.75, 0.75, 0.0 ,1.0 ],得到 第1个顶点的x轴向左移动,y轴向上移动,实现了三角形的缩放变大
即xformMatrix的每行行(x,y,z轴新坐标)与 vertices的每列数据(每个顶点的x,y,z轴坐标)相乘,实现了缩放
*/
var u_xformMatrix = gl.getUniformLocation(shaderProgram, 'u_xformMatrix')
gl.uniformMatrix4fv(u_xformMatrix, false, new Float32Array(xformMatrix))
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer)
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer)
var position = gl.getAttribLocation(shaderProgram, 'position')
gl.vertexAttribPointer(position, 3, gl.FLOAT, false, 0, 0)
gl.enableVertexAttribArray(position)
gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer)
var color = gl.getAttribLocation(shaderProgram, 'color')
gl.vertexAttribPointer(color, 3, gl.FLOAT, false, 0, 0)
gl.enableVertexAttribArray(color)
//平移
var translation = gl.getUniformLocation(shaderProgram, 'translation')
//会对vertices的3个顶点的x,y,z坐标进行相加实现平移,比如
/*
原vertices 顶点的坐标如下:
position = [
-0.5, 0.5, 0.0, 1.0 第1个顶点,相加后变成了 -0.3, 0.4, -0.1 即 第1个顶点的x轴向右平移 y轴向下平移
-0.5, -0.5, 0.0, 1.0 第2个顶点,相加后变成了 -0.3, -0.6, -0.1 即 第2个顶点的x轴向右平移 y轴向下平移
0.5, -0.5, 0.0, 1.0 第3个顶点,相加后变成了 0.7, -0.6, -0.1 即 第3个顶点的x轴向右平移 y轴向下平移
]
这样三角形的3个顶点都进行的平移
*/
gl.uniform3f(translation, 0.2,-0.1,-0.1)
gl.clearColor(1.0, 1.0, 1.0, 1.0)
gl.enable(gl.DEPTH_TEST)
gl.clear(gl.COLOR_BUFFER_BIT)
gl.viewport(0, 0, canvas.width, canvas.height)
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0)