效果展示
初始化shader着色器
WebGL中mix函数用于合成两个颜色得到一个新的颜色 mix(x,y,a)=x*(1-a)+y*a,通常用于渐变
<script id="vertexSource" type="x-shader/v-vertex">
attribute vec4 a_Position;
attribute vec2 a_Color;
varying vec2 v_Color;
void main(){
gl_Position= a_Position ;
gl_PointSize= 20.0;
v_Color = a_Color;
}
</script>
<script id="fragmentSource" type="x-shader/v-fragment">
precision highp float;
uniform sampler2D u_Sampler1;
uniform sampler2D u_Sampler2;
varying vec2 v_Color;
void main(){
vec4 color1= texture2D(u_Sampler1,v_Color);
vec4 color2= texture2D(u_Sampler2,v_Color);
gl_FragColor= mix(color1,color2,0.4);
}
</script>
着色器编译
const vsSource = document.getElementById("vertexSource").innerText;
const fsSource = document.getElementById("fragmentSource").innerText;
export const initShader = (gl, vertexSource, fragmentSource) => {
let vertexShader = gl.createShader(gl.VERTEX_SHADER);
let fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertexShader, vertexSource);
gl.shaderSource(fragmentShader, fragmentSource);
gl.compileShader(vertexShader);
gl.compileShader(fragmentShader);
let program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
return program;
};
let program = initShader(gl, vsSource, fsSource);
buffer数据
let points = new Float32Array([
-0.5, 1, 0.0, 1.0, //
-0.5, -1,0.0,0.0, //
0.5,1,1.0,1.0, //
0.5,-1,1.0,0.0, //
]);
let buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);
let postionsLocation = gl.getAttribLocation(program, "a_Position");
let colorLocation = gl.getAttribLocation(program, "a_Color");
gl.vertexAttribPointer(
postionsLocation,
2,
gl.FLOAT,
false,
4 * Float32Array.BYTES_PER_ELEMENT,
0
);
gl.enableVertexAttribArray(postionsLocation);
gl.vertexAttribPointer(
colorLocation,
2,
gl.FLOAT,
false,
4 * Float32Array.BYTES_PER_ELEMENT,
2 * Float32Array.BYTES_PER_ELEMENT
);
gl.enableVertexAttribArray(colorLocation);
纹理加载
let texture0 = gl.createTexture(); //
let texture1 = gl.createTexture();
let p1 = imageLoad("./back.png");
let p2 = imageLoad("./tree.png");
Promise.all([p1, p2]).then((res) => {
res.forEach((img, index) => {
if (index == 0) {
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture0);
} else {
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, texture1);
}
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGB,
gl.RGB,
gl.UNSIGNED_BYTE,
img
);
gl.uniform1i(Sampler2Location, index);
});
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
});