Как создать Minecraft на Python? Обзор библиотеки Ursina Engine / Хабр
Среди любителей Minecraft много энтузиастов: пока одни просто играют, другие запускают целые серверы и пишут модификации. А кто-то идет дальше и разрабатывает собственные песочницы. Последнее достаточно просто сделать на Python.
Под катом делюсь основами работы с библиотекой Ursina Engine и показываю, как с помощью нее создать мир из кубов.
Пояснения внутри кодовых вставок — неотъемлемая часть статьи. Обращайтесь к ним, если что-то непонятно. На более сложные вопросы по работе с библиотекой могу ответить в комментариях под текстом.
Первый чанк: основные элементы библиотеки
Ursina Engine — это полноценный движок под Windows, Linux и Mac, написанный на Panda3D, Pillow и Pyperclip. Его можно использовать для создания 2D- и 3D-игр. В комплекте библиотеки — готовые шейдеры, геометрические примитивы и анимации.
Движок будто консолидирует рутинную работу: разработчику нужно просто импортировать необходимые объекты и проработать логику игры.
from ursina import * app = Ursina() # здесь будет описана игровая логика app.run()
Инициализация окна игры.
Игровая сцена и наблюдатель: объекты типов Entity, FirstPersonController
Дисклеймер: Все, что описано в этом подразделе, лучше использовать для сцен с небольшим количеством объектов. Для более сложных полигонов генерацию нужно оптимизировать — об этом подробнее в следующих разделах. Но пропускать этот блок не советую: здесь объясняю принцип работы с ключевыми элементами библиотеки.
Для наполнения карты нужно использовать объект Entity. По сути, на базе него построены все внутриигровые сущности. Это могут быть как объекты игровой сцены — геометрические примитивы вроде кубов, сфер, квадратов и другого, так и, например, модели мобов.
... app = Ursina() # создаем объекты модели cube, с текстурой white_cube и заданными координатами for x in range(16): for z in range(16): Entity(model="cube", texture="white_cube", position=Vec3(x,0,z)) app.run()
Генерация платформы 16×16 из блоков типа Entity.
После запуска программы на экране появится двумерная картинка. Чтобы увидеть площадку из блоков в 3D, нужно добавить наблюдателя. Это можно сделать с помощью встроенного объекта FirstPersonController.
# импортируем объект from ursina.prefabs.first_person_controller import FirstPersonController ... # добавляем персонажа player = FirstPersonController() # активируем невесомость, чтобы персонаж не упал в пустоту player.gravity = 0.0 app.run() ...
Активация FirstPersonController.
После запуска программы вы увидите простую площадку из блоков. И хоть пока что она выглядит скучно, по ней уже можно перемещаться.
Отображение площадки из блоков после запуска программы.
По умолчанию персонажем можно управлять с помощью мышки и кнопок W, A, S, D. Но есть «фича»: если переключиться на русскую раскладку, то при нажатии кнопки сработает исключение TypeError. Поэтому лучше добавить автоматическое переключение раскладки при запуске программы — например, с помощью win32api.
Текстурирование и кастомные объекты
Кроме встроенных текстур и моделей, Ursina Engine позволяет добавлять собственные. Примеры таких кастомных объектов ищите в репозитории на GitHub.
Текстурирование блоков. Первым делом, мне кажется, лучше добавить и текстурировать блоки. Для этого нужно сделать Blender-модель, заготовить текстуру и импортировать объект в программу.
Blender, модель блока земли.
... # загружаем текстуру grass_texture = load_texture('assets/grass. png') for x_dynamic in range(16): for z_dynamic in range(16): # настраиваем объект Entity, загружаем модель block.obj Entity(model='assets/block', scale=0.5, texture=grass_texture, position=Vec3(x_dynamic,0,z_dynamic)) ...
Загрузка кастомного объекта block.
После запуска программы вы увидите что-то похожее на оригинальную игру.
Результат: платформа из блоков земли.
Текстурирование персонажа. Аналогичным образом можно добавить ту же руку персонажа. Сначала — заготовить текстуру для Blender-модели, а после — импортировать ее в программу через объект Entity. Чтобы закрепить руку рядом с камерой персонажа, нужно «подогнать» параметры — позицию и наклон.
Blender, модель руки.
... # загружаем текстуру руки arm_texture = load_texture('assets/arm_texture.png') # объявляем объект hand, привязываем к камере camera. ui, загружаем модель и размещаем ее в правом нижнем углу hand = Entity(parent = camera.ui, model = 'assets/arm', texture = arm_texture, scale = 0.2, rotation = Vec3(150, -10,0), position = Vec2(0.5,-0.6)) ...
Загрузка кастомного объекта hand.
Результат: в правом нижнем углу появилась рука.
Текстурирование неба. С помощью Entity также можно добавить небо — для этого нужно создать модель сферы и наложить на нее текстуру.
... sky_texture = load_texture('assets/sky_texture.png') sky = Entity( model = 'sphere', texture = sky_texture, scale = 1000, double_sided = True ) ...
Добавление объекта sky.
Результат: над игровой картой появилось небо.
Для создания перехода изо дня в ночь можно использовать функцию update. Она в параллельном потоке программы способна отслеживать время, координаты и другие параметры, а также — модифицировать объекты «на лету».... def update(): print(player.x, player.y, player.z) ...
Пример: функция параллельного вывода координат.
Результат: программа отслеживает актуальные координаты.
Основы взаимодействия с объектами
До этого раздела мы генерировали сцену и наполняли ее основными объектами. Но как с ними взаимодействовать?
Мониторинг действий через функцию input
Сначала нужно научиться отслеживать нажатия клавиш — для этого подходит функция input. С помощью нее можно, например, добавить режим быстрого бега при клике на шифт.
... def input(key): if key == 'o': # кнопка выхода из игры quit() if key == 'shift': # кнопка быстрого бега global shift_click if shift_click % 2 == 0: player. speed = normal_speed + 3 # увеличиваем скорость при нажатии shift_click += 1 else: player.speed = normal_speed shift_click += 1 ...
Программирование режима ускорения.
Также ее можно использовать для удаления и установки блоков при нажатии ЛКМ и ПКМ соответственно.
Включение блоков типа Button
Но не все блоки можно «разрушать». Для того, чтобы добавить в игру взаимодействие с миром, нужно использовать специальный объект Button. Он поддерживает функцию input и метод destroy, который нужен для уничтожения блоков.
... # создаем новый класс на базе Button и задаем стартовые параметры class Voxel(Button): def __init__(self, position=(0, 0, 0), texture=grass_texture): super().__init__( parent=scene, model='assets/block', scale=0.5, texture=texture, position=position, origin_y=0.5, color = color.color(0,0,random. uniform(0.9,1)) ) # добавляем input — встроенную функцию взаимодействия с блоком Voxel: # если нажали на ПКМ — появится блок # если нажали на ЛКМ — удалится def input(self, key): if self.hovered: if key == 'right mouse down': Voxel(position=self.position + mouse.normal, texture=texture) if key == 'left mouse down': destroy(self) # генерация платформы из блоков Voxel for x_dynamic in range(16): for z_dynamic in range(16): Voxel(position=(x_dynamic,0,z_dynamic)) ...
Генерация платформы 16×16 из блоков типа Button.
Результат: землянка, которая напоминает мне почему-то дом Шрека.
Супер — вы научились строить землянку. Попробуйте переплюнуть постройку с картинки.
Проблема оптимизации
Кажется, что статья подошла к концу: ландшафт из блоков готов, работу с объектами и обработку событий освоили. Но есть проблема с оптимизацией. Попробуйте сгенерировать полигон площадью в 1000 блоков — и вы заметите, как стремительно падает FPS.
Это связано с тем, что движок не умеет «безболезненно» загружать большое количество объектов Entity и Button. Конечно, можно последовательно генерировать чанки и удалять старые. Но у этого метода есть пара минусов.
- Не гарантирует стабильную работу. Внутри одного чанка с горной местностью может быть больше блоков, чем в нескольких с пологой.
- FPS все равно страдает. Чтобы подгружать дополнительные чанки незаметно, перед персонажем должно быть несколько сотен блоков. Это значит, что фреймрейт все равно просядет.
Поэтому рассмотренная механика хорошо подходит для создания именно небольших карт. А для генерации «бесконечных» миров лучше использовать объекты типа Mesh.
Арендуйте выделенный сервер с запуском от 2 минут и бесплатной заменой комплектующих. И используйте его ресурсы для гейминга.
Погружение в Mesh
Я бы не написал этот раздел, если бы не канал Red Hen dev. К слову, на нем уже больше года выходят видео по Ursina Engine. Сегодня это лучшая неофициальная документация. Поэтому если вы хотите углубиться, например, в процедурную генерацию мира из Mesh-блоков, переходите по ссылке.
Модель Mesh позволяет генерировать один логический объект и отрисовывать его по заданным координатам, когда как Entity создает в каждой точке новые объекты. Так Mesh потребляет меньше памяти и производительности GPU.
Схема генерации Entity- и Mesh-блоков.
Однако с блоками типа Mesh работать сложнее. Сначала нужно создать объект Entity, загрузить модель Mesh, а после — «слепить» из нее прообраз Blender-объекта (блока). Посмотрите сами.
... # создаем объект Mesh e = Entity(model=Mesh(), texture=this. textureAtlas) # подгружаем конкретную ячейку из атласа текстур (с помощью масштабирования) # атлас текстур — это обычное изображение, в котором собраны текстуры разных блоков e.texture_scale *= 64/e.texture.width def genBlock(this, x, y, z): model = this.subsets[0].model uu = 8 uv = 7 model.uvs.extend([Vec2(uu, uv) + u for u in this.block.uvs]) def genTerrain(this): x = 0 z = 0 y = 0 o_width = int(this.subWidth*0.5) for x_dynamic in range(-o_width, o_width): for z_dynamic in range(-o_width, o_width): # обращаемся к genBlock(), генерируем блоки типа Mesh this.genBlock(x+x_dynamic, y, z+z_dynamic) this.subsets[0].model.generate() ...
Пример генерации площадки из блоков Mesh.
Особенности Mesh
Генерация блоков Mesh — всего лишь одно из препятствий на пути к оптимизации. Есть и другие особенности, которые нужно учитывать.
- По умолчанию с Mesh-блоками нельзя взаимодействовать.
- Mesh-блоки не твердотельны.
Эти проблемы можно решить — например, написать собственные правила для удаления и установки блоков. Или управлять координатами персонажа таким образом, чтобы было ощущение перемещения по твердой поверхности.
Эти и другие решения уже есть — ищите их в GitHub-репозитории проекта Red Hen dev.
Генерация мира
Теперь, когда нет жестких ограничений на количество объектов внутри игровой сцены, можно сгенерировать Minecraft-подобный мир. Встроенные методы для этого не предусмотрены. Но есть простой способ — создать матрицу из шумов Перлина и последовательно «отрисовывать» ее внутри игры.
Матрица из шумов Перлина
Шум Перлина — это алгоритм процедурной генерации псевдослучайным методом. Механика такая: вы подаете на вход число seed, на базе которого генерируется текстура поверхности.
Шумы Перлина в разном масштабе.
Если не менять внутренние параметры алгоритма, то при загрузке одного и того же значения seed шум будет одинаковым.
from numpy import floor from perlin_noise import PerlinNoise import matplotlib.pyplot as plt noise = PerlinNoise(octaves=2, seed=4522) amp = 6 freq = 24 terrain_width = 300 landscale = [[0 for i in range(terrain_width)] for i in range(terrain_width)] for position in range(terrain_width**2): x = floor(position / terrain_width) z = floor(position % terrain_width) y = floor(noise([x/freq, z/freq])*amp) landscale[int(x)][int(z)] = int(y) plt.imshow(landscale) plt.show()
Генерация «красивого» шума Перлина.
Генерация сложного ландшафта
По сути, шум Перлина формирует двумерный массив с плавными спадами и подъемами по координате y. Его достаточно просто перенести в игру.
... for x_dynamic in range(-o_width, o_width): for z_dynamic in range(-o_width, o_width): # генерация Mesh-блока в заданной точке, координату y берем из алгоритма Перлина this. genBlock(x+x_dynamic, this.landscale[x+x_dynamic][z+z_dynamic], z+z_dynamic) ...
Генерация ландшафта.
Подобным образом возможно генерировать не только ландшафты, но и, например, шахты. Только в последнем случае используются черви Перлина. Подробнее о разных алгоритмах и принципах генерации мира можно узнать тут.
Результат: Minecraft-подобный ландшафт.
Элементы «атмосферы»: шейдеры и аудио
Игра до сих пор кажется плоской: ей не хватает музыки, звуков и чего-то «нового». Если другие блоки — песок, камень, дерево — добавить просто, то с анимированными объектами — например, водой — ситуация сложнее.
Добавление шейдеров
В Ursina Engine есть готовый набор шейдеров, которые можно импортировать из подмодуля ursina.shaders и подключить к нужным Entity-объектам. Это полезно, если нужно, например, показать объем объектов.
from ursina.shaders import basic_lighting_shader ... e = Entity(..., shader = basic_lighting_shader) ...
Пример подключения шейдера.
Ursina Engine, встроенные шейдеры.
Также к шейдерам можно причислить туманность, которая есть и в оригинальной игре. Она нужна, чтобы «сбить» фокус с дальних объектов.
... scene.fog_density=(0,95) # scene, как и window, тоже один из основных элементов библиотеки. Иногда его можно встретить в параметре наследования parent. Хотя, по моему опыту, его использование скорее опционально, чем обязательно. scene.fog_color=color.white ...
Добавление туманности.
Не всегда туманность смотрится хорошо. Возможно, стоит поэкспериментировать с параметром color.
Ursina Lighting. В целом, это все, что нужно знать о встроенных шейдерах. Но есть аналог ursina. shaders — открытая библиотека Ursina Lighting. С помощью нее можно добавить даже воду.
# импортируем основные объекты. Предварительно нужно развернуть репозиторий UrsinaLighting внутри своего проекта. from UrsinaLighting import LitObject, LitInit ... # важно! нужно инициализировать главный объект. lit = LitInit() ... # заполняем нижние уровни ландшафта водой (y = -1.1), создаем текстуру воды размером с ширину ландшафта. Проседать FPS не будет, тк water — это один объект, который просто «растянут» вдоль игровой сцены water = LitObject(position = (floor(terrain.subWidth/2), -1.1, floor(terrain.subWidth/2)), scale = terrain.subWidth, water = True, cubemapIntensity = 0.75, collider='box', texture_scale=(terrain.subWidth, terrain.subWidth), ambientStrength = 0.5) ...
Подключение UrsinaLighting и добавление воды.
Обратите внимание: вода буквально отражает небо. Мне кажется, что она выглядит лучше, чем в оригинальной игре.
Добавление звуков и музыки
Ursina Engine умеет воспроизводить аудиофайлы формата mp3 и wav. Так, например, можно добавить музыку C418 и разные звуки.
... punch_sound = Audio('assets/punch_sound',loop = False, autoplay = False) ... class Voxel(Button): ... def input(key): if key == 'left mouse down': punch_sound.play() ...
Добавление музыки и звуков удара.
Возможно, эти тексты тоже вас заинтересуют:→ Как запустить динозаврика Google на тачбаре? Обзор Python-библиотеки PyTouchBar
→ Каким должен быть Feature Store, чтобы оптимизировать работу с ML-моделями
→ 7 полезных книг по Python для старта и развития
Меню игры: основные элементы GUI
На базе Entity делают не только 3D, но и полноценные графические интерфейсы. Логично, ведь все элементы GUI — это двумерные объекты, с которыми Ursina Engine также работает хорошо.
Движок поддерживает элементы типа Text и ButtonList. Последний автоматически создает кнопки и привязывает к ним функции, которые срабатывают при нажатии.
Ниже — пример программирования простого меню игры.
# в отдельном файле menu.py from ursina import * app = Ursina(title='Minecraft-Menu') # создаем объект на базе Entity, настраиваем камеру и бэкграунд class MenuMenu(Entity): def __init__(self, **kwargs): super().__init__(parent=camera.ui, ignore_paused=True) self.main_menu = Entity(parent=self, enabled=True) self.background = Sky(model = "cube", double_sided = True, texture = Texture("textures/skybox.jpg"), rotation = (0, 90, 0)) # стартовая надпись Minecraft Text("Minecraft", parent = self.main_menu, y=0.4, x=0, origin=(0,0)) def switch(menu1, menu2): menu1.enable() menu2.disable() # вместо print_on_screen можно вписать lambda-функцию для запуска игры ButtonList(button_dict={ "Start": Func(print_on_screen,"You clicked on Start button!", position=(0,. 2), origin=(0,0)), "Exit": Func(lambda: application.quit()) },y=0,parent=self.main_menu) main_menu = MenuMenu() app.run()
Примитивный GUI на базе Ursina Engine.
Результат: «100%-сходство» с оригинальным меню.
Смотрим, что получилось
Код из статьи доступен на GitHub. Делайте «форк» и используйте его в качестве референса, а также предлагайте свои улучшения.
Получившийся проект издалека напоминает ранние версии Minecraft. Хотя и превосходит их по качеству шейдеров и текстур.
На самом деле, это лишь небольшая доля того, что можно сделать на базе Ursina Engine. Энтузиасты со всего мира создают на этом движке шутеры, платформеры и другие игры. И это оправдано: время разработки на Ursina Engine меньше, чем на чистом OpenGL. А качество игры выше, чем на том же PyGame.
Но несмотря на позитивный результат, хочу отметить и негативные моменты в работе с библиотекой.
Проблемы Ursina Engine
Нет подробной документации. О назначении некоторых параметров остается только догадываться. Документация ограничивается небольшим лендингом и репозиторием с примерами. Последнего недостаточно, чтобы полностью понять механику работы с объектами.
«Сырая» кроссплатформенность. На MacOS трудно управлять камерой персонажа: курсор постоянно слетает, а иногда и вовсе не перемещается. Некоторые элементы из UrsinaLighting не поддерживаются. Это нужно учитывать, если вы разрабатываете полноценный проект.
Не хватает элементов. Например, взаимодействие с объектами типа Mesh нужно программировать самостоятельно.
Что думаете по поводу этой библиотеки вы? Поделитесь мнением в комментариях.
Виртуальный музей шейдерной магии — Игры на DTF
Будущее уже наступило, просто оно еще неравномерно распределено
— Уильям Гибсон (цитата на стене одного из залов музея)
2688 просмотров
Что вам приходит в голову, когда вы слышите выражение «виртуальный музей в метавселенной»? Ставлю на то, что перед глазами сразу всплывает кринжовая картинка вроде этой:
Цукеровселенная. жпг
Ну или в лучшем случае что-то, отдаленно похожее на копию реального музея с репродукциями произведений искусства из реального мира, нередко тоже весьма отдаленно похожими на оригинал (прям как на картинке выше).
Или самое страшное — выставка картинок с уродливыми обезьянами, владельцы которых умоляют купить у них эти произведения «искусства» за крипту.
Я сам еще неделю назад представил бы ровно такую же картинку. Но на днях я встретил то, что полностью поменяло мое представление о виртуальных музеях.
Настолько, что захотелось написать статью про самый настоящий музей шейдерного искусства, на который мне повезло наткнуться практически случайно. Тем более, что в интернете почти нет информации об этом явлении, а на русском языке ее нет вообще.
Лобби музея
Trigger warning: Метавселенные
Не спешите закрывать, я не собираюсь агитировать вас уходить жить в Horizon Worlds или покупать мусорные NFT.
Забудем про все то, что стали называть словом «метавселенная» за последний год, будто бы все это приснилось нам в бредовом сне. Давайте лучше обратим внимание на то, что появилось задолго до поделок последних лет и называлось этим бранным словом до того, как оно стало ругательным.
Я говорю про VRChat.
Типичный паблик в виарчате
Уверен, и про него вы сможете сказать немало «теплых» слов. Вакханалия из школия, щитпостовых аватарок, мемов и фуррей с грудастыми аниме тянками — всё это виарчат. Точнее, его фасад, с этим сталкивается новичок впервые попав сюда. Можно сказать, обратная сторона практически ничем не ограниченной свободы самовыражения. Здесь полно творческих людей. Кто-то создает аватары своей мечты (и это отдельная тема для исследования), кто-то занимается высокоуровневым щитпостом, а кто-то создает миры.
Старпёры вроде меня могут сравнить это со старым интернетом, где могли и на три буквы послать, и свободно разговаривать на абсолютно любые темы, не придумывая новояз, позволяющий обходить системы автоматической цензуры, и свободно креативить, не парясь за алгоритмы продвижения в соцсетях.
Высокоинтеллектуальный контент из 2007-го
Обратной стороной этой картинки было то, что интернет той эпохи, как и VRChat был той еще помойкой, в которой приходилось подолгу копаться, чтобы найти что-то интересное именно тебе.
Сам я практически не интересовался виарчатом до недавнего времени, один раз заходил туда побегать четыре года назад, когда только обзавелся VR-шлемом, не нашел ничего интересного и забил.
Но интересоваться VR и не натыкаться время от времени на видео про него невозможно. Неделю назад ютуб подсунул мне вот это видео:
Это видео продало мне VRChat во второй раз
Автор, инженер-электронщик, раскрыл VRChat с необычной стороны, не только как социальную платформу, где еще жив дух настоящей свободы и анархии, но и как площадку творчества сообщества разработчиков шейдеров. В видео он упоминает ShaderFes — музей-выставку работ этого сообщества, о которой я и хотел бы рассказать в этой статье.
Чистая математика, картинка рисуется без подачи на вход шейдера текстур или полигонов
Если вы интересуетесь программированием игровой графики, то наверняка слышали про ShaderToy (а может быть даже выкладывали туда свои работы), и многие экспонаты этого музея-выставки вас не особо удивят.
Действительно, сообщество, создавшее выставку ShaderFes не первым пришло к тому, чтобы выкладывать на всеобщее обозрение свои достижения в шейдеростроении. Но они первые (поправьте, если это не так), кто сделал оформленную выставку работ, которую может посетить любой человек, никак не связанный с разработкой игр или программированием графики и не вхожий в сообщество.
Конечно, работы на ShaderToy от этого не становятся хуже, но знают о них немногие, это настоящий гиковский андерграунд, случайно наткнуться на который довольно сложно. Выставка ShaderFes делает шаг (пусть пока и робкий, так как о ней мало кто знает) навстречу более широкой аудитории.
Все еще введение. Что такое шейдеры
Наверное, материал будет не совсем полноценным, если не уделить пару строк описанию того, что такое шейдеры.
Если вы ставили шейдер-паки на Майнкрафт или ReShade на любые другие игры, то наверняка видели, как сильно замена шейдеров может поменять картинку:
Майнкрафт с заменой шейдеров. Слева сверху — оригинал с примитивным шейдером
Если сильно упростить, то шейдер — это небольшая программа, заточенная под выполнение полностью на видеокарте, и формирующая из набора текстур, полигонов и числовых параметров ту картинку, которую мы в итоге видим на экране. Освещение, блики, тени, анимации рассчитываются шейдерами. Простенький шейдер может состоять всего из нескольких десятков строк, и написать его сможет даже новичок в теме, но и выдавать он будет картинку, вроде той, что в Майнкрафте по дефолту.
Код этих программ мало похож на знакомый любому программисту код для процессора (независимо от языка, основные принципы тут те же). Циклы и условные переходы считаются дурным тоном в шейдерах, и хороший оптимизированный шейдер в идеале не должен содержать ни первого, ни второго, только чистый набор математических операций с данными, результатом которых становится буквально несколько байт — цвет пикселя на экране. По необычности чем-то напоминает Verilog — язык, на котором инженеры-электронщики разрабатывают процессоры и прочую электронику, но без такой плотной связи с железом и не такой чужеродный.
В общем, написание шейдеров работа не для каждого, здесь требуется как знание железа, так и хорошая математическая подготовка, да и без чувства прекрасного тоже сложно обойтись, если надо сделать что-нибудь красивое.
Если вам хочется немного больше подробностей, то на DTF уже выходила статья, которая детальнее описывает основы работы шейдеров:
Шейдеры. Что и как
Говоря общими словами, шейдер — это просто программа для графической карты. То есть то, что пишется школьниками на паскале (хипстерами на пайтоне) — это программы для вашего центрального процессора (CPU), а шейдеры — для графического (GPU). Особенность же этих программ выходит из особенностей GPU — они работают параллельно на сотнях маленьких…
GPU-ядрышки резвятся на фоне серьезного CPU
ShaderFes 2021 — Всемирная выставка нашего времени
(или ее демоверсия)
Фоновая музыка выставки
Добрались до сути, наконец-то.
ShaderFes — музей, или выставочный центр, похожий на те, что мы привыкли видеть в реальности: всё оформлено с большим вниманием к деталям, здание музея само по себе оставляет довольно хорошее впечатление. Внутри приятно находиться, фоном играет ненапряжная музыка, а стрелки и вспомогательные таблички помогают не заблудиться, и даже для аватаров-малоросликов есть возможность включить ступеньки, позволяющие подняться к поближе к экспонатам (это действительно важно, особенно если ты играешь морской свинкой в масштабе 1:1)
В центральном лобби вас встретит схема выставочных залов, которые здесь разбиты на четыре цветовых группы — Red, Green, Blue, Aplha (прямо как четыре компоненты цвета, которые вычисляет шейдер)
Каждая группа представляет собой цепочку из соединенных залов, пройдя которые вы вернетесь в лобби, и сможете начать просмотр следующей выставочной группы. У каждой группы свой цвет, вы точно не запутаетесь и не попадете случайно в те залы, в которых уже были. В зону Alpha вы попадаете, поднявшись на лифте, который здесь работает без дыма и зеркал, честно поднимая вас наверх, пока вы разглядываете лобби с высоты.
Залы выставки оформлены достаточно минималистично, хотя и не без любви к мелочам. Например, на стенах залов встречаются панели пожарной сигнализации. В общем, приятно глазу, но от главной ценности выставки ничто не отвлекает.
Со зданием разобрались, но это всего лишь декорация, создающая нужную атмосферу. Самое интересное — экспонаты, находящиеся в залах выставки. Здесь показано более двухсот работ от 80+ авторов со всего мира, но преимущественно из Японии.
Музей можно смело назвать интерактивным: многие экспонаты можно взять в руки, покрутить, засунуть внутрь голову, или залезть целиком, чтобы оказаться внутри фрактала, например.
У некоторых работ можно поменять параметры шейдера, подвигав слайдеры поблизости, нередко это может изменить облик шейдера до неузнаваемости.
У всех экспонатов есть табличка с описанием. Жаль, что нередко это описание исключительно на японском языке.
Дальше будет куча скринов и клипов с экспонатами выставки. Это лишь малая часть того, что там есть, выставка действительно очень большая. Хочу заранее отметить, что многие экспонаты полностью раскрываются только в VR, и на плоской ПК-версии могут выглядеть не так интересно, как через VR-шлем.
В VR это выглядит шикарно
Некоторые экспонаты могут выглядеть на первый взгляд довольно просто и не очень интересно. Но их красота внутри — часто подобные экспонаты созданы из чистых математических выражений, без использования текстур или других входных данных. Да, на практике легко было бы достичь того же результата более простыми средствами, но когда искусство было про практичность?
А это явно сугубо практичный сегмент выставки. Всё, что надо чтобы собрать аватар вайфу своей мечты: Шейдеры кожи, одежды, волос, ткани, даже глаза:
Отдельные экспонаты поражают воображение своей технической сложностью, хотя я считал, что меня сложно чем-то удивить. Шахматный ИИ на шейдере? Нейросетка с распознаванием образов? Переводчик? Всё это можно найти в выставочных залах, честно говоря, я до этого и не подозревал, что такое можно сделать, используя исключительно графические шейдеры на юнити:
Под потолком выставочного комплекса есть целый холодек, но после основной экспозиции он уже не так впечатляет:
К сожалению, не могу много рассказать об истории этой выставки, и о сообществе, которое за ней стоит, но знаю, что большая часть авторов из Японии, вот тут можно почитать интервью с ними (на японском, но гугл транслейт JP > EN переводит вполне сносно)
Современное искусство?
Я знаком с разработкой игр не понаслышке и довольно хорошо представляю себе сложность современных игр, даже казалось бы на первый взгляд простых.
Игры давно стали видом искусства, объединяющим и изобразительное искусство, и музыку, и литературу, и вносящим новую глубину — интерактивность.
В игровой разработке есть особенные области на стыке сразу нескольких профессиональных сфер — и программирование шейдеров одна из них. Чтобы сделать что-то крутое на шейдере, надо быть человеком-оркестром: хорошо программировать, отлично разбираться в математике, обладать воображением и художественным вкусом, чтобы получившийся результат был приятен глазу. Дополнительной сложности всему этому придают многочисленные технические ограничения, которые приходится преодолевать в процессе работы. В конце концов, итоговый результат должен работать достаточно быстро, чтобы выдавать хотя бы 60 кадров в секунду на среднем игровом ПК.
Если подобные работы не заслуживают того, чтобы называться искусством, то это проблема искусства
Искренне и абсолютно неиронично говорю, что я готов считать подобные работы искусством, безо всяких приставок вроде «пост», «мета» и прочее.
Надеюсь, со временем споры о праве видеоигр называться искусством станут историей, наряду с сомнительными образчиками современного искусства вроде банана, прилепленного изолентой к стене. А видеоигры, и все, что с ними связано, займут свое заслуженное место среди других, более привычных человечеству видов искусств.
Как посетить выставку?
Попасть в музей несложно. Виарчат бесплатен, не требует шлема виртуальной реальности. Хотя если он у вас есть и давно лежит без дела, советую все же подключить его к ПК и посетить музей именно в VR-режиме.
Устанавливаете VRChat на ПК (версия под Oculus Quest не годится, увы), регистрируетесь, проходите пятиминутный тутор и ищете в списке миров «ShaderFes 2021», переходите в него и наслаждаетесь выставкой воочию.
Для VR-режима желательно иметь компьютер помощнее, некоторые экспонаты очень жадные до ресурсов, да и сам виарчат не слишком хорошо оптимизирован.
Если затянет, то советую посоветовать посмотреть на ShaderFes прошлых лет, он поменьше и попроще, но тоже ничего. И обязательно посетите Treehouse in the shade, безумно красивый чилл-мирок, в котором можно надолго залипнуть под красивую музыку, размышляя о вечном, ведь автора этого мира уже нет среди живых.
Или полазить по ShaderToy, там за годы скопились тысячи восхитительных работ.
Спасибо что прочитали мой первый лонг, надеюсь вам было интересно!
Pascal Programming Assignment Help — Служба написания заданий
Pascal — это императивный и структурированный язык программирования, разработанный Никлаусом Виртом в 1970-х годах. Этот язык широко преподается студентам, поскольку он прост для понимания, позволяет создавать прозрачные, надежные и эффективные программы и может работать в соответствии с различными компьютерными платформами. Чтобы помочь им хорошо освоить язык программирования Pascal, им поручается письменное задание на нем. Но из-за проблем с отладкой ошибок при запуске программы на этом языке, большинство из них обращаются за помощью по программированию на Паскале. Если вы тоже застряли в отладке своей программы на Паскале, вот несколько концепций, которые вам необходимо четко понимать, чтобы лучше писать задания на Паскале.
Несколько важных концепций языка программирования Pascal 1. Изучение различных компиляторов и интерпретаторов, используемых в языке Pascal. Вот некоторые из них: Turbo51, Free Pascal, Turbo Pascal, GNU Pascal, Oxygene и Delphi. Существует три версии, в которых вы можете скачать Pascal бесплатно: tar.gz (можно загрузить как отдельный файл), версию Red Hat Package Manager (.rpm) и версию Debian (.deb). 2. Знание различных элементов структуры программирования на Паскале, таких как имя программы, команды, объявления (типы, переменные, функции, процедуры и константы), основной блок, операторы и выражения в каждом блоке и комментарии. 3. Хорошее владение всеми понятиями, описанными в базовом синтаксисе языка Pascal, такими как объявление переменных, функций или процедур, комментариев, чувствительности, зарезервированных слов (массив, in, of, div и т. д.), операторов, наборов символов и т. д. его идентификаторы. 4. Знание различных типов данных языка программирования Pascal. Три основных типа данных — скалярные, указательные и структурированные. Скаляр подразделяется на стандартный (целое, вещественное, логическое, символьное) и определяемый пользователем (нумерованный и поддиапазон). Структурированный подразделяется на массив, файл, запись и набор. 5. Изучение переменных и констант на языке программирования Pascal. Вам также необходимо знать о различных типах переменных (символьные, целые, логические и т. д.) и константах (строки, символы, вещественные типы и т. д.). 6. Знание того, как операторы Паскаля позволяют компиляторам манипулировать математическими или логическими операциями. Кроме того, вы также должны знать о различных типах операторов, символов и их описании, используемых в этом языке программирования. Существуют различные типы операторов: арифметические, отношения, логические и битовые. Вам также необходимо знать о приоритете операторов в Паскале, чтобы вы могли легко группировать термины в выражении.
Хотите знать, почему перед написанием задания вам следует подумать об изучении основных концепций программирования на языке Pascal? Просто продолжайте читать и получите ответ на свой вопрос.
Ну, теперь вы, должно быть, поняли, почему важно изучить Паскаль, прежде чем писать на нем задание. Кроме того, вы также должны знать основные понятия, которые вам необходимо учитывать для написания лучшего задания на Паскаль. |
Программа Python для печати треугольника Паскаля
Сохранить статью
Треугольник Паскаля — это образец треугольника, основанный на nCr , ниже представлено графическое изображение треугольника Паскаля.
Пример:
Ввод : N = 5 Вывод: 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1
Метод 1: Использование формулы nCr , т. е. n!/(n-r)!r!
После использования формулы nCr графическое представление становится следующим:
0C0 1С0 1С1 2С0 2С1 2С2 3C0 3C1 3C2 3C3
Алгоритм:
- Возьмем количество строк для печати, предположим, что это n
- Выполните внешнюю итерацию i от 0 до n раз, чтобы напечатать строки.
- Сделать внутреннюю итерацию для j от 0 до (N – 1).
- Печать одного пробела ” “.
- Закрыть внутреннюю петлю (j-петля) //необходимо для левого интервала.
- Сделать внутреннюю итерацию для j от 0 до i.
- Печать nCr i и j.
- Закрыть внутреннюю петлю.
- Печатать символ новой строки (\n) после каждой внутренней итерации.
Implementation:
Python3
|
Output:
1 1 1 1 2 1 1 3 3 1 1 4 6 4 1
Временная сложность: O(N 2 )
Вспомогательное пространство : O(1)
Метод 2: Мы можем оптимизировать приведенный выше код, используя следующую концепцию биномиального коэффициента, i-го запись в строке номер строка представляет собой биномиальный коэффициент C(строка, i) , и все строки начинаются со значения 1. Идея состоит в том, чтобы вычислить C(строка, i) , используя C(строка, i-1) .
C(строка, i) = C(строка, i-1) * (строка - i + 1) / i
Implementations:
Python3
Временная сложность: O(N 2 ) Метод 3: Это наиболее оптимизированный подход к печати треугольника Паскаля. основано на степенях числа 11. 11**0 = 1 11**1 = 11 11**2 = 121 11**3 = 1331 Implementation: Python3
|