Vector and Matrix types that are properly aligned for use in std140 uniforms.
All the types in this library have the same alignment and size as the equivilant glsl type in the default mode (std140).
This fixes the padding within members of structs but padding between members needs to be minded.
The types in padding
are there to make this easier.
Vectors are constructable to/from an array of their underlying type. Matrices are constructable
to/from both 1d and 2d arrays as well as an array of the underlying vector type. (eg. Mat2
can be
constructed from [Vec2; 2]
)
For the following glsl:
glsl
layout(set = 0, binding = 0) uniform Block {
mat4 mvp;
vec3 position;
vec3 normal;
vec2 uv;
}
This struct is rife with padding. However it's now easy to mind the padding:
```rust use shadertypes::{Vec2, Vec3, Mat4}; use shadertypes::padding::Pad2Float;
// Definition
// #[derive(zerocopy::AsBytes)] // Supports zerocopy with the zerocopy
feature
struct UniformBlock {
mvp: Mat4, // 16 align + 64 size
position: Vec3, // 16 align + 16 size
normal: Vec3, // 16 align + 16 size
uv: Vec2, // 8 align + 8 size
_padding: Pad2Float, // Struct is 16 byte aligned, so we need (the space of) 2 more floats.
}
fn generate_mvp() -> [f32; 16] { // ... }
// Construction
let block = UniformBlock {
// Anything that can be converted to a [f32; 16] or [[f32; 4]; 4] works
mvp: Mat4::from(generate_mvp()),
position: Vec3::new([0.0, 1.0, 2.0]), // from
also works
normal: Vec3::new([-2.0, 2.0, 3.0]),
uv: Vec2::new([0.0, 1.0]),
_padding: Pad2Float::new(), // default
also works
};
// Supports bytemuck with the bytemuck
feature
unsafe impl bytemuck::Zeroable for UniformBlock {}
// Safe to implement as there is no implicit padding
unsafe impl bytemuck::Pod for UniformBlock {}
let blocku8: &[u8] = bytemuck::castslice(&[block]); ```
License: MIT OR Apache-2.0 OR Zlib