渐变
前置工作,创建缓冲,对顶点着色器传递顶点数据
function main() {var canvas = document.getElementById('webgl');var gl = getWebGLContext(canvas);if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) returnvar n = initVertexBuffers(gl);
}function initVertexBuffers(gl) {var vertices = new Float32Array([-1, 1, -1, -1, 1, -1, 1, 1]);var n = 4;var a_Position = gl.getAttribLocation(gl.program, 'a_Position');var vertexBuffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);gl.enableVertexAttribArray(a_Position);return n;
}
顶点着色
var VSHADER_SOURCE ='attribute vec4 a_Position;\n' +'void main() {\n' +' gl_Position = a_Position;\n' +'}\n';
思考,最终操作改变每个片元的颜色,就是根据uv坐标的不同逐片元计算,使用cos控制周期性效果
uv坐标:二维空间每个像素绝对位置(0,0 ~ 宽高) gl_FragCoord.xy / 设备分辨率
cos周期变化:delta时间,每帧间隔为主键
对片元着色传递这些控制变量
let time = Date.now();let iTime = 0;let iResolutionAddr = gl.getUniformLocation(gl.program, "iResolution");let iTimeAddr = gl.getUniformLocation(gl.program, "iTime");gl.clear(gl.COLOR_BUFFER_BIT);let loop = () => {let nowTime = Date.now();let dt = (nowTime - time) * 0.002;iTime += dt;time = nowTime;gl.uniform2f(iResolutionAddr, 1536, 865); // 传递分辨率gl.uniform1f(iTimeAddr, iTime); // 传递时间gl.clearColor(0, 0, 0, 0);gl.drawArrays(gl.TRIANGLE_FAN, 0, n);requestAnimationFrame(loop);};loop();
片元着色
var FSHADER_SOURCE ='#ifdef GL_ES\n' +'precision mediump float;\n' +'#endif\n' +'uniform vec2 iResolution;\n' + // 屏幕分辨率'uniform float iTime;\n' +'void main() {\n' +'vec2 uv = gl_FragCoord.xy / iResolution;' + // 计算uv 0~1// cos 分别计算 v.x, v.y, v.z 的余弦值,返回 vec3(-1~1, -1~1, -1~1)'vec3 c = 0.5 + 0.5 * cos(iTime + uv.xyx + vec3(0, 2, 4));' + // vec3 0~1 'gl_FragColor = vec4(c, 1.0);\n' +'}\n';