Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Html 在WebGL中将颜色替换为纹理_Html_Html5 Canvas_Webgl - Fatal编程技术网

Html 在WebGL中将颜色替换为纹理

Html 在WebGL中将颜色替换为纹理,html,html5-canvas,webgl,Html,Html5 Canvas,Webgl,在视频游戏中,仅应用颜色来帮助加快加载过程。纹理准备好后,它们将替换当前颜色。在WebGL中是否有这样做的方法?到目前为止,我看到的所有教程都只展示了如何加载颜色或纹理(而不是一个接一个) 我猜每个形状的缓冲区都需要在纹理完全加载后进行更改。我假设这是通过一个AJAX调用设置的,即纹理可用,然后通过某种JavaScript函数应用。WebGL是否有一种内置的方式来实现这一点,而无需复杂的图像加载过程?这实际上非常简单,因为WebGL没有任何专门针对这一点的功能,这是一种仅从DOM API中免费获

在视频游戏中,仅应用颜色来帮助加快加载过程。纹理准备好后,它们将替换当前颜色。在
WebGL
中是否有这样做的方法?到目前为止,我看到的所有教程都只展示了如何加载颜色或纹理(而不是一个接一个)


我猜每个形状的缓冲区都需要在纹理完全加载后进行更改。我假设这是通过一个AJAX调用设置的,即纹理可用,然后通过某种JavaScript函数应用。
WebGL
是否有一种内置的方式来实现这一点,而无需复杂的图像加载过程?

这实际上非常简单,因为WebGL没有任何专门针对这一点的功能,这是一种仅从DOM API中免费获得的功能。加载图像时,无论如何,您必须实现它们的“onload”回调,因为图像加载是异步的。因此,只要输入“onload”回调,就可以运行从纯色切换到纹理所需的任何代码。

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

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

至于检测图像负载,这一点都不难,甚至不需要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;

我不确定如果不发布非常大的代码块,我能在这个主题上提供多少帮助,但如果您仍在努力,我可以详细介绍其他部分。

我将采取的方法如下

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.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);
  }
  img.src = url;
  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]);
这就是大多数示例的工作方式,尽管它们都默认为蓝色纹理

您可以很容易地扩展该想法,使用纯色,加载低分辨率纹理,然后在完成后加载高分辨率纹理


注意:上面的代码假设您正在加载power-of-2纹理。如果没有,您需要正确设置纹理参数。

比我想象的简单得多。当你说“两个不同的着色器”时,你是在说设置的初始着色器吗?如果是这样的话,我猜draw函数需要在某个点切换齿轮并从纹理输出。我不完全确定“初始着色器”是什么意思。您使用的是特定的教程或框架吗?实际上,从零开始构建我自己的WebGL引擎,遵循Mozilla WebGL教程中的许多想法和原则。我说的初始着色器是指在设置WebGL(如果我没记错的话)时用于从DOM中获取和存储着色器元素的着色器。好的,那么您只需要在DOM中定义第二个着色器。解析和编译它的工作原理与您现在拥有的着色器相同,您只需在运行时决定在调用
gl.useShader()时使用哪个着色器即可这更有意义,gl.useShader()是我需要的。非常感谢。好吧,几个月后我读了我自己的问题,我明白我在问什么了。要完全回答我自己的问题,请阅读下面的内容。要同时加载纹理和颜色,需要两组x片段和x顶点脚本。一个用于颜色,另一个用于纹理。因为它们是通过DOM拉入的,所以在初始化对象时只需使用正确的着色器ID。可以是颜色或纹理。希望这有助于像我一样无知的WebGL鞋底。