- 'shader' property of block materials: shaders/materials/<name>.glslv, .glslf with material_vertex / material_fragment hooks and #param uniforms - material shaders code is included into main, translucent and shadows programs through generated headers, no extra draw calls - chunk vertex normal.w byte replaced with 'flags': bit 7 - emission flag, bits 0-6 - material shader index (vertex format size is not changed) - doc/*/block-materials.md
6.9 KiB
Материалы блоков
Материал - общий набор свойств, применяемых к группам блоков.
Определения материалов расположены в папке block_materials/ контент-пака.
Блок ссылается на материал свойством material в формате пак:имя_материала
(см. свойства блоков).
Пример (block_materials/glass.json):
{
"steps-sound": "steps/glass",
"place-sound": "blocks/glass_place",
"break-sound": "blocks/glass_break",
"sound-absorption": 0.3
}
Свойства
| Имя | Тип | Описание |
|---|---|---|
| steps-sound | string | звук шагов |
| place-sound | string | звук установки блока |
| break-sound | string | звук разрушения блока |
| hit-sound | string | звук удара по блоку (по умолчанию - steps-sound) |
| sound-absorption | number | поглощение окружающих звуков, когда камера внутри блока |
| shader | string | имя шейдера материала (см. ниже) |
Шейдеры материалов
Шейдер материала позволяет настроить отрисовку блоков и сущностей без замены шейдеров движка. Код шейдера материала включается в мировые шейдеры (проходы непрозрачных, полупрозрачных блоков, теней и программу сущностей), поэтому блоки с разными материалами по-прежнему отрисовываются одним вызовом на чанк.
Сущность использует шейдер материала из своего свойства material (см. свойства сущностей).
Материал можно переопределить в рантайме через rig:set_material (см. скелет).
Свойство shader указывает имя шейдера, расположенного в папке shaders/materials/ пака.
Каждый из двух файлов опционален, но существующий файл обязан определять свою функцию:
shaders/materials/имя.glslv- вершинная стадия, должен определять функцию:
Функция также может изменять нормаль вершины// position - мировая позиция вершины vec3 material_vertex(vec3 position)a_realnormal(мировые координаты), например, при смещении поверхности.shaders/materials/имя.glslf- фрагментная стадия, должен определять функцию:// color - цвет текстуры блока до применения освещения vec4 material_fragment(vec4 color)
Доступны все uniform-переменные мировых шейдеров (u_timer, u_cameraPos, u_dayTime и т.д.),
атрибуты вершин (v_position, v_texCoord, v_light, v_normal) в вершинной стадии и
varying-переменные (a_texCoord, a_modelpos, a_realnormal, a_skyLight и т.д.) во фрагментной.
Один и тот же код материала компилируется во все программы (блоки, тени и сущности), поэтому можно
использовать только общий интерфейс, объявленный в shaders/lib/world_vertex_header.glsl,
world_fragment_header.glsl и world_uniforms.glsl.
Параметры шейдера объявляются директивой #param, так же, как в пост-эффектах,
и управляются из скриптов библиотекой gfx.materials.
Пример (shaders/materials/leaves.glslv):
#param float p_amplitude = 0.03
#param float p_speed = 1.2
vec3 material_vertex(vec3 position) {
float phase = position.x * 0.7 + position.z * 1.1 + position.y * 0.4;
position.x += sin(u_timer * p_speed + phase) * p_amplitude;
return position;
}
Материалы с одинаковым shader используют общий код шейдера и его параметры.
Имена функций-хуков и параметров автоматически делаются уникальными для каждого шейдера,
поэтому разные шейдеры могут объявлять одинаковые параметры.
Остальные функции и глобальные переменные всех шейдеров материалов компилируются
в одну программу, поэтому их имена должны быть уникальными (используйте префикс).
Note
Ошибки компиляции ссылаются на шейдер материала по его номеру:
3:12означает строку 12 шейдера номер 3. Номера печатаются в лог при загрузке контента,128это сгенерированный код диспетчера,0шейдер движка.
Ограничения:
- одновременно может быть загружено до 127 шейдеров материалов
- параметры-массивы не поддерживаются, имена параметров не могут начинаться с
_ - один и тот же параметр в обеих стадиях должен иметь одинаковый тип
- смещение вершин должно быть непрерывным (зависеть только от позиции вершины),
иначе между гранями появляются щели; оно не должно зависеть от
u_cameraPos, так как проход теней рисуется с точки зрения источника света - у вызовов
texture()внутриmaterial_fragmentне определены производные на границах материалов, используйте тамtextureLod