// GraphicsUniforms — the shared per-frame UBO (binding 0). single source, spliced into shaders // by the crGraphics include preprocessor. the CPU mirror lives in crGraphicsUniforms.h // and must match this layout. // explicit highp — block member precisions must match across stages (WebGL2 enforces this) layout(std140) uniform GraphicsUniforms { highp mat4 u_viewProjection; highp mat4 u_lightVP[3]; // frustum-fitted shadow cascades, near to far highp vec3 u_cameraPos; highp vec3 u_lightDir; highp vec4 u_lightColor; // rgb = color (linear, pre-converted on upload), a = intensity highp vec4 u_ambientSky; // rgb = color (linear), a = strength — hemisphere, +Y normals highp vec4 u_ambientGround; // rgb = color (linear), a = strength — hemisphere, -Y normals highp vec4 u_specParams; // x = shininess, y = strength highp vec4 u_shadowParams; // x = bias (world meters), y = strength, z = normal offset (shadow texels), w = darkness highp vec4 u_shadowCascadeParams[3]; // per cascade, precomputed on upload: x = texel world size, y = bias (depth01), zw = texel uv size highp vec4 u_fogColor; // rgb = color (linear, pre-converted on upload), a = enabled (0/1) highp vec4 u_fogParams; // x = start, y = end (view-space meters) highp vec4 u_timeParams; // x = sim time (pauses with the sim), y = real time (always flows) — seconds, both wrap at 600 };