My "wildest" diff yet
Right on, so naturally I've kept working on my renderer, and I've always wanted to make a blog entry about the development process, because it's something that I find interesting, it'd be interesting to look back on it in the future to see how I've progressed since, and hell, maybe it can help someone in a similar place. However, I never wrote anything, because I couldn't be bothered really, until now.
Recently I started work on moving my texture/sampler handling system to a descriptor indexing based system, which would make working with textures in the future a LOT easier, and while working on the system (which is still incomplete as of 09/04/2026, because while it technically works, I still need to finish setting everything up so I don't have to worry about it in the future), I realised that my shader compilation script was absolute fucking garbage, and I should get on with fixing it. This is how it looked like:
glslc main_pass/skybox.frag -o compiled/skybox.frag.spv
glslc main_pass/skybox.vert -o compiled/skybox.vert.spv
glslc main_pass/point_light.frag -o compiled/point_light.frag.spv
glslc main_pass/point_light.vert -o compiled/point_light.vert.spv
glslc main_pass/simple_shader.frag -o compiled/simple_shader.frag.spv
glslc main_pass/simple_shader.vert -o compiled/simple_shader.vert.spv
glslc lighting/shadowmap.frag -o compiled/shadowmap.frag.spv
glslc lighting/shadowmap.vert -o compiled/shadowmap.vert.spv
glslc buffers/normal_spec.vert -o compiled/normal_spec.vert.spv
glslc buffers/normal_spec.frag -o compiled/normal_spec.frag.spv
glslc buffers/depth.vert -o compiled/depth.vert.spv
glslc buffers/depth.frag -o compiled/depth.frag.spv
glslc post_effects/AO.vert -o compiled/AO.vert.spv
glslc post_effects/AO.frag -o compiled/AO.frag.spv
glslc testing/bindless_test.vert -o compiled/bindless_test.vert.spv
glslc testing/bindless_test.frag -o compiled/bindless_test.frag.spv
Pretty bad, right? There are one too many problems plainly visible. For one, I always compile everything, disregarding the possibility that I may not need to compile some shader code, which is most of the time, so compilation times are needlessly long (especially on my laptop), and unnecessarily so. The next problem that is plainly visible is that if I ever want to compile a new shader with the same script, I have to go in and manually add it, which is annoying. If the compiled/ directory doesn't exist, it also won't compile. Generally it's an awful script that was never meant to be more than a placeholder.
So, why did I decide to make a new script? For the first listed reason, I was getting tired of the longer-than-necessary compilation times, so I started work on a very dirty solution to my problem, and started manually adding all the file paths onto an array that I would then cycle through, comparing the dates of when they were last modified, and then compiling as needed. This was still pretty bad, and because it was taking me so long to fill the array manually I thought: "Why don't I just do it properly right away?", and so I did.
And now, the git diff as seen on github:
Yeah, nothing alike, this new script now searches for any files in any of the directories within shaders/, checks if compilation is needed, and then if it is needed it'll say which file was compiled, and will place the compiled spir-v file within the compiled/ directory.
Here is the latest version of the script, as I have tweaked it a bit since that first commit:
cd ./shaders/
[ ! -d ./compiled ] && mkdir ./compiled
shaderfiles=()
while IFS= read -r line; do
if [[ "${line:0:8}" != "compiled" ]]; then
shaderfiles+=("$line")
fi
done < <(rg --files)
IFS='/'
for val in "${shaderfiles[@]}"; do
read -ra isolated <<<"$val"
comp="compiled/"${isolated[1]}".spv"
if [ ! -f "$comp" ] || [[ $(date -r "$val" +%s) > $(date -r "$comp" +%s) ]]; then
glslc "$val" -o "$comp"
echo "compiled "$val""
fi
done
cd ..
So in its current iteration the shader compilation script will now place itself within the shaders directory (it as to be ran on VulkanLearnin_greal1/, which is where one also runs make and build/final_program), check if the compiled/ directory exists (if it doesn't, it'll make it), will read the files with ripgrep (not a standard package, but it's still a script made to be used by me, and if anyone else wants to compile my engine then they are free to install ripgrep themselves), and will then go through all the files that are not in compiled/ and will then contrast them with their compiled equivalents (if they exist). A massive improvement, and while it's nice while working from my desktop, it's even nicer while working from my laptop, where I feel the speedup from not needlessly compiling shaders much, much more.
Now with this out of the way for the foreseeable future, back I go to working on properly finalising descriptor indexing, and after that I'll add compute shading capabilities to my pipelines, so it's a good thing that I got this out the way now. Hopefully by the time I decide to write again I'll be talking about compute shading or abstractions for my swapchain class that will allow me to more easily create frame buffers from a rendering pipeline, because as it is now I'm not efficiently reusing code, but it's on the list.
Enjoy your day!