mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-09 13:01:49 +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
4.6 KiB
Markdown
97 lines
4.6 KiB
Markdown
# Block materials
|
|
|
|
A material is a common kit of properties applied to groups of blocks.
|
|
Material definitions are located in the `block_materials/` folder of a content pack.
|
|
A block refers to a material with the `material` property in the `pack:material_name` format
|
|
(see [block properties](block-properties.md)).
|
|
|
|
Example (`block_materials/glass.json`):
|
|
|
|
```json
|
|
{
|
|
"steps-sound": "steps/glass",
|
|
"place-sound": "blocks/glass_place",
|
|
"break-sound": "blocks/glass_break",
|
|
"sound-absorption": 0.3
|
|
}
|
|
```
|
|
|
|
## Properties
|
|
|
|
| Name | Type | Description |
|
|
|------------------|--------|----------------------------------------------------------|
|
|
| steps-sound | string | steps sound |
|
|
| place-sound | string | block placing sound |
|
|
| break-sound | string | block breaking sound |
|
|
| hit-sound | string | block hitting sound (`steps-sound` by default) |
|
|
| sound-absorption | number | ambient sounds absorption when the camera is in the block|
|
|
| shader | string | material shader name (see below) |
|
|
|
|
## Material shaders
|
|
|
|
A material shader allows to customize blocks and entities rendering without replacing the engine shaders.
|
|
Material shader code is included in the world shaders (opaque, translucent and shadows passes of blocks
|
|
and the entities program), so blocks with different materials are still rendered within a single draw call per chunk.
|
|
|
|
An entity uses the shader of its `material` property (see [entity properties](entity-properties.md)).
|
|
The material may be overridden at runtime with `rig:set_material` (see [skeleton](scripting/ecs.md)).
|
|
|
|
The `shader` property specifies the name of a shader located in the `shaders/materials/` folder of a pack.
|
|
Each of two files is optional, but an existing file must define its function:
|
|
|
|
- `shaders/materials/name.glslv` - vertex stage, must define the function:
|
|
```glsl
|
|
// position - vertex world position
|
|
vec3 material_vertex(vec3 position)
|
|
```
|
|
The function may also modify the vertex normal `a_realnormal` (world space),
|
|
for example when displacing a surface.
|
|
- `shaders/materials/name.glslf` - fragment stage, must define the function:
|
|
```glsl
|
|
// color - block texture color before lighting applied
|
|
vec4 material_fragment(vec4 color)
|
|
```
|
|
|
|
All the world shader uniforms (`u_timer`, `u_cameraPos`, `u_dayTime`, etc.),
|
|
vertex attributes (`v_position`, `v_texCoord`, `v_light`, `v_normal`) in the vertex stage and
|
|
varyings (`a_texCoord`, `a_modelpos`, `a_realnormal`, `a_skyLight`, etc.) in the fragment stage are available.
|
|
The same material shader code is compiled into all the programs (blocks, shadows and entities), so only
|
|
the common interface declared in `shaders/lib/world_vertex_header.glsl`, `world_fragment_header.glsl`
|
|
and `world_uniforms.glsl` may be used.
|
|
Shader parameters are declared with the `#param` directive, the same way as in [post-effects](scripting/builtins/libgfx-posteffects.md),
|
|
and controlled from scripts with the [gfx.materials](scripting/builtins/libgfx-materials.md) library.
|
|
|
|
Example (`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;
|
|
}
|
|
```
|
|
|
|
Materials with the same `shader` share the shader code and its params.
|
|
Hook functions and params names are made unique for every shader automatically,
|
|
so different shaders may declare the same params.
|
|
Other functions and global variables of all the material shaders are compiled
|
|
into one program, so their names must be unique (use a prefix).
|
|
|
|
> [!NOTE]
|
|
> Compilation errors refer to a material shader by its index: `3:12` means line 12
|
|
> of the shader number 3. The indices are printed to the log on content loading,
|
|
> `128` is the generated dispatch code, `0` is the engine shader.
|
|
|
|
Limitations:
|
|
|
|
- up to 127 material shaders may be loaded at the same time
|
|
- array params are not supported, params names must not start with `_`
|
|
- the same param declared in both stages must have the same type
|
|
- vertex displacement must be continuous (depend on the vertex position only),
|
|
otherwise gaps between faces appear; it must not depend on `u_cameraPos`,
|
|
because the shadows pass is rendered from the light's point of view
|
|
- `texture()` calls inside `material_fragment` have undefined derivatives
|
|
at borders between materials, use `textureLod` there
|