Three.js toDataUrl пустой

Когда я пытаюсь сохранить изображение из рендеринга three.js WebGl, оно оказывается совершенно пустым, но возвращает массу символов:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAK8AAADICAYAAACeY7GXAAADt0lEQ…IF4M2+znB4GcgWgDf7OsPhZSBbAN7s6wyHl4FsAXizrzP8AS/TAMmecuTCAAAAAElFTkSuQmCC

У меня для saveDrawingBuffer установлено значение true, например:

 renderer = new THREE.WebGLRenderer( { 
    alpha: true,
    antialias: true,
    preserveDrawingBuffer: true
} );

И вот как я вызываю toDataUrl:

var getImageData = false;
function render() {

            //camera.position.x += ( mouseX - camera.position.x ) * .005;
            //camera.position.y += ( - mouseY - camera.position.y ) * .005;

            camera.lookAt( scene.position );

            renderer.render( scene, camera );
             if(getImageData == true){
                imgData = renderer.domElement.toDataURL("image/png");
                window.setTimeout(10);
                console.log(imgData);
                getImageData = false;
            }
            requestAnimationFrame(render);
        }


           getImageData = true;

А вот как выглядит холст до рендеринга в изображение:

Холст холст

CanvasCode

<canvas width="175" height="200" style="width: 175px; height: 200px"></canvas>

Честно говоря, я не уверен, что еще сказать, кроме каких-либо идей относительно того, почему изображение выглядит совершенно пустым? Функция render() — это самая последняя вещь в нижней части кода.


person brandon cox    schedule 03.06.2016    source источник
comment
Кажется, я до сих пор не могу заставить его отображать изображение, я погуглил и попробовал несколько разных способов сделать это, но все равно все способы сделать пустое изображение.   -  person brandon cox    schedule 04.06.2016


Ответы (1)


WebGL — это асинхронный API. Таким образом, вам нужно либо добавить вызов gl.finish() (что может ухудшить производительность) перед вызовом toDataUrl(), либо вызвать его в следующем кадре. Для этого вы, например, можете использовать setTimeout (у вас это есть, но вы делаете это неправильно):

if(getImageData == true) {
    window.setTimeout(function () {
        imgData = renderer.domElement.toDataURL("image/png");
        console.log(imgData);
    }, 100);
    getImageData = false;
}
person Kirill Dmitrenko    schedule 07.06.2016
comment
Я только что попробовал это, он просто говорит, что gl, webgl и т. д. не определены. Я также пробовал THREE.finish(), и это тоже не сработало. - person brandon cox; 09.06.2016
comment
@brandoncox попробуйте setTimeout. Я отредактировал ответ, включив в него фрагмент кода. - person Kirill Dmitrenko; 09.06.2016
comment
Я получаю эту ошибку: [.CommandBufferContext.Offscreen-MainThread-038CA608]RENDER WARNING: нет текстуры, привязанной к единице 0 - person brandon cox; 09.06.2016
comment
@brandoncox У вас есть страница, на которую я могу заглянуть, чтобы помочь? - person Kirill Dmitrenko; 09.06.2016
comment
Я изменил его со 100 мс на 200, и это сработало, я думаю, 100 просто не хватило для загрузки текстуры. Спасибо! - person brandon cox; 10.06.2016