webGL
@
基础使用
const ctx =document.getElementById('canvas').getContext('webgl');
ctx.clearColor(0.0, 0.0, 0.0, 1.0); //清空颜色
ctx.clear(ctx.COLOR_BUFFER_BIT); //
//.COLOR_BUFFER_BIT 清空颜色缓存 ctx.clearColor(0.0, 0.0, 0.0, 1.0)
//DEPTH_BUFFER_BIT 清空深度缓冲区 搭配 gl.clearDepth(1.0)
//STENCIL_BUFFER_BIT 清空模板缓冲区 搭配 gl.clearStencil(0)
基础着色器封装
function initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE) {
const vertexShader = gl.createShader(gl.VERTEX_SHADER); //创建顶点着色器
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); // 创建片元着色器
gl.shaderSource(vertexShader, VERTEX_SHADER_SOURCE) // 指定顶点着色器的源码
gl.shaderSource(fragmentShader, FRAGMENT_SHADER_SOURCE) // 指定片元着色器的源码
// 编译着色器
gl.compileShader(vertexShader)
gl.compileShader(fragmentShader)
// 创建一个程序对象
const program = gl.createProgram();
gl.attachShader(program, vertexShader) //关联着色器
gl.attachShader(program, fragmentShader)//关联着色器
gl.linkProgram(program)//关联程序对象
gl.useProgram(program)//使用程序对象
return program;
}
创建变量并使用attribute变量和 uniform变量
const ctx = document.getElementById('canvas')
const gl = ctx.getContext('webgl')
// 创建着色器源码
const VERTEX_SHADER_SOURCE = `
// 只传递顶点数据
attribute vec4 aPosition; //创建aPosition变量
void main() {
gl_Position = aPosition; // vec4(0.0,0.0,0.0,1.0)
gl_PointSize = 30.0;
}
`; // 顶点着色器
const FRAGMENT_SHADER_SOURCE = `
precision mediump float; //指定精度
uniform vec2 uColor;
void main() {
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
`; // 片元着色器
const program = initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)
const aPosition = gl.getAttribLocation(program, 'aPosition'); //获取aPosition变量
const uColor = gl.getUniformLocation(program, 'uColor') //获取uColor变量
// gl.vertexAttrib4f(aPosition, 0.5,0.5,0.0,1.0)
// gl.vertexAttrib3f(aPosition, 0.5,0.5,0.0)
// gl.vertexAttrib2f(aPosition, 0.5,0.5)
let x = 0;
setInterval(() => {
x += 0.1;
if (x > 1.0) {
x = 0;
}
gl.vertexAttrib1f(aPosition, x) //修改值
gl.drawArrays(gl.POINTS, 0, 1); //重新绘制
}, 200)
点击绘制事件
ctx.onclick = function(ev) {
// 坐标
const x = ev.clientX //获取点击坐标
const y = ev.clientY//获取点击坐标
const domPosition = ev.target.getBoundingClientRect();
const domx = x - domPosition.left //计算出canvas坐标
const domy = y - domPosition.top;
const halfWidth = ctx.offsetWidth / 2
const halfHeight = ctx.offsetHeight / 2
const clickX = (domx - halfWidth) / halfWidth //计算出webgl坐标
const clickY = (halfHeight - domy) / halfHeight
points.push({
clickX, clickY
})
for (let i = 0; i < points.length; i++) {
gl.vertexAttrib2f(aPosition, points[i].clickX, points[i].clickY) //设置位置
gl.uniform2f(uColor, points[i].clickX, points[i].clickY)//设置颜色
gl.drawArrays(gl.POINTS, 0, 1);
}
}
着色器使用
const ctx = document.getElementById('canvas')
const gl = ctx.getContext('webgl')
// 创建着色器源码
const VERTEX_SHADER_SOURCE = `
// 只传递顶点数据
attribute vec4 aPosition; //创建aPosition变量
attribute float aSize;
void main() {
gl_Position = aPosition; // vec4(0.0,0.0,0.0,1.0)
gl_PointSize = aSize;
}
`; // 顶点着色器
const FRAGMENT_SHADER_SOURCE = `
precision mediump float; //指定精度
uniform vec2 uColor;
void main() {
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
`; // 片元着色器
const program = initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)
const aPosition = gl.getAttribLocation(program, 'aPosition'); //获取aPosition变量
const uColor = gl.getUniformLocation(program, 'uColor') //获取uColor变量
const aSize = gl.getAttribLocation(program, 'aSize')
// gl.vertexAttrib4f(aPosition, 0.5,0.5,0.0,1.0)
// gl.vertexAttrib3f(aPosition, 0.5,0.5,0.0)
// gl.vertexAttrib2f(aPosition, 0.5,0.5)
const points = new Float32Array([
-0.5, -0.5, 30.0,
0.5, -0.5, 30.0,
0.0, 0.5, 20.0,
])
const buffer = gl.createBuffer(); //创建缓冲区对象
gl.bindBuffer(gl.ARRAY_BUFFER, buffer); //将缓冲区对象绑定到目标
//gl.ARRAY_BUFFER 表示缓冲区储存的是顶点的数据
//gl.ElEMENT_ARRAY_BUFFER 表示缓冲区储存的是顶点的索引值
gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW); //向缓冲区对象写入数据
//gl.STATIC_DRAW
//数据不会或几乎不会改变。
//gl.STREAM_DRAW
//数据每次绘制时都会改变。
//gl.DYNAMIC_DRAW
//数据每次绘制时都会改变,并且绘制之间还会改变。
const BYTES = points.BYTES_PER_ELEMENT
gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, BYTES * 3, 0); //将缓冲区对象分配给aPosition变量
gl.vertexAttribPointer(aSize, 1, gl.FLOAT, false, BYTES * 3, BYTES * 2);
// gl.vertexAttribPointer(
// aPosition, //
// 指定每个顶点所使用数据的个数,
// 指定数据格式, gl.FlOAT gl.SHORT短整型 gl.UNSIGNED_BYTE 无符号字节 gl.INT整型 gl.UNSIGNED_SHORT无符号短整型 gl.UNSIGNED_INT无符号整型
// 是否将数据归一化到[0,1][-1,1 ]这个区间
// 指定连续两个顶点之间的字节数(如果是非整数数据,需要指定字节数),
// 数据偏移量
// )
gl.enableVertexAttribArray(aPosition); //连接aPosition变量与分配给它的缓冲区对象
gl.enableVertexAttribArray(aSize); //连接aPosition变量与分配给它的缓冲区对象
gl.drawArrays(gl.POINTS, 0, 3); //重新绘制(绘制什么图形,从第几个开始绘制,绘制个数)
//gl.LINE_LOOP 绘制闭合线段
//gl.TRIANGLES 绘制填充矩形
gl.drawArrays

2024-03-15
未分类
评论