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 coreand#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 ofogl46/are one table for all the shaders (a name has the same location everywhere), seeogl46/common.glsl. - The settings of the game (
SHADOWMAP_ENABLED,ENVMAP_ENABLED,MOTIONBLUR_ENABLED,POSTFX_ENABLED,EXTRAEFFECTS_ENABLED,OUTPUT_GAMMA) areconst bool(specialization constants in the binaries,ogl46/settings.glsl): use them inif, not in#if. - The constants of the game (bindings, sizes) are written in
ogl46/common.glslandvk14/common.glslfor 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 inci_shadervalidatorchecks them too).