ワンクリックで
wgsl-uniform-vec3-alignment
vec3<T> in WGSL uniform address space inherits vec4 alignment (16 bytes). When padding Rust
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
vec3<T> in WGSL uniform address space inherits vec4 alignment (16 bytes). When padding Rust
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Use when working on 3D-specific rendering — deferred chain, G-buffer, clustered shading, Stratum GI, ReGIR, SVGF/A-SVGF, TAA, shadow techniques, depth/HZB, anything 3D-specific. ALWAYS load titan-rendering-core first; this skill assumes core conventions. Loads Titan-specific overrides for realtime-rendering. NOT for 2D rendering or editor panels.
Use when diagnosing a Titan renderer artifact — flicker, ghosting, fireflies, banding, light leaks, seams, boil, NaN/Inf, aliasing, smear/trails, dark voids, shadow artifacts, GI instability, denoiser/TAA issues. The frame-isolation-first debugging method: capture 60Hz, diff frames / A-B vs classical, consult literature, isolate via systematic-debugging, propose (and prove) a fix, record empirically. NOT for landing the production fix (hand to titan-rendering-3d-agent), 2D rendering, or editor panels.
Use when working in titan-rendering-frame-graph, titan-rendering-core, or titan-rendering-post-process-core — frame graph DAG, RenderTarget, DevicePool, PostProcessHook, CameraFrameData, HDR intermediate, tonemap, color management. Foundational layer shared between current 3D and future 2D rendering. Loads Titan-specific overrides for realtime-rendering. NOT for 3D-specific concerns (deferred chain, GI, shadows) — load titan-rendering-3d after this.
When a Titan bench tool using Renderer3d lacks on_resize → renderer.resize(), depth_prepass_view and HZB occlusion resources are never created — DepthPrepass, HzbBuild, and SceneCull passes silently skip, and taps produce no output
When adding a camera UBO shared between Rust and WGSL, verify field-by-field that the CPU layout matches the WGSL struct — especially packed vec4 fields where reordering silently breaks the shader
When building a depth prepass for reverse-Z HZB occlusion culling, use Greater compare (not Always) — the closest fragment must win so the HZB stores the nearest occluding surface, not the farthest
| name | wgsl-uniform-vec3-alignment |
| description | vec3<T> in WGSL uniform address space inherits vec4 alignment (16 bytes). When padding Rust |
| source | auto-skill |
| extracted_at | 2026-06-15T20:25:00.000Z |
In WGSL's uniform address space, vec3<T> inherits the alignment of
vec4<T> (16 bytes). This means a WGSL struct like:
struct Params {
a: u32,
b: u32,
c: u32,
d: u32,
e: u32,
_pad: vec3u, // WRONG — 16-byte aligned, offset padded to 32
}
...can be 48 bytes on the GPU (wgpu/naga may insert 12 bytes of padding
before _pad to satisfy the 16-byte alignment) while the matching Rust
struct is 32 bytes. This causes bind-group validation failures on backends
that enforce uniform layout rules, or silent data corruption if validation
doesn't catch the size mismatch.
Why: WGSL § alignment rules: vec3 alignment = vec4 alignment =
16 bytes in uniform address space. The Rust #[repr(C)] struct has field
alignment = 4 bytes (the element alignment of [u32; 3] = 4). The two
layouts diverge.
Correct fix:
_pad: array<u32, 3>, // CORRECT — element alignment = 4, matches Rust
array<u32, 3> has the same element alignment as the Rust [u32; 3] (4
bytes), so the structs match exactly. The array carries the same 12 bytes
of data; only the alignment rule differs.
When to use vecNu at all: vec4u is safe because the alignment
is the same as array<u32, 4> (both 16 bytes). vec2u alignment is
8 bytes = array<u32, 2> alignment (both 8 bytes). Only vec3 has
this alignment-divergence property.
Verification: If a bind-group creation fails with a size-mismatch
error on a UBO (uniform buffer), check all vec3 fields in the WGSL
struct. Replace with array<T, 3>.
Affected code in Titan: vsm_allocate.wgsl VsmAllocateParams._pad
was fixed from vec3u to array<u32, 3> in commit 689b4fb8 after
the code review caught the latent mismatch.