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
| let textureList = [];
const VSHADER_SOURCE = ` attribute vec2 a_Position; // 顶点坐标 attribute vec2 a_PointUV; // 顶点UV varying vec2 v_PointUV;
void main(){ gl_Position = vec4(a_Position,0.0,1.0); v_PointUV = a_PointUV; } `; const FSHADER_SOURCE = ` precision mediump float; varying vec2 v_PointUV; uniform sampler2D u_Image; uniform sampler2D u_Image1; void main() { // 底层图片颜色 vec4 baseColor = texture2D(u_Image, v_PointUV); // 上层混合图片的颜色 vec4 blendColor = texture2D(u_Image1, v_PointUV); vec4 color = blendColor * baseColor; if(blendColor.a == 0.0){ color = baseColor; } gl_FragColor = color; } `;
const vShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vShader, VSHADER_SOURCE); gl.compileShader(vShader);
const fShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fShader, FSHADER_SOURCE); gl.compileShader(fShader);
const program = gl.createProgram() gl.attachShader(program, vShader) gl.attachShader(program, fShader) gl.linkProgram(program)
gl.useProgram(program) const bufferId = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, bufferId);
draw()
function random(min, max) { return min + Math.random() * (max - min); }
async function draw() { let data = [ -1, -1, 0, 0, 1, -1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 0, 1, -1, -1, 0, 0, ]; data = new Float32Array(data) await loadTextureImage(0, './images/1.jpeg') await loadTextureImage(1, './images/0.jpeg')
const FSIZE = data.BYTES_PER_ELEMENT;
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW); const a_Position = gl.getAttribLocation(program, 'a_Position'); gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 4, 0); gl.enableVertexAttribArray(a_Position);
const a_PointUV = gl.getAttribLocation(program, 'a_PointUV'); gl.vertexAttribPointer(a_PointUV, 2, gl.FLOAT, false, FSIZE * 4, FSIZE * 2); gl.enableVertexAttribArray(a_PointUV);
const u_Image = gl.getUniformLocation(program, "u_Image"); gl.activeTexture(gl.TEXTURE0 + 0); gl.bindTexture(gl.TEXTURE_2D, textureList[0]); gl.uniform1i(u_Image, 0);
const u_Image1 = gl.getUniformLocation(program, "u_Image1"); gl.activeTexture(gl.TEXTURE0 + 1); gl.bindTexture(gl.TEXTURE_2D, textureList[1]); gl.uniform1i(u_Image1, 1);
const u_TranslateImage = gl.getUniformLocation(program, "u_TranslateImage"); gl.uniform1f(u_TranslateImage, translateNumber);
gl.clearColor(1.0, 1.0, 1.0, 1.0); gl.clear(gl.COLOR_BUFFER_BIT); gl.drawArrays(gl.TRIANGLES, 0, data.length / 4) }
function isPowerOf2(value) { return (value & (value - 1)) === 0; }
function loadTextureImage(index, url) { return new Promise((resolve) => { const img = new Image(); img.src = url || './images/0.jpeg'; img.crossOrigin = 'anonymous' img.onload = () => { let texture = gl.createTexture(); textureList.push(texture) gl.bindTexture(gl.TEXTURE_2D, texture); gl.activeTexture(gl.TEXTURE0 + index); gl.bindTexture(gl.TEXTURE_2D, textureList[index]) gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img); if (isPowerOf2(img.width) && isPowerOf2(img.height)) { gl.generateMipmap(gl.TEXTURE_2D); } else { console.log("非2的整数次方"); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); }
resolve(texture) } }) }
|