voxelcore/doc/ru/block-materials.md
lookibed 81489a13cf add block material shaders
- '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
2026-10-02 06:33:01 +03:00

6.9 KiB
Raw Blame History

Материалы блоков

Материал - общий набор свойств, применяемых к группам блоков. Определения материалов расположены в папке 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