可以从WebGL纹理对象轻松创建HTML图像元素吗?

时间:2011-11-19 01:11:06

标签: webgl

我想获取我已渲染的WebGLTexture对象并使用它来创建HTML图像元素。目标是显示屏幕外渲染过程的结果以进行调试。它应该比将纹理渲染到全屏四边形(我目前的调试方法)要容易得多。

在WebGL中从图像元素创建纹理非常简单:

var image = new Image();
image.src = "myImg.jpg";

// image loads...

var texture = gl.createTexture();
gl.bindTexture(texture);
gl.texImage2D(_gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, image);

图像加载和解码完全由您完成。

是否有类似的简单方法来做反向?即:

// This doesn't work
var img = new Image(texture);

// But maybe this could
var img = createImageFromTexture(texture);

function createImageFromTexture(texture) {
    // ... some combination of tricks ...
}

如果有办法做到这一点,我相信它会在调试之外的上下文中有用。我会继续看看我是否能找到办法,但我觉得有人必须先尝试过这个。

3 个答案:

答案 0 :(得分:19)

您可以创建一个由纹理支持的framebuffer,然后使用gl.readPixels()从帧缓冲区中读取原始像素数据。获得数据像素后,可以使用ImageData将它们复制到2D画布。然后,您可以通过将图像的src属性设置为canvas.toDataURL()来构建图像。

function createImageFromTexture(gl, texture, width, height) {
    // Create a framebuffer backed by the texture
    var framebuffer = gl.createFramebuffer();
    gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);

    // Read the contents of the framebuffer
    var data = new Uint8Array(width * height * 4);
    gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, data);

    gl.deleteFramebuffer(framebuffer);

    // Create a 2D canvas to store the result 
    var canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    var context = canvas.getContext('2d');

    // Copy the pixels to a 2D canvas
    var imageData = context.createImageData(width, height);
    imageData.data.set(data);
    context.putImageData(imageData, 0, 0);

    var img = new Image();
    img.src = canvas.toDataURL();
    return img;
}

答案 1 :(得分:2)

以下是与toDataURL()一起运行node.js服务器以将多个映像直接传输到磁盘的示例:

http://www.oampo.co.uk/2011/01/exporting-video-from-webgl/

答案 2 :(得分:0)

WebGL上下文是一个画布,有几种记录良好的方法可以从画布中获取图像,因此基本方法看起来像这样:

  1. 在全屏(好,全画布)四边形上绘制纹理。它会 如果您事先调整画布大小,那么画布最好 与您尝试绘制的纹理图像的比例为1:1。
  2. 使用one described here之类的方法获取图像数据 走出画布。
  3. 如果您只想实际保存图像,则可能需要将其发送到要处理的服务器,但如果您只想在同一页面上显示图像,则可以设置您获得img代码src属性的dataURI,它应该正确显示。