Можно ли легко создать элемент изображения HTML из объекта текстуры WebGL? - PullRequest
12 голосов
/ 19 ноября 2011

Я хотел бы взять объект 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 ]

19 голосов
/ 14 сентября 2013

Вы можете создать кадровый буфер , опирающийся на текстуру, а затем считывать необработанные пиксельные данные из кадрового буфера с помощью gl.readPixels () .Получив пиксель данных, вы можете скопировать их на 2D-холст, используя ImageData .Затем вы можете создать изображение, установив для свойства 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;
}
.
2 голосов
/ 18 января 2013

Вот пример запуска сервера node.js в сочетании с toDataURL () для передачи нескольких изображений непосредственно на диск:

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

0 голосов
/ 19 ноября 2011

Контекст WebGL - это холст, и есть несколько хорошо документированных способов вытащить изображение из холста, поэтому базовая методология будет выглядеть примерно так:

  1. Нарисуйте свою текстуру на полноэкранном (ну, на холсте) четырехугольнике. Будет будет лучше, если вы измените размер холста перед рукой, чтобы холст имел Соотношение пикселей 1 к 1 с изображением текстуры, которое вы пытаетесь нарисовать.
  2. Используйте метод, подобный , описанному здесь , чтобы получить данные изображения из холста.

Если вы просто хотите сохранить изображение, вам, вероятно, придется отправить его на сервер для обработки, но если вы хотите просто отобразить изображение на той же странице, на которой оно было отображено, вы можете установить dataURI, который вы дали атрибуту src тега img, и он должен отображаться правильно.

...