| ... | ... |
@@ -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 |