... | ... |
@@ -2,6 +2,151 @@ |
2 | 2 |
|
3 | 3 |
An [OpenGL][] conventions document. |
4 | 4 |
|
5 |
+In order to promote modularity, interoperability and consistency, this document |
|
6 |
+tries to lay forward a set of conventions, mostly surrounding naming. This is |
|
7 |
+important when moving from a monolithic copy-and-paste regime, especially for |
|
8 |
+shaders, to one based on re-usable libraries. Historical (often deprecated) |
|
9 |
+OpenGL, other graphics APIs, uniformity and brevity are the main points of |
|
10 |
+reference and driving forces. |
|
11 |
+ |
|
12 |
+[`glconventions`]: https://git.rcrnstn.net/rcrnstn/glconventions |
|
13 |
+[OpenGL]: https://en.wikipedia.org/wiki/OpenGL |
|
14 |
+ |
|
15 |
+## Spaces and matrices |
|
16 |
+ |
|
17 |
+``` |
|
18 |
+mat4 world; |
|
19 |
+mat4 view; |
|
20 |
+mat4 projection; |
|
21 |
+``` |
|
22 |
+ |
|
23 |
+Note that `world` is what is sometimes known as `model`. OpenGL historically |
|
24 |
+had a combined `modelview` matrix which transformed *from* model space all the |
|
25 |
+way (through world space) *to* view space. Since having to name each matrix |
|
26 |
+with both the "from" space *and* "to" space results in overly long names, the |
|
27 |
+convention chosen here is to only use the "to" space name. This is consistent |
|
28 |
+with Direct3D. When we combine space names in a matrix name we use several "to" |
|
29 |
+space names, e.g. `view_world` or `projection_view_world`. Note the order! It |
|
30 |
+is the same as order of multiplication: `projection_view = projection * view`. |
|
31 |
+The "from" space is implicitly the space before the (last) named "to" space; |
|
32 |
+model->world->view->projection. |
|
33 |
+ |
|
34 |
+To enable instancing, `world` is (always) specified as a vertex attribute. |
|
35 |
+`view` and `projection` are uniforms (optionally a uniform block). |
|
36 |
+ |
|
37 |
+[`glVertexAttrib`]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glVertexAttrib.xhtml |
|
38 |
+ |
|
39 |
+## Shaders |
|
40 |
+ |
|
41 |
+### Variable naming |
|
42 |
+ |
|
43 |
+- [Uniforms][] |
|
44 |
+ - `*` |
|
45 |
+- Vertex shader [inputs][] (attributes) |
|
46 |
+ - `vert_*` (both per-vertex and per-instance data) |
|
47 |
+ uniforms |
|
48 |
+- Geometry shader [inputs][] |
|
49 |
+ - `geom_*` |
|
50 |
+- Fragment shader [inputs][] (vertex or geometry shader [outputs][]) |
|
51 |
+ - `*` |
|
52 |
+- Fragment shader [outputs][] (data) |
|
53 |
+ - `frag_*` |
|
54 |
+ |
|
55 |
+Note that the prefixes correspond to the file extensions used by the [GLSL |
|
56 |
+reference compiler][]. |
|
57 |
+ |
|
58 |
+Every name that is general enough that a collision might occur, even in |
|
59 |
+principle, must be suffixed with an `0`-based index (without any separating |
|
60 |
+`_`). Examples include `in vec4 color0`, `uniform sampler2D texture0`, `out |
|
61 |
+vec4 frag_data0`. |
|
62 |
+ |
|
63 |
+[uniforms]: #uniforms |
|
64 |
+[inputs]: #inputs |
|
65 |
+[outputs]: #outputs |
|
66 |
+[GLSL reference compiler]: https://www.khronos.org/opengles/sdk/tools/Reference-Compiler/ |
|
67 |
+ |
|
68 |
+### Uniforms |
|
69 |
+ |
|
70 |
+#### Geometric |
|
71 |
+ |
|
72 |
+```glsl |
|
73 |
+uniform mat4 view; |
|
74 |
+uniform mat4 projection; |
|
75 |
+``` |
|
76 |
+ |
|
77 |
+If the GLSL code is distributed with corresponding CPU code to set its |
|
78 |
+uniforms, the following is also acceptable, since the names and their scope is |
|
79 |
+the same: |
|
80 |
+ |
|
81 |
+```glsl |
|
82 |
+uniform camera |
|
83 |
+{ |
|
84 |
+ mat4 view; |
|
85 |
+ mat projection; |
|
86 |
+} |
|
87 |
+``` |
|
88 |
+ |
|
89 |
+Note that this is a [uniform block][] and requires [uniform buffer][] support, |
|
90 |
+i.e. OpenGL [\>=3.1][] or the [`ARB_uniform_buffer_object`][] extension. |
|
91 |
+Further more, it requires some more work on the CPU. The advantage is that the |
|
92 |
+uniforms do not have to be set for every used shader program and can be set |
|
93 |
+"globally" e.g. once per frame. |
|
94 |
+ |
|
95 |
+[uniform block]: https://www.khronos.org/opengl/wiki/Interface_Block_(GLSL) |
|
96 |
+[uniform buffer]: https://www.khronos.org/opengl/wiki/Uniform_Buffer_Object |
|
97 |
+[\>=3.1]: https://en.wikipedia.org/wiki/OpenGL#Version_history |
|
98 |
+[`ARB_uniform_buffer_object`]: https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_uniform_buffer_object.txt |
|
99 |
+ |
|
100 |
+### Inputs |
|
101 |
+ |
|
102 |
+#### Geometric |
|
103 |
+ |
|
104 |
+```glsl |
|
105 |
+in mat4 {prefix_}world; |
|
106 |
+in vec3 {prefix_}position; |
|
107 |
+in vec3 {prefix_}normal; |
|
108 |
+in vec2 {prefix_}tex_coord; |
|
109 |
+``` |
|
110 |
+ |
|
111 |
+In order of likelihood to be needed. |
|
112 |
+ |
|
113 |
+#### Common |
|
114 |
+ |
|
115 |
+```glsl |
|
116 |
+in vec4 {prefix_}color0; |
|
117 |
+``` |
|
118 |
+ |
|
119 |
+### Outputs |
|
120 |
+ |
|
121 |
+As a general rule, all inputs should be forwarded to outputs because, in a |
|
122 |
+modular world, it may not be known what input the next shader stage requires. |
|
123 |
+ |
|
124 |
+All geometric quantities should be outputted in the [standard space][] of the |
|
125 |
+next shader stage *and* in any spaces between the standard space of the current |
|
126 |
+shader stage (exclusive) and the next. Specifically, this means the vertex |
|
127 |
+shader should output e.g. both `vec3 normal` and `vec3 world_normal`. |
|
128 |
+ |
|
129 |
+Unused outputs will be optimized out in the link stage. |
|
130 |
+ |
|
131 |
+The overwhelmingly most common fragment shader output is `vec4 |
|
132 |
+frag_color`, and it is acceptable if data that might not quite be color |
|
133 |
+is written to this output, provided that it is the only output and that |
|
134 |
+the data can be held in `GL_RGBA8` (i.e. only 8 bits per channel). |
|
135 |
+ |
|
136 |
+[standard space]: #standard-spaces |
|
137 |
+ |
|
138 |
+### Standard spaces |
|
139 |
+ |
|
140 |
+Each shader stage has a standard space in which input geometric quantities are |
|
141 |
+expressed: |
|
142 |
+ |
|
143 |
+- vertex: `model` |
|
144 |
+- geometry: `view` |
|
145 |
+- fragment: `view` |
|
146 |
+ |
|
147 |
+Quantities that is not expressed in the standard space has the space prefixed, |
|
148 |
+e.g. `world_normal`. |
|
149 |
+ |
|
5 | 150 |
## License |
6 | 151 |
|
7 | 152 |
Licensed under the [CC BY 4.0 License][] unless otherwise noted, see the |