17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-29 17:27:30 +01:00
Files
maszyna/shaders/README.md

44 lines
2.9 KiB
Markdown

# Shaders
| Directory | What is in it |
|---|---|
| `ogl46/` | GLSL sources of the OpenGL 4.6 renderer |
| `ogl46bin/` | SPIR-V binaries of `ogl46/` (optional, made by `compile_spirv.py`) |
| `vk14/` | GLSL sources of the Vulkan 1.4 renderer |
| `vk14bin/` | SPIR-V binaries of `vk14/` (optional, made by `compile_spirv.py`) |
The renderers load the binary of a shader first, when there is one and it was compiled from the sources that are there now
(`manifest.txt` of the directory of the binaries lists the sources of each binary with their hashes). Otherwise the source is
compiled: by the OpenGL driver for `ogl46/`, by glslang inside the simulator for `vk14/` (with a cache of the results in the
directory of the user). `gfx.shaders.binaries no` in `eu07.ini` makes them always use the sources. The sources are needed
even with the binaries: the directives of the materials (`#pragma texture`, `#pragma param`) are read from them.
## Compiling to SPIR-V
python shaders/compile_spirv.py
compiles every shader of `ogl46/` (with the variant `MODEL_DRAWS` of the vertex and fragment shaders) and of `vk14/` with
`glslc` (Vulkan SDK, `VULKAN_SDK`, or `--glslc <path>`). A single file compiles the same way by hand:
glslc --target-env=opengl4.5 ogl46/mat_default.frag -o ogl46bin/mat_default.frag.spv
glslc --target-env=opengl4.5 -DMODEL_DRAWS=1 ogl46/vertex.vert -o ogl46bin/vertex.vert.MODEL_DRAWS.spv
glslc --target-env=vulkan1.4 vk14/imgui.frag -o vk14bin/imgui.frag.spv
A binary made by hand isn't in the manifest, so it is taken without being compared with its source. After a change of a
source, compile the binaries again (or delete them): a binary older than its source is not used, and the log says so.
## Writing shaders
* Every stage file starts with `#version 460 core` and `#define STAGE_VERTEX 1` (`STAGE_FRAGMENT`, `STAGE_GEOMETRY`,
`STAGE_COMPUTE`); files included by others (`.glsl`) don't.
* Includes: `#include "file.glsl"`, relative to the directory of the file.
* Every input and output between the stages has an explicit `layout(location = N)`, every sampler, image and block an explicit
binding, every loose uniform an explicit location: SPIR-V has no names to link by. The locations of the inputs and outputs
of `ogl46/` are one table for all the shaders (a name has the same location everywhere), see `ogl46/common.glsl`.
* The settings of the game (`SHADOWMAP_ENABLED`, `ENVMAP_ENABLED`, `MOTIONBLUR_ENABLED`, `POSTFX_ENABLED`,
`EXTRAEFFECTS_ENABLED`, `OUTPUT_GAMMA`) are `const bool` (specialization constants in the binaries, `ogl46/settings.glsl`):
use them in `if`, not in `#if`.
* The constants of the game (bindings, sizes) are written in `ogl46/common.glsl` and `vk14/common.glsl` for the binaries; the
game puts its own values before the sources and checks at the start that the files have the same ones (the shader
validator in `ci_shadervalidator` checks them too).