Автор текста: Александр Нилов

Архитектор информационных систем департамента «Логистика» КОРУС Консалтинг

Всем привет! Меня зовут Александр Нилов, я архитектор департамента «Логистика» КОРУС Консалтинг. Но сегодня речь пойдет не о работе, а о моем личном проекте – 3D компьютерной игре.

Я довольно давно занимаюсь программированием. Около 10 лет назад у меня возникла идея написать игру именно на Java, поскольку я использую этот язык в работе. Это был своего рода челлендж. Хотел попробовать себя, посмотреть, возможно ли это. И спойлер – возможно. Но проект дал мне больше, чем я мог рассчитывать.

В этой статье я погружусь в детали геймдева и расскажу о том, почему вообще стоит заниматься подобными проектами.

Ссылка на репозиторий

На Java написано не так уж много игр. Как правило, на Java создаются так называемые инди-игры. В последнее время это направление довольно популярно. Например, есть многопользовательская игра Wurm Online с миллионами игроков. Но для мира Java это скорее исключение, чем правило.

В целом Java – более универсальный язык – и для кофеварок, и для мейнфреймов. Но игры, как пет-проект, интересны тем, что они, как это называется, on the cutting edge, т.е. здесь используются самые передовые технологии, потому что работать все должно максимально быстро. В игре не должно быть багов, потому что исправить первое впечатление нового игрока будет скорее всего невозможно. Если человек скачает игру и наткнется на баги, он просто удалит ее. То есть здесь требования к разработке довольно высоки.

Примерно с такими соображениями 10 лет назад я начал проект. Прямо в процессе выкристаллизовалась идея RPG-игры по аналогии с Gothic или Oblivion. Первое время развитие шло довольно вяло, лет пять практически ничего не делал. Но потом у меня появилось свободное время, и я взялся за проект активнее.

Движок

В основе моей игры опенсорсный движок jMonkeyEngine 3. По условиям лицензии его можно использовать даже в коммерческих проектах. На нем писались игры, выложенные в Steam за небольшие деньги (порядка 160 рублей). Однако суперизвестных коммерческих применений этого движка я не знаю. Он не особо распространен.

Существуют гораздо более популярные игровые движки, например Unreal Engine или Unity Real-Time Development Platform. У них огромные комьюнити и хорошая документация, но работают они на других языках – C++ и .NET. На Java ничего такого нет. jMonkeyEngine – фактически единственный развивающийся из некоммерческих. Возможно, есть еще проприетарные, но их я изначально не рассматривал.

У jMonkeyEngine есть достаточно большое комьюнити – он поддерживается, есть активный форум. Однако, документация на несколько версий опаздывает за развитием кода (документацию обычно писать не так интересно, как код). Поэтому форум, по сути, и является основным источником информации. Проще посмотреть код и поговорить там. Почти каждый день на форуме всплывают темы: «А как сделать это…» или «Почему у меня трава мигает». В свое время я был удивлен тому, что старожилы очень подробно отвечают на эти вопросы, так что их ответы действительно можно использовать вместо документации.

Одно из основных преимуществ движка в том, что он позволяет писать под несколько платформ сразу. Поскольку это Java, весь код кроссплатформенный. Разрабатывая игру под Linux, можно автоматически получить работающую игру под Windows и MacOS, а также под планшеты и смартфоны Android, но с некоторыми оговорками, касающимися тестирования – подробнее на этом остановлюсь позже.

Честно говоря, мне не очень нравится курс развития этого движка. Команда core-девелоперов часто отметает классные идеи, с которыми к ним приходят участники сообщества. На мой взгляд, с учетом того, что это опенсорс без финансирования, если не будет развития, проект может потерять пользователей (если появится другой движок на Java, который предложит тот же функционал, он может оттянуть пользователей). Однако в целом, если говорить только про мой проект, к движку вопросов нет. Быть может, хотелось бы больше фич, которые позволили бы быстрее генерировать фреймы. Но в целом все, что надо, уже реализовано. Этим просто надо учиться пользоваться.

Погружаемся в технические детали

Я постепенно изучал движок – начал с простых туториалов, потом перешел к решению интересных мне задач. Движок отвечает за рендеринг содержимого графа объектов и передачу звука. Кроме того, в нем есть библиотека, которая обрабатывает физику столкновения тел и обнаруживает коллизии.

Все остальные задачи надо решать своими руками. Если движки на других платформах позволяют заложить какую-то базу – с чего-то начать, используя их готовые примитивы, то здесь этого нет. Это как конструктор Lego – делай, что хочешь и как хочешь.

Одна из библиотек движка позволяет процедурно сгенерировать ландшафт, состоящий из квадратов – так называемых тайлов. Когда камера приближается к крайнему тайлу, генерируются новые, находящиеся на стыке с ним, а наиболее отдаленные выгружаются. Но это только иллюзия – чтобы по такой земле можно было перемещаться нужно добавить невидимую физическую поверхность, повторяющую изгибы ландшафта, и наделить игроков телами присутствующими в мире физики (Collision shape). То есть как бы и сам игровой мир, и персонажи многомерны – существуют сразу в нескольких параллельных измерениях.

Сами по себе игры работают по одному и тому же принципу – в бесконечном цикле while=1 они рендерят так называемые фреймы в секунду (frames per second, FPS). Сама игра – как кукольный театр из графа объектов. Существует только то, что в данный момент снимает камера. Создается впечатление, что там есть земля, персонажи, деревья, небо и облака с солнцем. То, что находится вне ее поля зрения, движок не рендерит.

Добавление объекта в поле зрения осуществляется манипуляциями с графом объектов. В конце каждой итерации картинка отрисовывается. И если какие-то операции отрабатывают медленно (алгоритмы неудачные или объектов слишком много), вы получаете низкий FPS. Это относится к любым играм – что трехмерным, как в моем случае, что к двумерным, как на старых приставках.

Существуют разные способы реализовывать объекты так, чтобы это было оптимально с точки зрения производительности. Например, можно рисовать трехмерные картинки, а можно двухмерные. Глазом разница заметна не очень, но на производительности это сказывается в лучшую сторону.

В интернете есть целое сообщество game developer, для которых это хобби. Возможно, кто-то из них и получает за это деньги, но в свое свободное время они продолжают подбирать подходы и лайфхаки. Некоторое время назад я начал делиться скриншотами проекта на профильном форуме движка, и народ начал давать интересные советы, в том числе по части оптимизации.

Растительность

Движок позволяет задавать озера и землю с определенным рельефов (неровностями почвы). Я подобрал параметры, которые делают лес похожим на природу под Питером.

Довольно долго я бился над задачей реалистично сгенерировать траву. Звучит просто – любой детсадовец на бумаге нарисует траву. Но в рамках игры это оказалось экстремально сложной темой, по которой даже написано несколько диссертаций.

В целом есть множество подходов – как сложные, так и простые – прямоугольник с текстурой.

В современных играх, как я понял, используют комбинированный подход, чтобы трава выглядела правдоподобнее – создается как бы куст из нескольких перекрещенных под разными углами прямоугольников.

Я также использую именно его. Возможно, в будущем перейду на что-то более сложное. Пример сложного подхода – отрисовка травы полностью на GLSL-шейдерах.

Что я подразумеваю под простым комбинированным подходом?
Для используемого движка в интернете было выложено несколько примеров реализации травы. Я пытался использовать эти библиотеки, но они оказались слишком сильно завязаны на собственную внутрянку, т.е. там была своя генерация земли, деревьев и т.п. Оттуда нельзя было взять только траву, а перетаскивать всю библиотеку к себе не хотелось.

Библиотеки были плохо задокументированы, поэтому подробно изучать их можно было только через реверс-инжиниринг алгоритмов. Компилируешь, подключаешь к коду дебаггер и смотришь, как и что работает. Изучив таким образом несколько библиотек, я понял, что проще сделать самому.

Генерация травы осуществляется следующим образом. На высоте 150 местных единиц от нулевой точки (земли) я беру плоскость, на ней генератором случайных чисел выбираю точки. Из каждой такой точки вниз направляю луч — это техника называется ray cast. Если точка пересечения луча и земли выше уровня воды, т.е. не в озере, то я сажаю в нее пучок травы. Для этого один из стандартных пучков я подкручиваю в трех измерениях и масштабирую, чтобы вся трава не выглядела одинаково.

Аналогично сажаются деревья, только их на карте гораздо меньше. Я использовал модели деревьев из одной бесплатно распространяемой библиотеки. У меня применяется всего три модели дерева, но, как и траву, каждый раз я ее подкручиваю в трех измерениях и масштабирую. В итоге в кадре мы видим разнообразие.

Уровень детализации

С точки зрения перформанса детализация – очень важный момент. Если мы будем отрисовывать все со 100% детализацией, игра просто сожрет вычислительные ресурсы видеокарты и процессора. Но на самом деле 100% детализированы должны быть только те объекты, которые находятся вблизи. Когда мы отодвигаемся, допустим, на 100 игровых метров, детализация может быть уже 50%, а еще дальше – 25% и так далее. Установка правильного уровня детализации очень хорошо влияет на производительность. С этим тоже пришлось повозиться.

Кстати, для скорости обработки леса и травы важно, чтобы все материалы были одинаковые. Поэтому после посадки растительности нужно средствами движка сливать текстуры – это еще один лайфхак с форумов, который здорово экономит производительность. Грубо говоря, вся трава должна представлять собой единый материал, тогда движок сможет отрисовывать ее за один проход.

Погода

Довольно долго работал над тем, чтобы добавить дождь. Лайфхаки тоже вычитал на форумах.

В играх дождь и снег никогда не просчитываются для всей карты – от такой задачи любое современное железо просто умрет. Осадки создаются в полусфере, привязанной к невидимому узлу над игроком. Когда игрок идет по карте, полусфера следует за ним. Камера как бы крутится внутри этой сферы. Таким образом создается впечатление, что на карте везде есть осадки (хотя они рендерятся на маленьком ее кусочке). Гипотетически, если сильно отдалить камеру, будет видно, как над игроком перемещается полусфера.

Модели и лицензии

Существует большое количество открытых опенсорсных моделей, которые можно использовать в своих разработках. Но есть нюанс – надо следить за лицензиями. Моя игра разрабатывается под GPL v3. Эта лицензия требует открытия кода проекта в случае использования исходников. Но существует множество других лицензий. Некоторые из них позволяют распространять код, пригодный для коммерческого использования, другие же имеют определенные ограничения, несовместимые с GPL.

При использовании любых чужих разработок приходится следить за совместимостью лицензий. При этом я стараюсь избегать самописных лицензий, потому что они мутные. Непонятно, какие могут быть последствия использования моделей или текстур с такими ограничениями.

Я обратил внимание, что несмотря на то, что есть множество объектов, которые можно использовать, просто указав авторство (а иногда и не указывая его), в мире опенсорсных игр принято сохранять источник. Когда ты берешь текстуры, модели, звуки, скачанные с какого-либо открытого источника, всегда указывается ссылка на исходник, а также на лицензию. Вероятно, это делается, чтобы потом не было никаких вопросов. Например, если использовать в игре свободно распространяемые качественные звуки, а потом прохождение этой игры выложить на YouTube, сервис скорее всего определит использование мелодии и может даже заблокировать ролик в публичном доступе без нужных ссылок.

Последние изменения

Фактически, я закончил с генерацией леса. Можно бесконечно бродить по вымышленному лесу по типу Карелии под красивую музыку. Недавно я подключил библиотеку, которая позволила отыграть смену дня и ночи со всеми красивыми цветами рассветов и закатов. Иногда в этом лесу идет дождь.

Сейчас доделываю часть, касающуюся добавления звуков природы. Для звука можно было использовать библиотеку, которая идет с движком. А можно использовать другие библиотеки, позволяющие на устройстве отрендерить объемный звук (эхо в коридоре, например). Третий путь – делать самостоятельно с нуля. Конкретно в случае со звуком у меня вопросов к движку не было – все прекрасно работало.

В игре уже есть простенький искусственный интеллект. Иногда появляется так называемый NPC (Non Player Character) – противник, который бегает за игроком и пытается его побить. Он определяет, где находится игрок, и пытается его настигнуть, потом начинается бой. Боевая система состоит из ударов, которые можно заблокировать либо избежать (уклониться). ИИ блокирует входящие удары с определенной вероятностью.

Дальше планирую заняться моделями зданий, возможно даже целых поселков, чтобы наполнить игру разнообразием.

Тестирование

Поскольку для ускорения рендеринга в играх используется множество сложных технологий – та же многопоточность – при наличии ошибок или при неправильном подходе игра ведет себя по-разному на различном железе. И все это надо тестировать. Приходится делать это не только у себя, но и у друзей или на компьютере ребенка. Только так начинают вскрываться баги, которые в целом не так видны.

Выше я говорил, что движок позволяет разрабатывать параллельно под несколько платформ сразу. Так вот тестировать тоже приходится на нескольких платформах, потому что в теории все кроссплатформенное, но на практике поведение на Windows и на Android несколько отличается.

На данный момент я заканчиваю отладку – близится тот момент, когда я смогу сказать, что в игре нет блокирующих и критических багов. Фактически, на носу первый релиз.

Зачем это все

Изначально идея была в том, чтобы попробовать в принципе сделать игру на Java с бесконечным процедурно-генерируемым миром. И это действительно возможно, все работает, не уступая по скорости аналогичным проектам, написанным, допустим, на С++. Но сейчас я вижу, что у этого направления огромный потенциал – он вышел далеко за первоначальные рамки.

Меня привлекают несколько моментов:

  • при работе с такими проектами приходится принимать много архитектурных решений, и это интересно. Требования к качеству таких проектов намного выше, чем в коммерческих играх. Как правило, у бизнеса все-таки предусмотрен жизненный цикл игры – когда есть баги, они сортируются по критичности, как-то исправляются. Здесь же zero bug tolerance. Такое встречается и на некоторых коммерческих проектах, но не часто. А в пет-проектах поправить потом не получится, это приходится учитывать.

  • Мне пришлось обкатать много разных идей и технологий, исследовать много тем, напрямую или косвенно связанных с геймдизайном. Например, о том, как наделить NPC интеллектом, написаны целые талмуды – можно применять кучу разных решений, от очень простеньких скриптов, до сложных – LLM. И я продолжаю искать и изучать доступные варианты. Конечно, мне хотелось бы сделать больше. Но на пет-проекты не всегда есть время: вам приходится балансировать между работой, личной жизнью и пет-проектом, и игра в этом случае не в приоритете.

  • Однако пет-проект положительно сказывается на работе. Ее вполне можно прикладывать к резюме. Когда приходишь на собеседование, достаточно дать ссылку на репозиторий. Вместо того, чтобы задавать тебе какие-то вопросы, интервьюер может пойти и посмотреть в код – понять, нравится ему то, что ты пишешь, или нет.

  • Кроме того, игра получается «технологией двойного назначения». С одной стороны я развлекаюсь, а с другой – получаю определенные полезные навыки. На своем проекте я отлаживаю некоторые идеи, которые потом применяю в работе. Например, так я экспериментировал с модуляризацией – игра побита на модули, связанные между собой интерфейсами. Это дает хорошую структуризацию кода. Код не перемешивается и не сплетается, лучше читаем. А кроме того отдельные части проекта можно легко заменить – т.е. переписать модуль или его часть, исправив кусок логики. Впоследствии этот подход я успешно применил в коммерческой разработке.

  • Аналогично я экспериментировал с многопоточностью. Игра требует значительных вычислительных ресурсов, которые сильно загружают процессор. Та же рассадка травы – достаточно «тяжелое» вычисление. До этого у меня были определенные навыки работы с многопоточностью в Java, но здесь появилась возможность их отточить – в многопоточном режиме рассадка травы и деревьев происходит гораздо быстрее. Большой кусок работы можно разбить на секции, каждую из которых выполнять в отдельном потоке. Это позволяет ускорить обработку в несколько раз.

За 10 лет, которые прошли с момента начала проекта, мои навыки сильно выросли. Сейчас многие вещи я бы сделал по-другому. Есть ограничение по доступному времени. Это время можно использовать на переписывание того, что было написано криво, но работает, либо на добавление новых фич.

В целом работа над игрой продолжается. Исходники выложены, периодически я получаю комментарии от сообщества. Если вам интересно, заходите познакомиться с проектом. Для меня это будет ценный фидбек. Репозиторий можно скачать и собрать из исходников игру на своем железе. https://github.com/Arifolth/jme3rpg

Комментарии (30)


  1. trix
    16.01.2025 10:45

    уважаю дерзких безумцев, но прежде чем писать 3д игру на яве, я бы написал 2д игру :)


    1. Arifolth
      16.01.2025 10:45

      С одной стороны - make sense, приобрести опыт и попробовать идеи.

      С другой стороны - а зачем? Если целевым вариантом является 3D с процедурным миром и попытка воссоздать Gothic/Oblivion. В процессе всё равно приходится делать standalone мини-приложения для проверки гипотез. То есть создание 2D игры в данном случае кажется потерей времени на не-релевантные задачи.


    1. DuhovichSasha
      16.01.2025 10:45

      Полностью Вас поддерживаю 2D это первично в любой игре..


    1. Jijiki
      16.01.2025 10:45

      поверьте вы это сделаете очень быстро, где в 3д - 2д это просто матрица Ortho тоесть скорость добавления 2д в 3д близка к скорости света )

      https://www.songho.ca/opengl/gl_projectionmatrix.html

      https://www.songho.ca/opengl/gl_transform.html

      Matrix4 ModelGL::setOrthoFrustum


  1. solarwind
    16.01.2025 10:45

    Так Minecraft написан на Java, а это чуть ли не самая популярная игра в мире вообще...


    1. AdrianoVisoccini
      16.01.2025 10:45

      "был"

      есть отдельная Java версия, но основная давно переехала на плюсы


      1. Homyakin
        16.01.2025 10:45

        Насколько знаю, многие сидят на Java версии, в том числе из-за модов.


      1. voopr
        16.01.2025 10:45

        Нет никакой основной версии и никто никуда не переезжал.
        Есть кроссплатформенная Java Edition и есть Bedrock Edition для винды и консолей.
        Это две параллельно развивающиеся реализации.


      1. tsp1000
        16.01.2025 10:45

        Интересно, какая такая основная, если она Bedrock? На ней ней поддержки модов, до сих пор немало критичных багов, да и не переходит на нее никто, на ПК по крайней мере.


      1. solarwind
        16.01.2025 10:45

        Нет. На ПК никто на бедрок точно не переходит, ибо там нет всех этих миллиардов разработанных и до сих пор поддерживаемых модов. И Java-версия до сих пор активно развивается.


        1. Jijiki
          16.01.2025 10:45

          кстати майнкрафт без greedy meshing можно написать, там очень интересная идея, математика интересная, в конечном итоге можно и фигуры строить аля вокселями - для этого правда надо подумать как это делать, а чанки рисовать не так то и сложно, да и коллизия простенькая, после такого можно даже в себя поверить немного ) (рисовать чанк, строить блок/убрать блок, обновить чанк)


    1. burandby
      16.01.2025 10:45

      Кстати, да, а куда пропал lwjgl?

      Тоже джава игровой движок для 3д


  1. Jijiki
    16.01.2025 10:45

    классно очень, а сколько у вас память отьедает при запущенной игре? мне порой история с с/с++ надоедает порой реально подумываю переехать в java

    траву вроде можно отправить в геометрический шейдер, траву можно не шевелить и либо кидать в геометрический шейдер, либо кидать траву в 1 буффер, второй буффер, селектор идете рисуется селектор из буффера травы (там еще посмотреть как лучше)


    1. Arifolth
      16.01.2025 10:45

      Постепенно количество объектов в кадре увеличивается и требования начинают подрастать. Также это зависит от размеров текстур и используемых моделей (low poly/high poly).

      Требуется система имеющая от 4Gb RAM (бывают скачки выделения в пике до 6Gb) и от 2Gb до 4Gb Video RAM.

      Траву можно через шейдер рисовать, это правда, но шейдер пишется не на Java а уже на другом языке - GLSL OpenGL Shading Language, он кажется довольно сложным, надо отдельно изучать. И в шейдере для травы придется учитывать неровности ландшафта, место посадки (не сажать на скалах и под водой) и тогда уж надо бы сделать эффект ветра - колышащуюся траву. С шейдерами я планирую как-нибудь попозже поразбираться.


      1. Jijiki
        16.01.2025 10:45

        ява всё таки дорога у меня сейчас такой расклад

        посмотрите тутс ниже он должен придать вам уверенности, я когда его увидел многое стало реально сделать

        у вас трава одинаковая, это классно, и момент что она одинаковая тоже двоякий (трава может быть и частичкой тогда возможно будет доступ к координате по высоте)

        весь тутс ниже я оттестировал, перенял его опыт, и щас на С пытаюсь понять как хейтмапу делать, но в тутсе скейл и высота 1 в 1


  1. Jijiki
    16.01.2025 10:45

    вот советую тутсы
    https://www.mbsoftworks.sk/tutorials/opengl4/
    и DSA местами может улучшить

    по траве получается либо бить на части и трансформ фидбек в доках пишут он работает со стадией геометрического, либо как кубики у синМатрикса на геометрическом шейдере


  1. Jijiki
    16.01.2025 10:45

    Генерация травы осуществляется следующим образом. На высоте 150 местных единиц от нулевой точки (земли) я беру плоскость, на ней генератором случайных чисел выбираю точки. Из каждой такой точки вниз направляю луч — это техника называется ray cast. (вот это нагрузно) дело в том что у вас проекция террейна находится в плоскости 2д (x,0,z); поэтому проще генерить по террейну без рейкаста, подправляя высоту из карты высот = (random,height,random) далее не знаю как вы ходите, но если есть карта высот проще ходить по нормалям(террейна), так вы половину формул на площадь/обьём скипните просто и будете всё равно там где надо. (потратьте время на карту высот и получение тайловых карт высот это вам очень поможет), далее изза того что мы на 2д плоскости можно пойти дальше и генерить области УГО где дом/дерево - получится поидее +- как должно быть, если ходить по дому, просто ставим материал на лесницу/пол если есть материал(по имени) ходим по нему, соотв на террейне где нет УГО у вас материал(по имени), так будет вся инфа статичная и высота известная, по матеше - советуют использовать кватернионы на камере и обьектах, пишут там скипается некоторое число умножений матриц

    по запуску лучей и физикe(дело в том что реал тайм мы до сих пор не тянем поэтому лучше посмотреть практики как можно симулировать) есть нетривиальные наблюдения, недавно случайно набрёл на обзор https://gamedev.ru/code/articles/PositionBasedPhysics


    1. Jijiki
      16.01.2025 10:45

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


      1. Arifolth
        16.01.2025 10:45

        В библиотеках движка есть ParticleEmitter. Я использую его для реализации осадков. Но дело в том, что у него есть "форма" - в пределах которой эти частицы и испускаются и видны.


        1. Jijiki
          16.01.2025 10:45

          ок, я делал по синматриксу там попроще и тоже ява советую глянуть тоже - ThinMatrix

          но лучше тутс выше глянуть он попрофесиональнее попроизводительнее


  1. Fancryer
    16.01.2025 10:45

    Скажите, как вы решали проблему с ограничением симуляции дождя - чтобы в помещениях не было капель?


    1. Jijiki
      16.01.2025 10:45

      у дома есть баундинг бокс(центроид и по геометрии ограничивающие плоскости куб типо) его можно посчитать оффлайн по факту когда вы его создаете, если у вас частицы и вы управляете в коде частицами просто по высоте работайте баундинг бокса(виртуальный расчет только в коде - баундинг бокс имею ввиду и его точка виртуальная они участвуют в расчетах. для дебага можно отрисовывать)

      https://ru.wikipedia.org/wiki/Иерархия_ограничивающих_объёмов

      http://ray-tracing.ru/articles184.html небольшие вводные

      вроде дорого выходит, вопрос интересный ниразу не думал о таком, если зашли в дом то дом рисовать первым(спрятать за дом партиклы по очередности отрисовки), но это только внутри, а снаружи? мы же же можем быть одновременно только в одном месте

      какието хитрости наверняка есть)

      еще вариант верх дома делать по материалу террейна, и учесть как-то высоту - подставлять ее

      допустим есть УГО дома и карта высот, надо как-то сделать карту высот и вырезать площадь дома и выбирать максимум это наверно дешевле


      1. vassabi
        16.01.2025 10:45

        а тоннели/пещеры у вас есть?


        1. Jijiki
          16.01.2025 10:45

          у меня нету, я просто задался вопросом как удешевить эти операции, в сторону облегчения ради анимаций/интерактива, у пещер тоже есть топология и точка входа, в разных играх сделано по разному но если удасться всё вживить в террейн, и отключать отрисовку когда когда вы внутри каких-то областей и ходить по высоте террейна которая в текущий момент подвела вас к вросшему в террейн обьекту и увела внутрь - вроде получается дешевле чем пускать лучи

          поидее в пещере после предбанника поворота можно отключить то что снаружи


        1. Jijiki
          16.01.2025 10:45

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


    1. Arifolth
      16.01.2025 10:45

      Я пока никак не решал, ибо у меня пока нет зданий со входом с улицы. Вообще зданий пока нет. Но, кажется это можно решить именно с использованием BoundingBox - проверяются координаты частиц и попавшие в него убираются. Этот метод кажется самым точным но и самым тяжелым.

      Внутри здания совершенно точно можно управлять этим через бакет (очередности) отрисовки RenderQueue.Bucket.Transparent. Снаружи использовать такой подход не выйдет, так как будет нарушена очередность отрисовки травы, неба и удалённых гор.

      Ещё можно проверять положение ноды игрока - если он внутри дома отключать отображение полусферы с частицами через particleGeom.setCullHint(Spatial.CullHint.Always);

      Но это должно визуально полностью отключить дождь. То есть в дверной проём будет видно что снаружи дождя нет.


      1. Jijiki
        16.01.2025 10:45

        да но представье теперь на сколько дорого ради частицы проверять все ну пускай в ноде квадрата баундинг боксы, варик с вживлением или подменой новой высоты набирает обороты потомучто тогда у вас все коллизии с тереном будут статичны

        вы за 1 иф находите под частицу в этом случае высоту, под игрока 1 иф и остается производительность на анимации(тоесть булыжники допустим кидать в загрузку карт дома деревья и будет высота уникальная) (тоесть дом стоит на подступах, деревья и камни с водой имеют тоже уникальные моменты, если всё кроме воды по чему можно ходить вживить в террейн то там поидее будет задача только разбиения и гео рассадки квадрантов)


  1. lgorSL
    16.01.2025 10:45

    Судя по пересвеченным и недосвеченным картинкам вам могут помочь гамма-коррекция, hdr и tone mapping.

    Я пробовал на libgdx свой пайплайн рендеринга сделать - было прикольно, очень красиво, но времени много заняло.

    Ещё из интересного для godot есть экспериментальное расширение для того чтобы писать на kotlin, но пока что остаётся ждать и наблюдать за развитием.


  1. DuhovichSasha
    16.01.2025 10:45

    Программировать игры это хобби. Я у меня тоже есть такая страсть. В магазине продаются кубики Рубика и пирамиды Мефферта любого размера. Программы Популярный размер 3. Вот взял и написал программу на трех языках программирования. Java. Pascal Abc. Python. Для любого размера кубика и пирамиды. Использовал 2D модель для 3D объекта. Применил макрос ( повторяющиеся последовательности вращений). Получилось удобно играть и изучать кубики больших размеров. При недописанной программе обнаружил, что можно определить и игру - НеРубик. Но играть в неё не получается. При вращения боковой плоскости боковая грань не вращается. Приглашаю к поиску алгоритма решения кубика НеРубика. Реального кубика такого нет. А виртуальный есть.


  1. Pugemon
    16.01.2025 10:45

    В тегах ошибка
    Стоит тег "игра на javascript"
    Хотя проект полностью на обычной java....