移除 TWGL 中的蓝色方块

Remove blue square in TWGL

我的问题是我正在使用 TWGL 库制作带有纹理的着色器,当它们加载图像时,加载前总是出现一个蓝色框。我找不到关于该问题的任何信息,也没有在文档中找到任何信息,甚至在其他作品中也找不到。

如何删除那个蓝框?

"use strict";

class MathUtils {
  constructor() {}

  lerp(a, b, n) {
    return n * (b - a) + a;
  }
}

const main = () => {
  const canvas = document.getElementById("canvas");
  const gl = canvas.getContext("webgl");
  const mathUtils = new MathUtils();
  const mouse = { x: 0, y: 0 };
  const lastmouse = [0, 0];
  if (!gl) {
    return;
  }
  
  const textures = [
    "https://i.ibb.co/9WvFgbZ/fancycrave-165873-unsplash.jpg",
    "https://i.ibb.co/NSfVqTq/map2.jpg",
    "https://i.ibb.co/cy79kN4/blur.jpg"
  ];
  const textLoaded = [];
  for (let tex of textures) {
    textLoaded.push(
      twgl.createTexture(gl, {
        src: tex,
        crossOrigin: ""
      })
    );
  }

  let originalImage = { width: 1, height: 1 }; // replaced after loading
  const text0 = twgl.createTexture(
    gl,
    {
      src: textures[0],
      crossOrigin: ""
    },
    (err, texture, source) => {
      originalImage = source;
    }
  );

  let uniforms = {};
  let anim = { value: 1 };
  // compile shaders, link program, lookup location
  const programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);

  // calls gl.createBuffer, gl.bindBuffer, gl.bufferData for a quad
  const bufferInfo = twgl.primitives.createXYQuadBufferInfo(gl);

  const render = time => {
    time *= 0.001; // seconds

    twgl.resizeCanvasToDisplaySize(gl.canvas);

    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

    gl.clearColor(0, 0, 0, 0);
    gl.clear(gl.COLOR_BUFFER_BIT);

    gl.useProgram(programInfo.program);

    // calls gl.bindBuffer, gl.enableVertexAttribArray, gl.vertexAttribPointer
    twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);

    const canvasAspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
    const imageAspect = originalImage.width / originalImage.height;
    let mat = m3.scaling(imageAspect / canvasAspect, -1);

    // this assumes we want to fill vertically
    let horizontalDrawAspect = imageAspect / canvasAspect;
    let verticalDrawAspect = -1;
    // does it fill horizontally?
    if (horizontalDrawAspect < 1) {
      // no it does not so scale so we fill horizontally and
      // adjust vertical to match
      verticalDrawAspect /= horizontalDrawAspect;
      horizontalDrawAspect = 1;
    }
    mat = m3.scaling(horizontalDrawAspect, verticalDrawAspect);

    uniforms = {
      u_text: textLoaded[0],
      u_map: textLoaded[1],
      u_blur: textLoaded[2],
      u_matrix: mat,
      u_time: time * 10,
      u_res: [gl.canvas.clientWidth, gl.canvas.clientHeight],
      u_mouse: lastmouse
    };

    // calls gl.activeTexture, gl.bindTexture, gl.uniformXXX
    twgl.setUniforms(programInfo, uniforms);

    // calls gl.drawArrays or gl.drawElements
    twgl.drawBufferInfo(gl, bufferInfo);

    lastmouse[0] = mathUtils.lerp(lastmouse[0], mouse.x, 0.1);
    lastmouse[1] = mathUtils.lerp(lastmouse[1], mouse.y, 0.1);

    requestAnimationFrame(render);
  };
  requestAnimationFrame(render);

  canvas.addEventListener("mousemove", ({ clientX, clientY }) => {
    mouse.x = -clientX / innerWidth;
    mouse.y = -clientY / innerHeight;
  });
};

main();
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
<canvas id="canvas"></canvas>
<script id="vs" type="f">
  attribute vec2 position;
  attribute vec2 texcoord;

  uniform mat3 u_matrix;

  varying vec2 v_texcoord;

  void main() {
     gl_Position = vec4(u_matrix * vec3(position, 1), 1);
     v_texcoord = texcoord;
  }
</script>
<script id="fs" type="f">
  precision mediump float;
  
  uniform vec2 u_mouse;
  uniform vec2 u_res;
  uniform float u_time;
  uniform float u_dpi;
  uniform sampler2D u_text;
  uniform sampler2D u_map;
  uniform sampler2D u_blur;

  varying vec2 v_texcoord;
   
  void main(){
    float distAmount = .003;
      
    vec2 uv = v_texcoord; 
    vec2 parallax = u_mouse * 0.07;
    
    float freq = 70.0;
    float amp = 0.004;
    
    vec4 map = texture2D(u_map, uv);

    float dethMap = map.r - .5;
    float distMap = map.g;

    float x = uv.y * freq + u_time * 3.; 
    float y = uv.x * freq + u_time * .3;
    
    float distX = cos(x+y) * amp * cos(y);
    float distY = sin(x-y) * amp * cos(y);

    vec2 distPosition = vec2(uv.x + distX * distMap, uv.y + distY * distMap);
       
    vec2 turbulance = distPosition + (parallax * dethMap);
    
    vec4 ori_img = texture2D(u_text, turbulance);
    vec4 blur_img = texture2D(u_blur, turbulance);
        
    vec4 color = mix(ori_img, blur_img, length(distPosition) * distAmount);
    
    gl_FragColor = color;
  }  
</script>
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<script src="https://webglfundamentals.org/webgl/resources/m3.js"></script>

我没有看到任何蓝框

您可以设置默认颜色 twgl 用于通过调用

使纹理立即可用
twgl.setDefaults({
  textureColor: [0, 0, 0, 0],  // make initial color transparent black
});

加载纹理之前。

您可以通过 color 选项设置任何单个纹理的临时初始颜色

const texture = twgl.createTexture(gl, {
  src: 'https://somedomain.com/path/to/someimage.jpg',
  color: [0, 0, 0, 0],  // make initial color transparent black
});

另请注意,您可以在对 twgl.createTextures 的一次调用中加载所有图像,并且 twgl 应自动处理交叉原点

  // replaced after loading
  let srcs = {
    text: { width: 1, height: 1 },
  };
  const textures = twgl.createTextures(gl, {
    text: {src: "https://i.ibb.co/9WvFgbZ/fancycrave-165873-unsplash.jpg" },
    map: {src: "https://i.ibb.co/NSfVqTq/map2.jpg" },
    blur: {src: "https://i.ibb.co/cy79kN4/blur.jpg" },
  }, (err, textures, sources) => {
    srcs = sources;
  });
const imageAspect = srcs.text.width / srcs.text.height;
        uniforms = {
          u_text: textures.text,
          u_map: textures.map,
          u_blur: textures.blur,
        ...

"use strict";

class MathUtils {
  constructor() {}

  lerp(a, b, n) {
    return n * (b - a) + a;
  }
}

const main = () => {
  const canvas = document.getElementById("canvas");
  const gl = canvas.getContext("webgl");
  const mathUtils = new MathUtils();
  const mouse = { x: 0, y: 0 };
  const lastmouse = [0, 0];
  if (!gl) {
    return;
  }
  
  twgl.setDefaults({
    textureColor: [0, 0, 0, 0],
  });
  // replaced after loading
  let srcs = {
    text: { width: 1, height: 1 },
  };
  const textures = twgl.createTextures(gl, {
    text: {src: "https://i.ibb.co/9WvFgbZ/fancycrave-165873-unsplash.jpg" },
    map: {src: "https://i.ibb.co/NSfVqTq/map2.jpg" },
    blur: {src: "https://i.ibb.co/cy79kN4/blur.jpg" },
  }, (err, textures, sources) => {
    srcs = sources;
  });

  let uniforms = {};
  let anim = { value: 1 };
  // compile shaders, link program, lookup location
  const programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);

  // calls gl.createBuffer, gl.bindBuffer, gl.bufferData for a quad
  const bufferInfo = twgl.primitives.createXYQuadBufferInfo(gl);

  const render = time => {
    time *= 0.001; // seconds

    twgl.resizeCanvasToDisplaySize(gl.canvas);

    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

    gl.clearColor(0, 0, 0, 0);
    gl.clear(gl.COLOR_BUFFER_BIT);

    gl.useProgram(programInfo.program);

    // calls gl.bindBuffer, gl.enableVertexAttribArray, gl.vertexAttribPointer
    twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);

    const canvasAspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
    const imageAspect = srcs.text.width / srcs.text.height;
    let mat = m3.scaling(imageAspect / canvasAspect, -1);

    // this assumes we want to fill vertically
    let horizontalDrawAspect = imageAspect / canvasAspect;
    let verticalDrawAspect = -1;
    // does it fill horizontally?
    if (horizontalDrawAspect < 1) {
      // no it does not so scale so we fill horizontally and
      // adjust vertical to match
      verticalDrawAspect /= horizontalDrawAspect;
      horizontalDrawAspect = 1;
    }
    mat = m3.scaling(horizontalDrawAspect, verticalDrawAspect);

    uniforms = {
      u_text: textures.text,
      u_map: textures.map,
      u_blur: textures.blur,
      u_matrix: mat,
      u_time: time * 10,
      u_res: [gl.canvas.clientWidth, gl.canvas.clientHeight],
      u_mouse: lastmouse
    };

    // calls gl.activeTexture, gl.bindTexture, gl.uniformXXX
    twgl.setUniforms(programInfo, uniforms);

    // calls gl.drawArrays or gl.drawElements
    twgl.drawBufferInfo(gl, bufferInfo);

    lastmouse[0] = mathUtils.lerp(lastmouse[0], mouse.x, 0.1);
    lastmouse[1] = mathUtils.lerp(lastmouse[1], mouse.y, 0.1);

    requestAnimationFrame(render);
  };
  requestAnimationFrame(render);

  canvas.addEventListener("mousemove", ({ clientX, clientY }) => {
    mouse.x = -clientX / innerWidth;
    mouse.y = -clientY / innerHeight;
  });
};

main();
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
<canvas id="canvas"></canvas>
<script id="vs" type="f">
  attribute vec2 position;
  attribute vec2 texcoord;

  uniform mat3 u_matrix;

  varying vec2 v_texcoord;

  void main() {
     gl_Position = vec4(u_matrix * vec3(position, 1), 1);
     v_texcoord = texcoord;
  }
</script>
<script id="fs" type="f">
  precision mediump float;
  
  uniform vec2 u_mouse;
  uniform vec2 u_res;
  uniform float u_time;
  uniform float u_dpi;
  uniform sampler2D u_text;
  uniform sampler2D u_map;
  uniform sampler2D u_blur;

  varying vec2 v_texcoord;
   
  void main(){
    float distAmount = .003;
      
    vec2 uv = v_texcoord; 
    vec2 parallax = u_mouse * 0.07;
    
    float freq = 70.0;
    float amp = 0.004;
    
    vec4 map = texture2D(u_map, uv);

    float dethMap = map.r - .5;
    float distMap = map.g;

    float x = uv.y * freq + u_time * 3.; 
    float y = uv.x * freq + u_time * .3;
    
    float distX = cos(x+y) * amp * cos(y);
    float distY = sin(x-y) * amp * cos(y);

    vec2 distPosition = vec2(uv.x + distX * distMap, uv.y + distY * distMap);
       
    vec2 turbulance = distPosition + (parallax * dethMap);
    
    vec4 ori_img = texture2D(u_text, turbulance);
    vec4 blur_img = texture2D(u_blur, turbulance);
        
    vec4 color = mix(ori_img, blur_img, length(distPosition) * distAmount);
    
    gl_FragColor = color;
  }  
</script>
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<script src="https://webglfundamentals.org/webgl/resources/m3.js"></script>