在WebGL中用纹理替换颜色

时间:2011-11-11 06:04:45

标签: html5 html5-canvas webgl

在视频游戏中,仅应用颜色以帮助加快加载过程。纹理准备好后,它们会替换当前颜色。有没有办法在WebGL中执行此操作?到目前为止我看过的所有教程都只显示了如何加载颜色或纹理(不是一个接一个)。

我猜想每个形状的缓冲区在纹理完全加载后需要更改。我认为这是通过AJAX调用键控纹理可用,然后通过某种JavaScript函数应用。 WebGL在没有复杂的图像加载过程的情况下是否有内置的方法?

3 个答案:

答案 0 :(得分:5)

在我所看到的大多数游戏中,你所描述的行为通常都是以每顶点着色或非常低的纹理开始,并在可用时将其“混合”到完整纹理。那种顺利的过渡很棘手,但如果你想要的只是从一个到另一个的快速“流行”,那应该不会太麻烦。

我将采用的基本路线是创建一个具有纹理坐标和颜色信息的顶点缓冲区,以及两个不同的着色器。一个着色器将使用颜色信息,另一个将忽略它并使用纹理。一旦纹理准备就绪,您就会发信号通知网格开始使用基于纹理的网格。

至于检测图像负载,这根本不难,你甚至不需要AJAX:

var image = new Image();
image.addEventListener("load", function() {
    // Image is done loading, push to texture
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
    // Set up any other state needed, such as switching the shader for the mesh
}, true);
image.src = src;

我不确定在没有张贴真正大的代码块的情况下,我可以在这个问题上给予多少帮助,但如果你还在努力,我可以详细说明其他部分。

答案 1 :(得分:1)

我将采取的方法如下

loadTexture(url, initialColor) {

  var tex = gl.createTexture();

  // start with a single color.
  gl.bindTexture(gl.TEXTURE_2D, tex);
  var pixel = new Uint8Array(initialColor);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, pixel);

  // start loading the image
  var img = new Image();
  img.src = url;
  img.onLoad = function() {

    // when the image has loaded update the texture.          
    gl.bindTexture(gl.TEXTURE_2D, tex);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
    gl.generateMipmap(gl.TEXTURE_2D);
  }
  return tex;
}

// Load a tree texture, use brown until the texture loads.
var treeTexture = loadTexture("tree.png", [255, 200, 0, 255]);
// Load a water texture, use blue until it loads.  
var waterTexture = loadTexture("water.jpg", [0, 0, 255, 255]);

这就是http://webglsamples.googlecode.com上的大多数样本的工作方式,尽管它们都默认为蓝色纹理。

您可以轻松地将该想法扩展为使用纯色,加载低分辨率纹理,然后在完成加载高分辨率纹理时。

注意:上面的代码假设您正在加载2次幂纹理。如果不是,您需要正确设置纹理参数。

答案 2 :(得分:0)

实际上非常简单,如果WebGL没有专门用于此的任何功能,那么您可以免费获得它,因为它是一个DOM API。当你加载图像时,无论如何你必须实现他们的'onload'回调,因为图像加载是异步的。所以只需输入'onload'回调,无论需要运行什么代码来从纯色切换到纹理。