mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-04 18:41:51 +00:00
- '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
97 lines
6.9 KiB
Markdown
97 lines
6.9 KiB
Markdown
# Материалы блоков
|
||
|
||
Материал - общий набор свойств, применяемых к группам блоков.
|
||
Определения материалов расположены в папке `block_materials/` контент-пака.
|
||
Блок ссылается на материал свойством `material` в формате `пак:имя_материала`
|
||
(см. [свойства блоков](block-properties.md)).
|
||
|
||
Пример (`block_materials/glass.json`):
|
||
|
||
```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` (см. [свойства сущностей](entity-properties.md)).
|
||
Материал можно переопределить в рантайме через `rig:set_material` (см. [скелет](scripting/ecs.md)).
|
||
|
||
Свойство `shader` указывает имя шейдера, расположенного в папке `shaders/materials/` пака.
|
||
Каждый из двух файлов опционален, но существующий файл обязан определять свою функцию:
|
||
|
||
- `shaders/materials/имя.glslv` - вершинная стадия, должен определять функцию:
|
||
```glsl
|
||
// position - мировая позиция вершины
|
||
vec3 material_vertex(vec3 position)
|
||
```
|
||
Функция также может изменять нормаль вершины `a_realnormal` (мировые координаты),
|
||
например, при смещении поверхности.
|
||
- `shaders/materials/имя.glslf` - фрагментная стадия, должен определять функцию:
|
||
```glsl
|
||
// 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`, так же, как в [пост-эффектах](scripting/builtins/libgfx-posteffects.md),
|
||
и управляются из скриптов библиотекой [gfx.materials](scripting/builtins/libgfx-materials.md).
|
||
|
||
Пример (`shaders/materials/leaves.glslv`):
|
||
|
||
```glsl
|
||
#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`
|