вторник, 28 июля 2015 г.

Продолжая тему предыдущего поста...

Штука, похожая на ту, которую я так изобретаю в миру называется Sparce Voxel Octree и применяется для рендеринга сложных объектов, как оказалось. Именно похожая, а не такая же. Во-первых, у меня нету "вокселей", которые состоят из 2х2х2=8 (и поэтому octree), хотя это имеет свои плюсы. Во-вторых, дело пока не касается рендеринга.

Если же говорить о том, чем кончилось то, что я начал в прошлый раз, то за выходные там пофиксились некоторые баги, время обработки для одной "точки наблюдения" упало до примерно 20 миллисекунд (это только за счет правки багов, без оптимизаций, хотя все равно много), прикрутилось сохранение блоков на диск и загрузка с него (правда, настолько неэффективная, а может быть, даже бажная, что немного побродив, я занял гигабайта 2 на диске и создал порядка 250К файлов) , а еще выгрузка тех блоков, что уже не нужны. Также я нашел небольшую статью (http://0fps.net/2012/01/14/an-analysis-of-minecraft-like-engines/) про эту тему, однако в ней метод нашли "опасно привлекательным" и "на самом деле очень медленным", так как действительно не очень просто бывает отыскать, скажем, соседний блок. Хорошо, если он оказывается в одном "суперблоке", но если нет, приходится делать запросы "наверх", которые, при большой глубине, действительно оказываются долгими. Что актуально для настоящих octree, где "наверху" знают только 2х2х2. В случае, когда "суперблок" содержит, например, как в случе моего эксперимента 8х8, это менее актуально, на самом деле. Тем более, что в силу изменяющейся с расстоянием точности обработки, соседи становятся все крупнее.
Правда, пока не известно, как в такое впихиваются некоторые другие вещи. Например, меня до сих пор гложут сомнения, что так можно будет легко и просто обрабатывать, например, жидкости и газы, для чего нужно, как минимум, находить границы сред. Ведь я уже говорил, что у большинства подобных движков есть, например проблемы с водой, точнее с ее течением в более низкие места, вызванные "бесконечным миром" и "очень много блоков нужно пересчитать". Так как мир в моем движке, во-первых, конечен, во-вторых, все равно пересчитывается каждый тик, само собой нужно попытаться и настоящую работу с жидкостями и газами реализовать.
И так как я уже закончил, по моему мнению, с 2D, прежде чем копаться куда-то дальше в 3D опять таки придется заниматься поиском простого решения для прототипирования в 3D. Потому что писать на голых вызовах OpenGL все-таки будет очень долго.
И есть еще темы для размышления, только из того, что хотелось-бы видеть возможным:
  1. Как впихнуть в это некие сети (провода, трубы, конвейры, что угодно), по которым бы можно было передавать энергию или сигналы или предметы. Как эффективно их обрабатывать после перехода с отдельных блоков на более крупную сущность? Впрочем, наверняка это и без таких извратов как-то сначала преобразуется в один объект и соответственно обрабатывается. Однако, к сети обычно подключаются сущности, которые делают из А какое-то Б, и вот тут уже нужно крепко подумать. Можно ли, например, сделать из такой сети с сущностями достаточно простой объект, который и без блоков выполняет нужные действия. А еще, можно ли сделать так, чтобы сложность его обработки не сильно росла с размером этой сети...
  2. Как впихнуть в это мультиблочные структуры? Рано или поздно их захочется видеть и они должны как-то, во-первых, узнавать, что они правильно собраны, во-вторых, что они до сих пор целы, а в третьих - взаимодействовать всей своей тушей с окружающим миром.
  3. А еще явно обязательно захочется иметь что-то, что больше 1 блока и умеет двигаться. Ну, я не знаю. Динозавриков. Улиток размеров с 9-этажку. Мало ли что. Звездный крейсер Дарта Вейдера. Причем, что-то обязательно захочется собирать из блоков, например. Однако, такое сооружение должно не просто двигаться взад и вперед, а иметь возможность делать это, во-первых, плавно, во-вторых, плавно же поворачивать. И нужно будет обнаруживать столкновения, конечно же.
  4. И самый эпичный вопрос мне в голову пришел ночью. Скажем, у нас есть лодка, которая плавает на поверхности воды. Сейчас она находится далеко от нас, но плавает на поверхности озера, которое мы случайно осушили у себя тут. Неужели нужно хранить сущность лодки как-то отдельно, а потом проверять, влияет ли на нее какой-то процесс? Глупо как-то и неэффективно смотрится. Другой вопрос - при осушении вода должна все-таки оставаться в разных неровностях, из которых она не могла бы утечь. То есть, вытекание воды из водоема процесс не настолько простой как "да просто в этом суперблоке уровень моря меняем и все". В общем, вещи, которые кажутся естественными, вносят немало вопросов для размышления. 5+) ... много всего, чего страшно озвучивать
С учетом того, что в 2D простейшая операция, которая просто брала одно число из каждого "блока" и усредняла его с соседними заняла 20 мс, у меня уже есть сомнения в производительности того, что получится. Хотя, конечно, это быстрее обсчета всего мира. Я уже приводил пример Земли, с радиусом около 6000 км. Так вот, в итоге двухмерный мир получается размером примерно 4.5е8*2.2е8, то есть 12е12 блоков. С учетом текущих алгоритмов, которые его разбивают на 16х8 частей, а потом каждую 8-ю часть полученного постепенно разбивают на 8 и углубляются до уровня отдельного блока, который находится на небольшом расстоянии от игрока, выходит всего порядка 30 тысяч блоков. Хотя, конечно, во-первых, в 3D это будет на порядок больше, во-вторых, мне эта дистанция "высокого разрешения" кажется все-таки крайне маленькой. Но 30 тысяч это уже большая цифра. Стоит делать что-то сложнее с каждым из 30 тысяч блоков и движок просто не будет успевать делать это вовремя. Является ли это проблемой Java? Не знаю. Можно узнать, только если переписать все на С++. Чем я, возможно, и начну заниматься, ради того, чтобы вспомнить, как оно и будет ли от этого какой-то прок.
Как это не создает проблемы в Майнкрафте? Дело в том, что там не обрабатывают каждый блок, насколько я знаю. У него есть сущность TileEntity, и только она обрабатывается, причем только если чанки, в которых они находятся, загружены. Это может быть какой-то монстрик или еще что-то. Они там хранятся в списке отдельно от блоков, поэтому размер мира никак не влияет на производительность. Зато влияет количество таких, генерирующих события, объектов. И ложится все где-то на количествах порядка одной-двух тысяч, по моему.

Комментариев нет:

Отправить комментарий