Quick answer: SPIR-V Cross-translated shader producing wrong values for vec3 in uniform buffer? std140 pads vec3 to 16 bytes; std430 packs to 12 - declare the buffer layout explicitly.

Vec3 field in a uniform buffer reads as (0, 0, x_value) on translated GLSL.

Use std140 universally

layout(std140, binding=0) uniform Foo {
  vec3 bar;
}

std140 is the more conservative; portable across translators.

Or pad vec3 to vec4

Use vec4 in the buffer; ignore the w component. Eliminates the layout ambiguity.

Validate with spirv-cross dump

Dump the translated GLSL; inspect offsets. Mismatch with your CPU-side struct = bug.

“Buffer layout has multiple rules. Mixing rules across translation = silent data corruption.”

Standardize on std140 across the project. The 4-byte padding is cheap; the bug class is expensive.

Related reading