【发布时间】:2021-07-24 19:05:29
【问题描述】:
我正在使用 WebGL 开发浏览器游戏,the recommended advice 似乎是使用直接的 HTML 元素或在 WebGL 画布上分层的 2d 画布来执行 UI/HUD。
这一切都很好,但是你如何处理纹理共享?例如,游戏中可能有掉落在地上的物品,因此它们存在于世界中,因此必须是 WebGL 纹理,因为它们是存在于地面上的物品。
但是,当您拿起它们时,它们的图标会在 HUD 中使用,因为它们会在屏幕底部的技能栏上占据位置。因此,您必须有一个 Canvas2D 纹理才能在您的 UI 上绘制,一个 WebGLTexture 才能在您的 WebGL 画布上绘制。
目前,我通过两次加载纹理来处理这个问题,一次作为游戏中的 WebGL 纹理,一次作为画布纹理。但我不认为这种解决方案具有很强的可扩展性,因为在最坏的情况下,我必须将游戏中的每个纹理加载两次,这会使游戏的内存使用量翻倍。
作为参考,这是我加载纹理的两种方式:
// Load canvas texture
static createCanvasFromImage(filename: string) {
return new Promise((resolve, reject) => {
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
let newImg = new Image();
newImg.onload = function() {
canvas.width = newImg.width;
canvas.height = newImg.height;
context.drawImage(newImg, 0, 0);
resolve(canvas);
}
newImg.src = filename;
});
}
.
// Load WebGL texture
static loadImageAndCreateTextureInfo(gl: WebGLRenderingContext, url: string) {
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
// Fill the texture with a 1x1 blue pixel.
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 255, 255]));
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
// Don't know size until it loads
var textureInfo = { width: 1, height: 1, texture: tex };
var img = new Image();
img.addEventListener('load', function() {
textureInfo.width = img.width;
textureInfo.height = img.height;
gl.bindTexture(gl.TEXTURE_2D, textureInfo.texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
});
img.src = url;
return textureInfo;
}
这通常是如何处理的?有什么方法可以共享这些纹理,使得每个纹理只在内存中加载一次,并且可以在任一画布上使用?
【问题讨论】:
-
WebGL 纹理对象的数据存储驻留在 GPU 内存中,由图形驱动程序管理。
-
ImageBitmaps 可以被 webgl 和 2d 上下文使用。
-
您可以将图像绘制到您不向用户显示的第三个画布上,并通过
ctx.drawImage(textureCanvas, 0, 0)和WebGL 通过gl.texImage2D在您的2D 画布中使用它。
标签: javascript html canvas webgl textures