webGL多图纹理

146 阅读1分钟

效果展示

1733370703299.png

初始化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);
  });