This translation is community contributed and may not be up to date. We only maintain the English version of the documentation. Read this manual in English
Материалы используются для выражения того, как графический компонент (спрайт, тайловая карта, шрифт, GUI-нода, модель и т.д.) должны быть отрендерены.
Метариал содержит теги, информацию, которая применяется конвейером рендеринга для отбора объектов для рендера. Также он содержит ссылку на шейдерные программы, которые компилируются через доступные графические драйверы и загружаются на графическое аппаратное обеспечение и запускаются в каждом кадре, когда компонент рендерится.
Чтобы создать материал, кликните правой кнопкой мыши по нужной папке в обозревателе Assets и выберите New... ▸ Material. (Вы также можете выбрать File ▸ New... в меню, а затем выбрать Material). Укажите имя нового файла материала и нажмите Ok.
Новый материал откроется в Material Editor.
Файл материала содержит следующую информацию:
render.enable_material()
. Имя должно быть уникальным.render.predicate()
для выбора компонентов, которые нужно отрисовать вместе. Подробнее см. Документацию по рендеру. Максимальное количество тегов в проекте — 32.Атрибуты шейдера (также называемые потоками вершин или вершинными атрибутами) — это механизм, с помощью которого GPU получает вершины из памяти для рендеринга геометрии. Вершинный шейдер задает набор потоков через ключевое слово attribute
, и в большинстве случаев Defold автоматически создает и привязывает эти данные на основе имени потока. Однако в некоторых случаях вы можете захотеть передавать больше данных на вершину для реализации специфических эффектов, которые движок по умолчанию не предоставляет. Атрибут вершины можно настроить с помощью следующих полей:
SEMANTIC_TYPE_COLOR
отобразит виджет выбора цвета, хотя данные по-прежнему передаются как есть из движка в шейдер.
SEMANTIC_TYPE_NONE
— значение по умолчанию, просто передает данные в буфер вершинSEMANTIC_TYPE_POSITION
— координаты вершины; можно использовать вместе с пространством координатSEMANTIC_TYPE_TEXCOORD
— текстурные координатыSEMANTIC_TYPE_PAGE_INDEX
— индекс страницыSEMANTIC_TYPE_COLOR
— вызывает отображение цветового виджета в инспектореSEMANTIC_TYPE_NORMAL
— нормаль вершиныSEMANTIC_TYPE_TANGENT
— касательная вершиныSEMANTIC_TYPE_WORLD_MATRIX
— мировая матрица вершиныSEMANTIC_TYPE_NORMAL_MATRIX
— матрица нормалей вершиныTYPE_BYTE
— знаковый 8-битный байтTYPE_UNSIGNED_BYTE
— беззнаковый 8-битный байтTYPE_SHORT
— знаковое 16-битное значениеTYPE_UNSIGNED_SHORT
— беззнаковое 16-битное значениеTYPE_INT
— знаковое целое числоTYPE_UNSIGNED_INT
— беззнаковое целое числоTYPE_FLOAT
— число с плавающей точкой (по умолчанию)VECTOR_TYPE_SCALAR
— скалярVECTOR_TYPE_VEC2
— вектор из 2 элементовVECTOR_TYPE_VEC3
— вектор из 3 элементовVECTOR_TYPE_VEC4
— вектор из 4 элементов (по умолчанию)VECTOR_TYPE_MAT2
— матрица 2x2VECTOR_TYPE_MAT3
— матрица 3x3VECTOR_TYPE_MAT4
— матрица 4x4Vertex
— один раз на вершину (по умолчанию)Instance
— один раз на экземпляр, например для мировых матрицposition
, texcoord
и др.) это значение игнорируется.Переопределение конфигурации атрибутов позволяет уменьшить объем данных и снизить нагрузку на память CPU и GPU.
Система материалов автоматически присваивает семантику атрибутам по их именам во время исполнения:
position
- semantic type: SEMANTIC_TYPE_POSITION
texcoord0
- semantic type: SEMANTIC_TYPE_TEXCOORD
texcoord1
- semantic type: SEMANTIC_TYPE_TEXCOORD
page_index
- semantic type: SEMANTIC_TYPE_PAGE_INDEX
color
- semantic type: SEMANTIC_TYPE_COLOR
normal
- semantic type: SEMANTIC_TYPE_NORMAL
tangent
- semantic type: SEMANTIC_TYPE_TANGENT
mtx_world
- semantic type: SEMANTIC_TYPE_WORLD_MATRIX
mtx_normal
- semantic type: SEMANTIC_TYPE_NORMAL_MATRIX
Если вы указываете эти атрибуты в редакторе материалов, их поведение будет определяться вашей конфигурацией.
Как и в случае с пользовательскими шейдерными константами, вы можете изменять значения вершинных атрибутов во время исполнения через go.get
, go.set
и go.animate
:
go.set("#sprite", "tint", vmath.vector4(1,0,0,1))
go.animate("#sprite", "tint", go.PLAYBACK_LOOP_PINGPONG, vmath.vector4(1,0,0,1), go.EASING_LINEAR, 2)
Однако при обновлении вершинных атрибутов есть особенности: возможность использовать новое значение зависит от семантики атрибута. Например, компонент спрайта поддерживает SEMANTIC_TYPE_POSITION
, и если вы попытаетесь переопределить атрибут с этой семантикой, то компонент проигнорирует новое значение, поскольку семантика требует, чтобы данные всегда исходили от позиции спрайта.
Изменение пользовательских вершинных атрибутов во время исполнения в настоящее время поддерживается только для компонентов типа спрайт.
Инстансинг — это техника, используемая для эффективной отрисовки множества копий одного и того же объекта на сцене. Вместо создания отдельной копии объекта каждый раз, инстансинг позволяет движку использовать одну модель и переиспользовать её многократно. Например, в игре с большим лесом вместо того, чтобы создавать отдельную модель дерева для каждого дерева, можно создать одну модель и размещать её сотни или тысячи раз с разными позициями и масштабом. Таким образом, весь лес может быть отрисован одним вызовом отрисовки, а не отдельными вызовами для каждого дерева.
Инстансинг на данный момент доступен только для компонентов типа Model.
Инстансинг включается автоматически, если соблюдены необходимые условия. Defold активно использует пакетирование состояния отрисовки — чтобы инстансинг работал, необходимо соблюдение следующих требований:
render.enable_material()
Чтобы указать, что атрибут должен повторяться на каждый экземпляр, установите для него Step function = Instance
. Это делается автоматически для некоторых семантик по имени (см. таблицу Семантика атрибутов по умолчанию
), но также может быть установлено вручную в редакторе материалов.
Простой пример: сцена с четырьмя игровыми объектами, у каждого из которых есть компонент-модель:
Материал настроен с одним пользовательским атрибутом, повторяющимся на каждый экземпляр:
Вершинный шейдер использует несколько атрибутов, повторяющихся на каждый экземпляр:
// Атрибуты на вершину
attribute highp vec4 position;
attribute mediump vec2 texcoord0;
attribute mediump vec3 normal;
// Атрибуты на экземпляр
attribute mediump mat4 mtx_world;
attribute mediump mat4 mtx_normal;
attribute mediump vec4 instance_color;
Обратите внимание, что mtx_world
и mtx_normal
по умолчанию будут использовать Step function = Instance
. Это можно изменить в редакторе материалов, добавив соответствующие записи и установив Step function = Vertex
, чтобы атрибут повторялся на вершину.
Чтобы убедиться, что инстансинг работает, можно воспользоваться веб-профайлером. В приведённом примере, так как единственное различие между экземплярами куба — это атрибуты на экземпляр, отрисовка осуществляется одним вызовом:
Для использования инстансинга на графических адаптерах с OpenGL требуется как минимум OpenGL 3.1 (на десктопе) или OpenGL ES 3.0 (на мобильных устройствах). Это означает, что на очень старых устройствах с OpenGL ES2 или более старыми версиями инстансинг может быть недоступен. В таком случае отрисовка всё равно будет работать по умолчанию, без дополнительных действий со стороны разработчика, но производительность будет ниже. В настоящее время нет способа определить, поддерживается ли инстансинг, но в будущем планируется добавить такую возможность — чтобы можно было, например, использовать более дешёвый материал или полностью отключить элементы вроде листвы, которые обычно отрисовываются с использованием инстансинга.
Шейдерные константы или “uniform”-ы — это значения, которые передаются из движка в вершинные или фрагментные программы шейдеров. Для использования константы вы задаете ее в файле материала либо через свойство Vertex Constant либо через свойство Fragment Constant. Соответствующие uniform
переменные должны быть определены в программе шейдера. Следующие константы могут быть установлены в материале:
CONSTANT_TYPE_WORLDVIEWPROJ
Пример:
go.set("#sprite", "tint", vmath.vector4(1,0,0,1))
go.animate("#sprite", "tint", go.PLAYBACK_LOOP_PINGPONG, vmath.vector4(1,0,0,1), go.EASING_LINEAR, 2)
Пример:
go.set("#sprite", "m", vmath.matrix4())
Чтобы константа CONSTANT_TYPE_USER
или CONSTANT_TYPE_MATRIX4
была доступна через go.get()
и go.set()
, она должна использоваться в шейдере. Если она определена в материале, но не используется, она будет удалена и станет недоступной в рантайме.
Сэмплеры используются для отбора цветовой информации из текстуры (тайловый источник или атлас). Цветовая информация может далее быть использована для вычислений в программе шейдера.
Компоненты типа спрайт, тайловая карта, GUI или эффект частиц автоматически получают набор sampler2D
. Первый объявленный sampler2D
в программе шейдера автоматически привязывается к изображению, на которое ссылается графический компонент. Поэтому сейчас нет необходимости указывать какие-либо сэмплеры в файле материалов для этих компонентов. Более того, эти типы компонентов сейчас поддерживают только одну текстуру. (Если вам нужно множество текстур в шейдере, вы можете использовать вызов render.enable_texture()
и устанавливать текстурные сэмплеры вручную из своего рендер скрипта.)
-- mysprite.fp
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D MY_SAMPLER;
void main()
{
gl_FragColor = texture2D(MY_SAMPLER, var_texcoord0.xy);
}
Вы можете задать настройки сэмплера для компонента добавив сэмплер по имени в файле материалов. Если вы не устанавливаете свой сэмплер в файле материалов, будут использованы глобальные настройки graphics проекта.
Для компонентов типа модель, вам необходимо задать ваши сэмплеры в файле материала с теми настройками, которые вы хотите. Далее после этих действий редактор позволит вам выставить текстуры для любого модельного компонента, который использует этот материал:
-- mymodel.fp
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D TEXTURE_1;
uniform lowp sampler2D TEXTURE_2;
void main()
{
lowp vec4 color1 = texture2D(TEXTURE_1, var_texcoord0.xy);
lowp vec4 color2 = texture2D(TEXTURE_2, var_texcoord0.xy);
gl_FragColor = color1 * color2;
}
sampler2D
переменной.WRAP_MODE_REPEAT
– повторит данные текстуры вне диапазона [0,1].WRAP_MODE_MIRRORED_REPEAT
– повторит данные текстуры вне диапазона [0,1], но каждое второе повторение будет зеркально отражено.WRAP_MODE_CLAMP_TO_EDGE
— будет приводить данные текстуры со значениями больше 1.0 к значению 1.0, а любые значения меньше 0.0 будут приводиться к значению 0.0 — то есть крайние пиксели будут повторяться до края.Default
— использует параметр фильтрации по умолчанию, указанный в файле game.project
в секции Graphics
, как Default Texture Min Filter
и Default Texture Mag Filter
.FILTER_MODE_NEAREST
– использует тексель с координатами ближайшими к центру пикселя.FILTER_MODE_LINEAR
– устанавливает взвешенное линейное среднее для массива текселей 2x2, которые лежат ближе всего к центру пикселя .FILTER_MODE_NEAREST_MIPMAP_NEAREST
– выбирает ближайшее значение текселя в отдельной MIP-карте.FILTER_MODE_NEAREST_MIPMAP_LINEAR
– выбирает ближайший тексель из двух ближайших лучших вариантов MIP-карт и затем линейно интерполирует между этими двумя значениями.FILTER_MODE_LINEAR_MIPMAP_NEAREST
– линейное интерполирование в пределах отдельной MIP-карты.FILTER_MODE_LINEAR_MIPMAP_LINEAR
– использует линейную интерполяцию для вычисления значения на каждой из двух карт, а затем выполняет линейную интерполяцию между этими двумя значениями.Когда конвейер рендеринга отрисовывает, он берет значения констант из буфера по-умолчанию — системного буфера констант. Вы можете создать собственный буфер констант, чтобы перекрыть константы по-умолчанию и вместо этого выставить uniform-ы для программы шейдера программно в рендер скрипте:
self.constants = render.constant_buffer() -- <1>
self.constants.tint = vmath.vector4(1, 0, 0, 1) -- <2>
...
render.draw(self.my_pred, self.constants) -- <3>
tint
в ярко-красныйУчтите, что элементы констант буфера ссылаются как обычная Lua таблица, но вы не можете итерироваться по буферу с помощью вызовов pairs()
или ipairs()
.
Did you spot an error or do you have a suggestion? Please let us know on GitHub!
GITHUB