Так. У меня еще одна работа теперь 😁 Снова фреймворк для рисования🤣 но теперь больше вектора
❤7👏1🤯1
Forwarded from Hyperadio
Друзья! Вещание hyperadio в тестовом режиме продолжается.
Не забудьте обновить ссылки!
🖥 stream.hyperadio.ru — основная страничка радио
🔈 stream.hyperadio.ru/live — поток в MP3
🔈 stream.hyperadio.ru/live2 — поток в OGG
♥️ donate.stream/nodeus — а здесь можно внести посильную помощь на содержание сервера вещания.
Не забудьте обновить ссылки!
🖥 stream.hyperadio.ru — основная страничка радио
🔈 stream.hyperadio.ru/live — поток в MP3
🔈 stream.hyperadio.ru/live2 — поток в OGG
♥️ donate.stream/nodeus — а здесь можно внести посильную помощь на содержание сервера вещания.
Наконец добрался до разбора долгов: допилил статью про инструменты профилирования метала. Осталась еще пара эпизодов в этой серии: про диагностику ручками без инструментов и про TDD шейдеров.
https://gostrobrod.dev/articles/metal/mtl_s02e08.html
https://gostrobrod.dev/articles/metal/mtl_s02e08.html
George Ostrobrod
08. Metal System Trace | George Ostrobrod Blog
Though GPU frame capture in Xcode provides some performance details, it’s usually not very precise because time values may change from frame to frame due to thermal conditions, other GPU load, and so on. So I recommend using Instruments...
🔥2❤1👀1
Сел писать последний раздел инструментов Метала про ручные приемы, и оказалось, что там выходит материала еще на три статьи. Сезон немного разросся относительно того, что я изначально планировал. Вот какая-то такая будет разбивка по частям:
• Что и как выводить
• Как и куда выводить
• Зачем выводить и для чего
Из плохого (сложного) - придется делать кучу примеров, но постараюсь не сильно закапываться, хотя некоторые примеры/разделы потребуют немного углубится.
Из хорошего - эти приемы в большинстве своем валидны не только для Метала - я их начинал еще с OpenGL использовать, так что целевая аудитория немного шире будет.
Надеюсь, будет полезно. Как только завершу с металом, сделаю пост/серию/видео/статью про гладкий рендеринг (по заявкам), а потом наверное продолжу видеоэффекты, которые пол года назад остановились по какой-то причине
• Что и как выводить
• Как и куда выводить
• Зачем выводить и для чего
Из плохого (сложного) - придется делать кучу примеров, но постараюсь не сильно закапываться, хотя некоторые примеры/разделы потребуют немного углубится.
Из хорошего - эти приемы в большинстве своем валидны не только для Метала - я их начинал еще с OpenGL использовать, так что целевая аудитория немного шире будет.
Надеюсь, будет полезно. Как только завершу с металом, сделаю пост/серию/видео/статью про гладкий рендеринг (по заявкам), а потом наверное продолжу видеоэффекты, которые пол года назад остановились по какой-то причине
🔥11❤4👍4
Пока вот вам статья про быструю математику на свифте и дальше от коллеги с третьей работы
https://www.cocoawithlove.com/blog/matrix-multiplications-swift.html
https://www.cocoawithlove.com/blog/matrix-multiplications-swift.html
👍4🤯3
Итак, первая часть
https://gostrobrod.dev/articles/metal/mtl_s02e09.html
https://gostrobrod.dev/articles/metal/mtl_s02e09.html
George Ostrobrod
09. Manual Diagnostics: pt.1 Value level | George Ostrobrod Blog
There could be cases in your project when GPU Frame Capture may not work (Xcode can crash on it) or may take too much time. And usually you don't have any opportunity to get values from shader code on the CPU side. Actually, you do, beca...
👍4❤2
Наконец я завершил второй сезон Метала. Гештальт закрыт.
https://gostrobrod.dev/articles/metal/mtl_s02e10.html
https://gostrobrod.dev/articles/metal/mtl_s02e10.html
George Ostrobrod
10. Manual Diagnostics: pt.2 Tooling level | George Ostrobrod Blog
This article is now part of a book
🔥9👍3
Этой песне больше 60 лет. Она была написана задолго до рождения киберпанка, интернета и всего вот этого цифрового. Но сейчас в ней больше киберпанка, смысла и актуальности, чем во всем опопсевшем ныне кибер”панке”.
https://youtu.be/6ukmjBSQY-c?si=GsFuWdIcVJHdw0Ln
https://youtu.be/6ukmjBSQY-c?si=GsFuWdIcVJHdw0Ln
YouTube
Simon and Garfunkel - The Sound of Silence (1966)
"The Sound of Silence" is a song by singer-songwriter duo Simon & Garfunkel. Written in February 1964 by Paul Simon in the aftermath of the 1963 assassination of John F. Kennedy, the song propelled the group to mainstream popularity. An initial version preferred…
🔥5👍1
4-manual-msaa.png
849.5 KB
Итак, по заявкам трудящихся расскажу, как рисовать гладкие полигоны и линии (анти-алиасинг)
Самый простой способ антиалиасинга - суперсэмплинг.
Идея суперсэмплинга в том, чтобы посчитать значение в нескольких точках, а потом их схлопнуть в один пиксель.
Самый простой (но не самый экономный) способ - отрисовать в текстуру в два раза больше, а потом обратно в нужный размер с линейной интерполяцией. Будет красота по всей сцене, но вам надо х3 памяти, и x5 пиксельрейт. Не самая экономная штука в общем.
Я буду прикреплять картинку как есть, чтобы можно было поразглядывать
Самый простой способ антиалиасинга - суперсэмплинг.
Идея суперсэмплинга в том, чтобы посчитать значение в нескольких точках, а потом их схлопнуть в один пиксель.
Самый простой (но не самый экономный) способ - отрисовать в текстуру в два раза больше, а потом обратно в нужный размер с линейной интерполяцией. Будет красота по всей сцене, но вам надо х3 памяти, и x5 пиксельрейт. Не самая экономная штука в общем.
Я буду прикреплять картинку как есть, чтобы можно было поразглядывать
👍1
2-msaa.png
827.4 KB
Чтобы не городить огород, во всех нормальных фреймворках есть встроенный мультисэмплинг. В Метал-е для этого нужно указать число сэмплов у пайплайна и таргет текстуры (+ тип текстуры `.type2DMultisample`), а у энкодера будет что-то такое в рендер таргетах:
Что мы тут видим: фрагменты летят по числу сэмплов в
let pass = MTLRenderPassDescriptor()
pass.colorAttachments[0].texture = msaaTexture
pass.colorAttachments[0].resolveTexture = resolveTexture
pass.colorAttachments[0].loadAction = .clear
pass.colorAttachments[0].storeAction = .multisampleResolve
Что мы тут видим: фрагменты летят по числу сэмплов в
msaaTexture, а потом уже резолвятся в выходную текстуру resolveTexture. По дефолту оно будет у вас антиалиасить только геометрию, которая идет через пиксели. Внутри геометрии все будет по прежнему. Об этом дальше.👍1
3-persample.png
853.3 KB
Вот чтобы делать MSAA буквально как суперсэмплинг, во фрагментном шейдере нужно обрабатывать каждый сэмпл (`[[sample_id]]`) отдельно по типу такого:
Проект я потом отдельно прикреплю.
fragment float4 circle_msaa_persample_fragment(TriangleOut in [[stage_in]],
constant ScreenUniforms &screen [[buffer(0)]],
uint sampleID [[sample_id]]) {
const float2 sampleOffsets[4] = {
float2(-0.125, -0.375),
float2(0.375, -0.125),
float2(-0.375, 0.125),
float2(0.125, 0.375)
};
float2 pixel = in.position.xy + sampleOffsets[sampleID & 3u];
float2 ndc = demoPixelToNdc(pixel, screen.resolution);
float3 color = demoTriangleCircleColor(ndc, 1.0);
return float4(color, 1.0);
}
Проект я потом отдельно прикреплю.
👍1
5-derivatives.png
841.1 KB
MSAA - это все здорово, но часто дорого.
Если у вас задача про процедурную геометрию на базе SDF например, то дешевле использовать производные и
Если у вас задача про процедурную геометрию на базе SDF например, то дешевле использовать производные и
smoothstep:
float d = length(uv) - 0.55;
float aaMask = 1.0 - smoothstep(-fwidth(d), fwidth(d), d);
👍1
6-subpixel.png
9.1 MB
Если вы особые ценители прекрасного, то для вас еще есть и субпиксельный антиалиасинг. Его вы скорее всего видели на шрифтах (когда на символах будто цветовая аберрация).
Суть его в том, что мы используем каналы пикселя (часто это тупо три палочки RGB), то есть мы делим пиксель на три трети и в зависимости от покрытия заливаем их соответствующим образом.
Техника эта зависит от реализации матрицы дисплея, потому не факт, что супер универсально.
Суть его в том, что мы используем каналы пикселя (часто это тупо три палочки RGB), то есть мы делим пиксель на три трети и в зависимости от покрытия заливаем их соответствующим образом.
Техника эта зависит от реализации матрицы дисплея, потому не факт, что супер универсально.
🔥4
1-mipmap.png
3.1 MB
Это не совсем про антиалиасинг, но про работу с артефактами интерполяции.Если вы возьмете текстуру и просто отрисуете ее лажащей в XZ плоскости в перспективной проекции, то по мере удаления ваша текстура превратится в кашу даже с линейной интерполяцией (билинейной на самом деле).
Соль в том, что линейная интерполяция это не про среднее всех пикселей между двумя выбранными (это называется area), а именно что только этих двух пикселей. То есть, очевидно, у вас потеряется очень много информации на больших масштабах.
Решается это через мипмапы (пирамида, где каждый следующий слой это х2 меньшая картинка). Там при сэмплинге соовтествующих пикселей не теряется информация, потому как при генерации у нас усредняются попарно все соседние пиксели. Тут есть два варианта:
1. При загрузке текстуры через
2. При создании тексутры указывать что нужны мипмапы и пото генерировать блит операцией (`blit.generateMipmaps(for: texture)`).
Далее мы можем включить трилинейную интерполяцию: значение будет браться средним по ближайшим слоям мипмапа, а потом еще и между ними. В итоге получается гладенько красиво. Все, что надо, указать
Это может быть полезно для нормальной отрисовки геометрии, если вы, скажем отрисовали линию на текстуре, а потом натягиваете эту плоскость на что-то еще. Вот чтобы эту линию не попердолило, лучше генерировать мипамап пердварительно. Делается это довольно быстро на фоне всего остального, но жрет х1.5 памяти.
Соль в том, что линейная интерполяция это не про среднее всех пикселей между двумя выбранными (это называется area), а именно что только этих двух пикселей. То есть, очевидно, у вас потеряется очень много информации на больших масштабах.
Решается это через мипмапы (пирамида, где каждый следующий слой это х2 меньшая картинка). Там при сэмплинге соовтествующих пикселей не теряется информация, потому как при генерации у нас усредняются попарно все соседние пиксели. Тут есть два варианта:
1. При загрузке текстуры через
MTKTextureLoader указывать MTKTextureLoader.Option.generateMipmaps: true.2. При создании тексутры указывать что нужны мипмапы и пото генерировать блит операцией (`blit.generateMipmaps(for: texture)`).
Далее мы можем включить трилинейную интерполяцию: значение будет браться средним по ближайшим слоям мипмапа, а потом еще и между ними. В итоге получается гладенько красиво. Все, что надо, указать
.mipFilter=.linear или mip_filter::linear (смотря где вы его создаете) при создании сэмплера.Это может быть полезно для нормальной отрисовки геометрии, если вы, скажем отрисовали линию на текстуре, а потом натягиваете эту плоскость на что-то еще. Вот чтобы эту линию не попердолило, лучше генерировать мипамап пердварительно. Делается это довольно быстро на фоне всего остального, но жрет х1.5 памяти.
👍2
AntialiaingDemo.zip
99.5 KB
Демка для потыкать. Половина негенерена кодексом так что не ругайтесь
👍3
Прогаем с кенгурой
Физарум в живой природе
Можно заказать чашек петри и высадить его на них
This media is not supported in your browser
VIEW IN TELEGRAM
Помните эксперименты с тайлами на генуарий? Нашел им применение. Делаю раскраску по заявке ребёнка. Кстати и линза пригодилась
🔥6