Melkov's
168 subscribers
582 photos
76 videos
39 files
221 links
Мой движок: @vecxylog
Чат: @melkovteam
Download Telegram
😁5
1😢6😁2👍1🔥1
Простой формат растровых изображений.

Достаточно открыть блокнот и в нем указать разрешение в пикселях. Выставить яркость и массив цветов в формате RGB.

Интересный курс для начинающих по компьютерной графике. Он на основе книги Fundamentals of CG (4 издание).

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

Ссылка: https://www.youtube.com/playlist?list=PLplnkTzzqsZTfYh4UbhLGpI5kGd5oW_Hh
Изучаю компьютерную графику и с полного нуля разрабатываю 2D-движок для веб-игр на TypeScript.

В канале веду дев-логи: копаюсь в графоне, экспериментирую, собираю велосипеды из костылей и делюсь полезными материалами.

На данный идет только процесс обучения и попытки что-то создать.

@vecxylog
🔥4
Forwarded from Vecxy
⚙️Log #9

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

В общем, у нас есть экран HD 1920x1080.

WebGL в свою очередь рендерит все что помещается в диапазон от -1 до 1 как по X, так и по Y. Все что за пределами - не попадает в зону видимости. Собственно это clip space (пространстве отсечения).

Так вот, чтобы от рендерить экран - нам нужно его нормализовать. Это значит чтобы мы позиции точек по ширине в диапазоне от 0 до 1920 (видимый диапазон) - преобразовали в диапазон от -1 до 1 и тоже самое нужно сделать по высоте.

Для этого необходимо наши позиции точек разделить на наш размер экрана Screen (1080, 1920). Ну типа два вектора поделить между собой.
Например у нас точка на нашем экран P1, находится в таких координатах (200, 200)

Поэтому для преобразования в диапазон от -1 до 1 (нормализовать), нужно сделать P1 / Screen = (200 / 1080, 200 / 1920) = (~0,18, 0,10).
Результат округлил, чтобы не писать много цифр, но и webgl умеет тоже округлять качество значений с плавающей точкой через precision в шейдере.

Так вот, мы получили нормализованные координаты, но прикол в том, что они находятся в диапазоне от 0 до 1. Получается что наши позиции точек будут нахдоится где-то сверху в правой части экрана. Почему? Ну потому что webgl рендерит область от -1 до 1 и центр у него находится ровно в (0, 0). А так как у нас нормализованные координаты находятся от 0 до 1, то это справа сверху.

Здесь я не мог понять, потому что не хватало теоретических знаний, но до меня дошло, когда я начал рисовать это дело.

Так вот, помимо того, что у нас нормализованные координаты сверху справа, так они еще и в два раза меньше нашего экрана в конечном итоге.

Чтобы привести в нужный вид, нам необходимо сначала заскейлить это дело, ведь не гоже наши точки уменьшать, для этого нужно умножить на x2 и нормализованные координаты выйдут в диапазон от 0 до 2. Берем нашу нормализованную точку: P1 * 2 = (~0.18 * 2, ~0.10 * 2) = (~0,37, ~0,20).

Ну вот, теперь нормально. Однако, если координаты точки были бы больше 1, то в данный момент webgl их бы не от рендерил за пределами видимой области (clip space).

Теперь нам нужно сделать смещение / перемещение. Собственно так как у нас все находится по прежнему в правом верхнем углу экрана, то нам нужно это сместить ровно на 1 влево и на 1 вниз, потому что наш диапазон теперь от 0 до 2. Берем нашу нормализованную и отскейленную точку: P1 - 1 = (~0,37 - 1, ~0,20 - 1) = (~-0,63, ~-0,79).

Отлично! Теперь наши точки находятся в пределах видимости от -1 до 1 и они смещены в левый нижний угол экрана. Однако есть некое нечистое деяние, это не по стандарту, все должно быть относительно левого верхнего угла экрана. Почему? Ну погуглив и послушав больших дядек из этой области, понял что это маст хев, пока инфы по этому нет, но в вобщем и целом это сложилось исторически + согласованность, чтобы было во всех системах одинаково для упрощения.

Как нам это провернуть? Ну тут все тоже просто, достаточно умножить наши координаты точек на инверсивный вектор. Например сейчас у нас в левом нижнем углу, значит нам нужно поменять только позицию по высоте, отразить их. Для этого берем вектор (1, -1), где X будет 1, потому что нам не нужно менять позиции по X, но будет -1 по Y, чтобы отразить все координаты. P1 = (~-0,63, ~-0,79) * (1, -1) = (~-0.63 * 1, ~0.79 * -1) = (~-0,63, ~0.79)

А вот собственно и весь шейдер данной операции:
#version 300 es;

precision mediump float;

attribute vec2 a_position;
uniform vec2 u_resolution;

void main() {
v_color = a_color;

vec2 n_position = a_position / u_resolution;

vec2 sn_position = n_position * 2.0;

vec2 clip_space = (sn_position - 1.0) * vec2(1, -1);

gl_Position = vec4(clip_space, 0, 1);
}


P.S. На скрине все в кучу, но это было очень эффективно :D
Please open Telegram to view this post
VIEW IN TELEGRAM
В for-циклах ++i и i++ работают одинаково, но ++i теоретически чуть быстрее и используется как более оптимизированный стиль.

++i изменяет значение сразу, без создания временной копии.
i++ создает временный объект, который затем отбрасывается (в некоторых старых компиляторах это могло давать небольшой оверхед).
WebAssembly: Как «невозможное» стало реальностью? https://habr.com/p/892052

"wasm-революционеры... 

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

Вы сначала сами попробуйте сделать что-то на wasm, посмотрите на размер сборки, измерьте скорость на живом примере, покурите, подумайте..."

"Делал на js - sax парсер xml . Так вот работает он быстрее в разы(в 7-10 раз) чем бинарный expat или libxml.
WebAssembly нужная технология, но очень специфичные. И точно не серебряная пуля"

"Сколько я ни смотрел бенчмарков, везде преимущество в скорости WASM было скажем так неочевидно. Да, в узких кейсах может быть преимущество 2-3-5х (откуда автор взял 10х?), но глобально по больнице - приблизительный паритет, иногда даже немного медленнее было. Оговорюсь, что смотрел я это год-два назад, может сейчас что-то поменялось"

#save
Forwarded from Vecxy
This media is not supported in your browser
VIEW IN TELEGRAM
⚙️Log #12

Спрайт, над которым теперь можно делать преобразования — скейлить, вращать и менять позицию.

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

Затем познакомился с аффинной матрицей. Она позволила мне описывать такие преобразования, как масштабирование, поворот и перемещение в 2D-пространстве. Однако, всё ещё есть некоторые шероховатости в понимании, как именно она работает в контексте 2D. Планирую на следующей неделе посвятить ещё несколько дней этому вопросу и углубиться в практику, чтобы лучше разобраться.

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

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

В этом туториале очень качественно эти преобразования объясняются и визуально демонстрируют в софте Nuke Studio. Сегодня себе его установил, чтобы по CG всякие штуки визуально закреплять.

Также поэкспериментировал с ортографической проекцией. Это позволило моему спрайту отображаться одинаково, независимо от его положения относительно камеры. Таким образом, он не искажается при удалении или приближении камеры. Камеру, правда, я еще не реализовал — пока что нужно больше практики в матрицах.

В общем, потрогал много всего, было много трудностей и косяков, но в итоге получилось то, что можно посмотреть в видео. Теперь буду более детально разбирать эти моменты и пробовать разные подходы, чтобы всё закрепить и действительно освоить.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Forwarded from Vecxy
This media is not supported in your browser
VIEW IN TELEGRAM
⚙️Log #13

Это первая птица-иконка, которая научилась двигаться в этом движке!
Please open Telegram to view this post
VIEW IN TELEGRAM
1
This media is not supported in your browser
VIEW IN TELEGRAM
Ахах
😁7
🔥61😁1
Почему в WebGL-проектах на Unity и Cocos и других движках скорость рендера часто ограничена 60 кадрами в секунду, даже если устройство поддерживает больше?

В большинстве случаев браузеры ограничивают requestAnimationFrame до 60fps, потому что он синхронизирован с частотой обновления экрана, и исторически большинство экранов было 60 Гц. Но если у устройства экран, скажем, на 120 Гц, то в некоторых браузерах rAF может отдавать и больше fps — это зависит от самого браузера и платформы. Например, в Chrome на Android с 120 Гц экраном такое вполне возможно, особенно если не тормозит GPU.

Unity действительно использует свой цикл рендера, и может работать быстрее, чем 60fps, если явно не установлен Application.targetFrameRate. Но в WebGL-сборках Unity всё равно ориентируется на rAF, и из-за политики браузера может "залипать" на 60fps, если не удаётся точно синхронизироваться с дисплеем.

Что касается Cocos, то там по умолчанию тоже стоит ограничение на 60fps в продакшн-билде. Надо смотреть, какая версия и движок под капотом (Cocos2d-js, Cocos Creator и т.д.), но обычно можно попробовать выставить вручную cc.game.setFrameRate(120) или аналог, если такая возможность есть. Однако это будет работать только если браузер и устройство реально поддерживают больше, иначе всё равно будет кап.

Так что по факту: ограничение идёт в первую очередь от браузера и дисплея. Движок может только просить "дай мне больше fps", но не факт, что получит :)
👍4
Ахах, постоянно на это попадаюсь :D
👾6
Тесты? Не, не слышал…

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

Но недавно мне подарили книгу по TDD от Кента Бека (хз кто подарил). Что могу сказать? Книга норм, читается легко, не скучно, местами даже увлекательно. Самое главное — она как-то начала заставлять меня посматривать в сторону тестов. Не всегда и не по канону, как того требует TDD-подход, но всё же.

Что важно — я начал видеть реальную пользу от тестов на живых примерах в своей работе. Сейчас, например, пишу DI-контейнер по типу Extenject, но попроще и с фичами, заточенными под конкретный проект. Так вот, тесты там реально помогают. Просто пишешь кейсы, которые нужно проверить, описываешь поведение и ожидаемый результат — и всё, можно спокойно работать над ядром системы. Меняешь что хочешь, как хочешь, не боишься, что что-то отъедет. Потому что тесты тебе сразу покажу где и когда ты соснул .... Очень экономит время и вообще удобно.

Плюс, когда вспомнил прошлые проекты, понял, что было куча моментов, где тесты бы реально пригодились, но я их не писал, потому что был от этого далёк.

Короче, советую нормально и серьёзно присмотреться к теме. Тесты — это реально крутая штука, и далеко не такая бесполезная, как может показаться сначала. Раньше я сам думал, мол, зачем писать этот бесполезный код, который ничего не делает — но это было ошибкой. Главное — найти свою меру: либо идти по хардкору и писать тесты на каждый чих, еще до начала реализации, либо использовать точечно — в сложных местах, где важно проверить поведение и разные кейсы.
👍2
E или F?
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔5🔥1
❄️ Зима

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

Это не часть проекта и не игровой билд — просто идеи и визуальный стиль.

Какой кадр вам кажется самым атмосферным?
👍3
Media is too big
VIEW IN TELEGRAM
Думаю интересно получилось, уже небольшая сцена с каким-то активным действием :D

P.S. Песня по радио в машине играет.
«Катюша» – М. Исаковский / М. Блантер
1👍1
Media is too big
VIEW IN TELEGRAM
Мне кажется это получилось очень атмосферно. Сарай правда не моделировал, но он очень неплохо подошел. Буду его брать в работы, попробую использовать и переделать немного.
👍21
This media is not supported in your browser
VIEW IN TELEGRAM
😁
1😁1
Media is too big
VIEW IN TELEGRAM
Реализовал самую важную механику😁
2😁1