Shader Architecture

37.1 Includes & modules

GLSL has no native module system. Options:

String concatenation / custom #include resolver in your engine.

GL_GOOGLE_include_directive with glslang/glslc (#include "lighting.glsl").

GL_ARB_shading_language_include (named strings in OpenGL).

glslify for web projects.

Organize shared code: common.glsl (constants, math), brdf.glsl, noise.glsl, shadows.glsl, tonemap.glsl.

37.2 Shader variants & permutations

Features combine multiplicatively (shadows × normal maps × skinning × fog...). Strategies:

Compile variants with #define sets (keep the count manageable; cache binaries with glGetProgramBinary / Vulkan pipeline caches).

Uber-shaders with uniform branches for rarely-changing features.

Vulkan specialization constants.

Material graphs that generate GLSL (Unreal-style node editors, Godot visual shaders, Blender nodes).

37.3 Cross-compilation

glslang / shaderc GLSL (and HLSL) → SPIR-V SPIR-V → GLSL, GLSL ES, HLSL, MSL (Metal), reflection data naga (wgpu) WGSL/GLSL/SPIR-V ↔ each other Tint (Dawn) HLSL → DXIL / SPIR-V modern shading language (modules, generics) targeting SPIR-V, HLSL, GLSL, Metal, CUDA, WGSL

bgfx shaderc, Unity HLSLcc, MoltenVK engine/platform pipelines

Shader reflection (SPIRV-Reflect, SPIRV-Cross) extracts bindings and uniform layouts automatically for your renderer.

37.4 GLSL in engines & tools

Godot: Godot shading language (GLSL-like) with shader_type spatial;, ALBEDO, NORMAL_MAP built-ins.

Unity: HLSL/ShaderLab, cross-compiled to GLSL for OpenGL/Vulkan targets.

Unreal: HLSL + material graph.

Blender: GLSL for EEVEE and OpenGL viewport add-ons.

TouchDesigner, openFrameworks, Processing, Cinder, Bonzomatic (live coding), ISF (Interactive Shader Format for VJ software).

🧪 Part III Exercises

Write a geometry shader that draws vertex normals as lines; another that renders a wireframe overlay with barycentric coordinates.

Tessellate a flat grid with distance-based LOD and displace it with a height map to form terrain.

Implement a compute-shader Gaussian blur using shared memory tiles; compare with the fragment-shader version.

Build a GPU particle system: SSBO storage, compute update with curl noise, instanced rendering, atomic emission counter.

Implement PBR with Cook–Torrance and IBL (irradiance map, prefiltered map, BRDF LUT) on a grid of spheres varying roughness and metallic.

Convert your forward renderer to deferred shading with a G-buffer and 100+ point lights; add SSAO.

Write a Shadertoy ray marcher with at least four SDF primitives, smooth blending, soft shadows, AO, and fog.

Port your vertex/fragment shaders to Vulkan GLSL with descriptor sets, push constants, and a specialization constant; compile with glslc.

Use subgroup operations to speed up a compute-shader reduction; compare with the shared-memory version.

Capture a frame in RenderDoc, find the most expensive draw, and step through one pixel's fragment shader.