Является ли imageData CanvasPixelArray напрямую доступным для контекста WebGL холста? - PullRequest
4 голосов
/ 27 февраля 2012

Я использую Three.js для рисования 3D-моделей на визуализаторе холста webgl над простыми элементами DOM, и мне нужно обнаруживать столкновения между ними.В настоящее время мой рабочий метод заключается в том, чтобы использовать renderer.domElement.toDataURL (), загрузить его как объект imageData, затем нарисовать его в отдельном контексте 2D-холста, затем вытянуть пиксельный массив getImageData () и выполнить итерацию, используя это удивительное столкновение пикселейfunction .

Это невероятно медленный и понижает частоту кадров до почти неиграбельного ~ 5-8 FPS.Без запуска этого обнаружения ударов я получаю около 40-50 FPS.

Я думаю, что замедление невероятно громоздкое toDataURL () -> load image-> drawImage () -> getImageData ().

У меня возникает вопрос: Есть ли лучший способ получить доступ к сглаженным данным 2D-пикселей, доступным на холсте WebGL? или, возможно, лучший метод экстраполяции координат моего 3D-объекта безпараллакс?Честно говоря, любой способ получить какое-либо обнаружение столкновений быстрее, чем я в настоящее время, будет чрезвычайно полезен.

РЕДАКТИРОВАТЬ : WebGL context.readPixels () работает отлично для меня, и это супер быстро по сравнению с моим предыдущим Kludge.Хотя следует отметить, что массив данных зеркально отображается сверху вниз по сравнению с массивом данных пикселей обычного изображения.Я просто перевернул свою проверку Y на значение столкновения и заставил ее работать, хотя другие могут запутаться хитрее.Удачи!

Ответы [ 2 ]

4 голосов
/ 28 февраля 2012

Вы можете использовать gl.readPixels:

// Render your scene first then...
var left = 0;
var top = 0;
var width = canvas.width;
var height = canvas.height;
var pixelData = new Uint8Array(width * height * 4);
gl.readPixels(left, top, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixelData);

pixelData теперь содержит пиксельные данные сцены в виде байтов без знака (0-255), расположенных как [R, G, B, A, R, G, B, A...] Должны быть такими же данными, как getImageData, нопо гораздо более низкой цене.

[ РЕДАКТИРОВАТЬ: ]

Я забыл упомянуть, что если вы собираетесь это делать, вы захотите создать свойКонтекст WebGL с параметром preserveDrawingBuffer, например, так:

var gl = canvas.getContext("experimental-webgl", {preserveDrawingBuffer: true});

Это предотвращает внутреннюю работу WebGL от очистки буфера до того, как вы его доберетесь (что приведет к чтению целого ряда пустых пикселей).Включение этой опции может замедлить рендеринг, но он все равно должен загружаться быстрее, чем 5-8 FPS!:)

0 голосов
/ 11 августа 2013
 renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer:true });



 var gl = renderer.getContext()
 var buf = new Uint8Array(200 * 200 * 4);
 gl.readPixels(0, 0, 200, 200, gl.RGBA, gl.UNSIGNED_BYTE, buf);


console.log(buf);

это отлично работает.

...