Комментарии 42
Полезная статья, спасибо!
Огромное Вам спасибо за вклад в освещение HTML5!
Гигантское вам спасибо за совет использовать многослойные canvas. Вроде бы и просто, а в голову не пришло.
Метод довольно эффективен, так как переносит довольно большую часть операций на ОС. Особенный профит от его использования возникает в играх-платформерах, когда весь уровень можно отрисовать в фоновом канвасе и просто двигать его внизу, под основной сценой. То же самое, когда реализуется паралакс-эффект.
Еще, думается, можно попробовать отдельные спрайты делать канвасами – потому что основная сцена получается очень разреженной.
Еще, думается, можно попробовать отдельные спрайты делать канвасами – потому что основная сцена получается очень разреженной.
На мобильных устройствах ситуация абсолютно обратная — многослойные канвасы сильно тормозят, приходится использовать 1 + пререндер сцены в бэкграунд (причём бэк div'а размером с канвас и расположенный под ним, поскольку необъяснимым образом background у канваса опять же сильно тормозит).
Ещё многими хитрыми способами можно добиться вполне нормальной скорости работы канваса на мобильниках.
Ещё многими хитрыми способами можно добиться вполне нормальной скорости работы канваса на мобильниках.
Я как раз использую несколько слоёв при разработке игры на LibCanvas.
Не надо увлекаться, пары слоёв вполне достаточно. Основной выигрыш дали другие приёмы, несколько слоёв просто немного помогли мне. Кеширование в бэк-буфер, не полная отрисовка канваса (а только изменённые части), и т.п.
Не надо увлекаться, пары слоёв вполне достаточно. Основной выигрыш дали другие приёмы, несколько слоёв просто немного помогли мне. Кеширование в бэк-буфер, не полная отрисовка канваса (а только изменённые части), и т.п.
Прошу прощения, это писал я, с ноута девушки. Забыл перелогиниться.
Допустим, у нас есть супермарио. Почти весь экран статичен, только несколько спрайтов движутся. Разве будет плохо, если уровень отрисовать в нижнем слое, а поверх него двигать canvas'ы размером со спрайт?
Ого, огромная работа. Спасибо.
>>К сожалению, на момент написания, только iOS 5.0 beta с Safari 5.1 использовала аппаратное ускорение canvas
Вроде на обновлении винФона тоже Ие с аппаратным ускорением. Хотя что говорить о телефонах — когда даже на декстопах нормальное ускорение канваса есть только у ИЕ и ФФ
Вроде на обновлении винФона тоже Ие с аппаратным ускорением. Хотя что говорить о телефонах — когда даже на декстопах нормальное ускорение канваса есть только у ИЕ и ФФ
Не буду оригинальничать, добавлю два примеров, как легко использовать оптимизации из топика на LibCanvas:
Параметр optimize у drawImage. Оптимизация, кстати, очень хорошая, производительность повысилась значительно.
Используйте многослойные canvas для сложных сцен
var layer1 = new LibCanvas('canvas');
layer2 = layer1.createLayer('second');
layer3 = layer1.createLayer('elseOne');
layer1.ctx.fill( new Rectangle(20,20,50,50) );
layer3.ctx.fill( new Rectangle(80,80,50,50) );
Избегайте нецелых координат
Параметр optimize у drawImage. Оптимизация, кстати, очень хорошая, производительность повысилась значительно.
ctx.drawImage({
image: libcanvas.getImage('test'),
from: [15, 25],
optimize: true
});
<эстетика головного мозга>createLayer – хм, удобно, но не очень элегантно :) Вы думаете, так лучше, чем какой-нибудь класс Scene и его поле – Layers = [Layer1,Layer2,..] ?</эстетика>
Это разные уровни абстракции ;) Какой-нибудь Scene вполне может использовать эти самые createLayer.
Очень полезно, спасибо!
Был немного удивлен первым триком.
Я как-то надеялся что браузер оптимизирует поток рендера хотя бы внутри requestAnimationFrame
Остается только построить кореляцию между ускорением использование этого pbufferа, и лишней нагрузкой которую генерит копирование, очень больших вообщето, обьемов данных.
И хотелось бы добавить про многослоные канвасы: дети, каждый канвас занимает в памяти как минимум X*Y*3.
Я как-то надеялся что браузер оптимизирует поток рендера хотя бы внутри requestAnimationFrame
Остается только построить кореляцию между ускорением использование этого pbufferа, и лишней нагрузкой которую генерит копирование, очень больших вообщето, обьемов данных.
И хотелось бы добавить про многослоные канвасы: дети, каждый канвас занимает в памяти как минимум X*Y*3.
гм, посмотрел на исходник первого теста, понял что кто-то в интерете не прав.
Ваш «канвас» ничем от обычной картинки не отличается
Ваш «канвас» ничем от обычной картинки не отличается
Очевидно, что текст не совпадает с примером и это вина не переводчика, в оригинале тоже непонятно.
Судя по коду имеется ввиду, что вместо того, чтобы каждый кадр рисовать графические примитивы — лучше их отрисовать один раз в буфер, а потом отрисовывать из буфера и это правда — отрисовать круг согласно математическим расчётам, которые производятся в .arc или кривую, согласно математическим расчётам, которые производятся в bezierCurveTo значительно медленнее, чем просто скопировать картинку соответствующего размера.
А вот реальная «двойная буферизация» особого смысла не имеет — ведь браузер имеет свой собственный бек-буфер, а отрисовка бек-буфера на основной слой:
1. Занимает слишком много времени
2. Мешает искать узкие места отрисовки
Каждый канвас занимает не X*Y*3, а X*Y*4, вы забыли про альфа-канал, но это не так важно на практике.
Если у нас игра размером, скажем, 1680*1050 (размер — огромен, обычно казуалки намного меньше), то это 7 метров на слой. Даже 5 слоёв — это 35 метров оперативки на игру, не так много ;)
Судя по коду имеется ввиду, что вместо того, чтобы каждый кадр рисовать графические примитивы — лучше их отрисовать один раз в буфер, а потом отрисовывать из буфера и это правда — отрисовать круг согласно математическим расчётам, которые производятся в .arc или кривую, согласно математическим расчётам, которые производятся в bezierCurveTo значительно медленнее, чем просто скопировать картинку соответствующего размера.
А вот реальная «двойная буферизация» особого смысла не имеет — ведь браузер имеет свой собственный бек-буфер, а отрисовка бек-буфера на основной слой:
1. Занимает слишком много времени
2. Мешает искать узкие места отрисовки
Каждый канвас занимает не X*Y*3, а X*Y*4, вы забыли про альфа-канал, но это не так важно на практике.
Если у нас игра размером, скажем, 1680*1050 (размер — огромен, обычно казуалки намного меньше), то это 7 метров на слой. Даже 5 слоёв — это 35 метров оперативки на игру, не так много ;)
Честно говоря, не могу попасть в контекст ваших двух комментариев. Но если у вас есть конкретные предложения для правок – внимательно слушаю.
Как-то в статье не заметил, но хотя бы в абзац про нецелые координаты стоило бы добавить, что координатная сетка не целочисленная и начинается с (0.5; 0.5), а целые координаты — границы пикселей.
В интернетах это освещено более подробно, а на сайте MDN можно посмотреть пример (линии нечётной ширины выглядят шире, как-будто «размытыми»).
В интернетах это освещено более подробно, а на сайте MDN можно посмотреть пример (линии нечётной ширины выглядят шире, как-будто «размытыми»).
На самом деле это не совсем так. Ведь когда вы делаете fillRect — ничего не блурится ;) И линия шириной 2 пикселя — тоже не блурится. Просто особенности рендеринга и на производительность они мало влияют.
Да, я выразился не точно; подразумевались именно сложные пути.
Тем не менее, некоторое влияние существует.
Тем не менее, некоторое влияние существует.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Улучшаем производительность HTML5 canvas