#javascript #html #image-processing #canvas
#javascript #HTML #обработка изображений #холст
Вопрос:
Я создаю небольшую многопользовательскую онлайн-игру с помощью JavaScript и собственного API Canvas (WebGL). Я хочу найти цвет пикселей на экране как форму обнаружения столкновений, я полагаю, что это сэкономит ресурсы, если не обрабатывать каждую фигуру в каждом кадре, а просто проверить, является ли цвет пикселя в определенной позиции таким, что он соприкасается с фигурой. (Надеюсь, это имеет смысл)
Я провел несколько тестов, и у меня средняя задержка кадров составляет около 4-5 миллисекунд без обнаружения столкновений, а затем, когда я делаю один вызов метода контекста моего холста .getImageData()
, внезапно эта задержка кадров увеличивается до 19-20 миллисекунд…
Насколько я могу найти в Интернете getImageData()
, это единственное средство проверки цвета данного пикселя, но я должен думать, что есть какой-то другой способ, который не приводит к такой огромной задержке.
Я попытался запустить getImageData()
небольшую часть экрана по сравнению с более крупными разделами, и запрос размером 1×1 пиксель приводит к задержке 10 мс, тогда как запрос размером 600×600 пикселей составляет около 15 мс… Итак, проблема не в количестве / размере запроса, а в том, что сам запрос выполняется чрезвычайно медленно, поэтому здесь нет возможности для оптимизации, мне НУЖЕН другой способ.
Кроме того, кэширование данных изображения также не является вариантом. Мне нужно опрашивать эти пиксели каждый отдельный кадр, я не могу его кэшировать (потому что проигрыватель и объект, с которым он должен столкнуться, постоянно перемещаются, и ими управляют через Интернет, поэтому также невозможно предсказать, где они будут в любой момент времени… Мне НУЖНО опрашивать каждый кадр без исключений)
Чтобы было ясно, я не спрашиваю, как писать коллизии или как создавать пиксельные системы обнаружения коллизий… Я спрашиваю ТОЛЬКО о том, как получить цвет пикселя на холсте без необходимости использования .toImageData()
, потому .toImageData()
что это слишком медленно для моего варианта использования.
Комментарии:
1. Ваша предпосылка неверна: проверка цвета пикселя будет медленнее, чем худшее обнаружение столкновений, о котором вы можете подумать. Также вы говорите, что используете контекст webgl, но у этого нет метода getImageData, есть только 2d контекст.
2. @Kaiido О, тогда я виноват. У меня сложилось впечатление, что 2D-контекст был просто слоем поверх WebGL? Он по-прежнему использует WebGL, нет? Кроме того, как вы можете быть уверены, что проверка цвета пикселя будет медленнее, чем обнаружение столкновений? В моем случае использования у меня на экране около 200 дуг / линий (при этом новые добавляются примерно 5-6 раз в секунду)… Вы действительно думаете, что проверка столкновений с тысячами дуг в каждом кадре будет быстрее, чем получение цвета одного пикселя?
3. Нет, это не поверх WebGL. 2D-контекст может быть аппаратно ускорен и, таким образом, использовать графический процессор, как это делает WebGL, но это все еще полностью отдельные API. И да, я уверен, что это будет медленнее, именно потому, что 2D-контекст может быть аппаратно ускорен. Чтобы прочитать пиксельные данные, браузер должен уменьшить контекст и переместить буфер из графического процессора в центральный. Это не только замедляет выполнение, но даже замедляет все последующие операции рисования. С другой стороны, вычисление пересечения — это всего лишь арифметика, с которой современные процессоры могут справиться без проблем.
4. Спасибо! Это все еще не отвечает на мой вопрос, но это полезная информация, и она может помочь мне найти решение.
Ответ №1:
Стандартное обнаружение столкновений может оказаться лучшим вариантом. Проверка на соответствие пикселям хорошо работает для идеального обнаружения столкновений со сложными объектами, но может стать дорогостоящей при большом количестве пикселей.
Вместо этого я бы, вероятно, рекомендовал использовать стандартное обнаружение столкновений с простыми формами. Если все сделано правильно, он должен иметь хорошую производительность даже для более сложной игры.
Если вы действительно хотите использовать идеальное столкновение пикселей, вам нужно сначала проверить прямоугольные ограничивающие рамки двух объектов, чтобы убедиться, что они находятся недалеко друг от друга. Если их ограничивающие рамки пересекаются, вы можете использовать битовые маски ваших спрайтов, чтобы быстро проверить каждый пиксель на перекрытие. В этом вопросе немного больше информации. Это не JS, но концепция будет той же самой.
Комментарии:
1. Спасибо за ваш ответ, но это не полезная информация. Я не просил другого способа записи моего обнаружения столкновений, и я не спрашивал, как сделать пиксельные столкновения идеальными… Я спрашивал, как получить цвет пикселя без использования
.getImageData()
, и ваш ответ даже не касается этого.