diff options
| author | Irene Knapp <ireneista@irenes.space> | 2026-07-13 13:25:16 -0700 |
|---|---|---|
| committer | Irene Knapp <ireneista@irenes.space> | 2026-07-15 22:35:16 -0700 |
| commit | 5dddb64f6a2fd072f2a26d4400f9a2a84386dc4e (patch) | |
| tree | db4e3b75cb5230f97f068b5e9455856cecba8807 /shaders/shader.vert | |
| parent | ec66f7419f2155d1b4bd852fdc3da87646d865c0 (diff) | |
it spins!!!!
ahem. more formally: provide animated uniforms to the shader, and use them the tutorial just wants us to do three matrices, and to defer all the actual math to a library it recommends. that would certainly be simpler. anyway, we use quaterion+offset for everything but the projection frustum, and do all the math ourselves Change-Id: I399f432bebb1e7ca4d4342efa1d5aaf37b32f427 Force-Push: yes
Diffstat (limited to 'shaders/shader.vert')
| -rw-r--r-- | shaders/shader.vert | 86 |
1 files changed, 85 insertions, 1 deletions
diff --git a/shaders/shader.vert b/shaders/shader.vert index d53ef0a..ff1698d 100644 --- a/shaders/shader.vert +++ b/shaders/shader.vert @@ -1,7 +1,22 @@ #version 460 +struct Transformation { + vec4 rotation; + vec3 translation; +}; + +// layout(binding = 0) uniform vec3 only_transform; + +layout(binding = 0) uniform UniformBlock { + vec3 scale; + Transformation model; + Transformation view; + mat4 projection; +} uniform_block; + layout(location = 0) in vec2 inPosition; layout(location = 1) in vec3 inColor; + layout(location = 0) out vec3 vertexColor; vec2 triangle[3] = vec2[]( @@ -16,8 +31,77 @@ vec3 colors[3] = vec3[]( vec3(0.0, 0.0, 1.0) ); + +// ///////////////// +// // Quaternions // +// ///////////////// +// +// To mathematicians, the components of a quaternion are traditionally +// multiplied by 1, i, j, and k, where 1 is a real number and i, j, and k are +// unit values along the three imaginary axes. GLSL doesn't give us component +// names that map cleanly onto these, and xyzw are confusing in this context +// because it's unclear whether x or w is the real-valued component, so we +// reference the components by numeric index. Yes, that sucks, but everything +// else sucks worse. +// +// That is: 0 is the real value and 1, 2, and 3 are the i, j, and k values. +// +// When reading code samples elsewhere, keep in mind that this is not the +// only possible choice. Checking how components are labeled should be the +// very first thing you do in understanding any quaternion arithmetic, +// anywhere. Also keep in mind that there are many equivalent ways to write +// any algebraic expression, and check carefully whether things are identical +// in meaning. +// +// This same challenge arises with matrices, it's just that the designers +// of GLSL have chosen to encapsulate that complexity inside the language. + +// This is kept carefully the same as quaternion_conjugate() in +// linear_algebra.rs. +vec4 quaternion_conjugate(vec4 a) { + return vec4(a[0], -a[1], -a[2], -a[3]); +} + +// This is kept carefully the same as quaternion_product() in +// linear_algebra.rs. +vec4 quaternion_product(vec4 a, vec4 b) { + return vec4((a[0] * b[0]) - (a[1] * b[1]) - (a[2] * b[2]) - (a[3] * b[3]), + (a[0] * b[1]) + (a[1] * b[0]) + (a[2] * b[3]) - (a[3] * b[2]), + (a[0] * b[2]) - (a[1] * b[3]) + (a[2] * b[0]) + (a[3] * b[1]), + (a[0] * b[3]) + (a[1] * b[2]) - (a[2] * b[1]) + (a[3] * b[0])); +} + +vec3 quaternion_rotate(vec3 position, vec4 rotation) { + vec4 result = quaternion_product(quaternion_product(rotation, + vec4(0.0, position)), + quaternion_conjugate(rotation)); + return vec3(result[1], result[2], result[3]); +} + +vec3 transform(vec3 a, Transformation transformation) { + vec3 rotated = quaternion_rotate(a, transformation.rotation); + vec3 translated = rotated + transformation.translation; + return translated; +} + + +vec4 apply_all_transforms(vec3 position) { + vec3 scaled = vec3(position.x * uniform_block.scale.x, + position.y * uniform_block.scale.y, + position.z * uniform_block.scale.z); + //return vec4(scaled, 1.0); + vec3 model = transform(scaled, uniform_block.model); + vec3 view = transform(model, uniform_block.view); + //vec4 projected = vec4(view, 1.0) * uniform_block.projection; + vec4 projected = vec4(view, 1.0) * uniform_block.projection; + //return vec4(view, 1.000); + return projected; + //return vec4(position, 1.0); +} + + void main() { - gl_Position = vec4(inPosition, 0.0, 1.0); + gl_Position = apply_all_transforms(vec3(inPosition, 0.0)); vertexColor = inColor; } |