Пиши шейдер один раз - запускай везде
Начну с того, что если пишешь под десктоп, то шейдеры можно писать на классическом GLSL (версии 120, 130, 330, 430 и т. д.) или на HLSL, если работаете с DirectX. А вот для веба и мобилок обычно используют GLSL ES (упрощённая версия под OpenGL ES) - например, 100 (ES 2.0), 300 (ES 3.0) и т. д. Разница между ними не огромная, но есть нюансы: В новых версиях появляются layout qualifiers, другие типы данных, чуть иной синтаксис. В GLSL ES, например, нельзя просто так взять и объявить переменную без "precision" в фрагментном шейдере и прочие нюансы.
Но иногда хочется писать на современном GLSL 450+, а потом оказывается что на телефоне или в браузере это не запустится. И приходится переписывать кучу кода под каждую платформу.
И тут начинается для большинства абсолютная магия!
В игровых движках типа Unity, Unreal, Godot и даже game maker, всё это уже решено - шейдеры автоматически адаптируются под разные платформы. Например, в Defold недавно завезли поддержку SPIRV-Cross. Говоря отдельно про саму либу, то она умеет превращать шейдеры из SPIR-V (промежуточный бинарный формат) в:
- GLSL (любой версии),
- GLSL ES (для мобилок и веба),
- HLSL (под DirectX),
- MSL (под Metal, для Apple).
SPIR-V это как универсальный байткод для шейдеров. Его можно получить, например, из GLSL с помощью glslang (официальный компилятор от Khronos) или даже из HLSL c помощью DirectXShaderCompiler (не я не проверял)
Я залип на эту тему
Помучился, почитал доки, даже брал консультацию у спецов, чтобы помогли собрать ради спорт интереса glslang + SPIRV-Cross в один бинарник настроив нужные команды лично под меня. Теперь я могу:
1. Написать шейдер на современном GLSL.
2. Скомпилить его в SPIR-V.
3. Конвертнуть в любую целевую версию - хоть под WebGL, хоть под Vulkan или DirectX.
Вот ссылки на проекты благодаря чему это возможно, там же есть собранные отдельные бинарники для быстрых тестов:
SPIRV-Cross https://github.com/KhronosGroup/SPIRV-Cross
glslang https://github.com/KhronosGroup/glslang
Начну с того, что если пишешь под десктоп, то шейдеры можно писать на классическом GLSL (версии 120, 130, 330, 430 и т. д.) или на HLSL, если работаете с DirectX. А вот для веба и мобилок обычно используют GLSL ES (упрощённая версия под OpenGL ES) - например, 100 (ES 2.0), 300 (ES 3.0) и т. д. Разница между ними не огромная, но есть нюансы: В новых версиях появляются layout qualifiers, другие типы данных, чуть иной синтаксис. В GLSL ES, например, нельзя просто так взять и объявить переменную без "precision" в фрагментном шейдере и прочие нюансы.
Но иногда хочется писать на современном GLSL 450+, а потом оказывается что на телефоне или в браузере это не запустится. И приходится переписывать кучу кода под каждую платформу.
И тут начинается для большинства абсолютная магия!
В игровых движках типа Unity, Unreal, Godot и даже game maker, всё это уже решено - шейдеры автоматически адаптируются под разные платформы. Например, в Defold недавно завезли поддержку SPIRV-Cross. Говоря отдельно про саму либу, то она умеет превращать шейдеры из SPIR-V (промежуточный бинарный формат) в:
- GLSL (любой версии),
- GLSL ES (для мобилок и веба),
- HLSL (под DirectX),
- MSL (под Metal, для Apple).
SPIR-V это как универсальный байткод для шейдеров. Его можно получить, например, из GLSL с помощью glslang (официальный компилятор от Khronos) или даже из HLSL c помощью DirectXShaderCompiler (не я не проверял)
Я залип на эту тему
Помучился, почитал доки, даже брал консультацию у спецов, чтобы помогли собрать ради спорт интереса glslang + SPIRV-Cross в один бинарник настроив нужные команды лично под меня. Теперь я могу:
1. Написать шейдер на современном GLSL.
2. Скомпилить его в SPIR-V.
3. Конвертнуть в любую целевую версию - хоть под WebGL, хоть под Vulkan или DirectX.
Вот ссылки на проекты благодаря чему это возможно, там же есть собранные отдельные бинарники для быстрых тестов:
SPIRV-Cross https://github.com/KhronosGroup/SPIRV-Cross
glslang https://github.com/KhronosGroup/glslang
❤5🔥4👍3