summary refs log tree commit diff
path: root/shaders/shader.vert
blob: ff1698d64c83252201ad1a2247700a2ebd3fb399 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#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[](
  vec2(0.0, -0.5),
  vec2(0.5, 0.5),
  vec2(-0.5, 0.5)
);

vec3 colors[3] = vec3[](
  vec3(1.0, 0.0, 0.0),
  vec3(0.0, 1.0, 0.0),
  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 = apply_all_transforms(vec3(inPosition, 0.0));
  vertexColor = inColor;
}