-
Notifications
You must be signed in to change notification settings - Fork 0
/
notes.txt
259 lines (222 loc) · 14.3 KB
/
notes.txt
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# Learn OpenGL NOTES
Immediate Mode (fixed function pipeline): Old way of OpenGL, easier but developers have less freedom
Core-Profile Mode: Requires developer to truly understand OpenGL/graphics, but more flexible/efficient
Context: The state of OpenGL
Graphics Pipeline: Process of transforming 3D coordinates => 2D coordinate => colored pixels
OpenGL Shading Language (GLSL): Language shaders are written in
Vertex: Collection of data per 3D coordinate
Vertex Attributes: Any data associated with a vertex (ex: 3D position, color value)
Primitives: Hints that tell OpenGL how to render data (ex: points, triangles, line)
== GRAPHICS PIPELINE ==
1. Vertex Shader: 3D coordinates => 3D coordinates & some basic processing on vertex attributes
2. Primitive (Shape) Assembly: Takes all vertices from vertex shader that form a primitive and assembles all the points in the primitive shape given
3. Geometry Shader: Takes in a collection of vertices that form a primitive and has the ability to generate other shapes by emitting new vertices to form new (or other) primitives.
4. Rasterization Stage: Maps the resulting primitives (of Geometry Shader) to the corresponding pixels on the final screen, resulting in fragments for the fragment shader to use.
- Clipping: Before fragment shaders run, clipping discards all fragments that are outside your view, increasing performance.
5. Fragment Shader: Calculate the final color of a pixel. Usually the stage where all the advanced OpenGL effects occur (ex: lighting, shadows, color of the light).
6. Alpha Test & Blending: Checks the corresponding depth (and stencil) value of the fragment and uses those to check if the resulting fragment is in front or behind other objects and should be discarded accordingly.
- NOTE: even if a pixel output color is calculated in the fragment shader, the final pixel color could still be something entirely different when rendering multiple triangles.
Fragment: All the data required for OpenGL to render a single pixel
Shaders: Small programs on the GPU for each step of the graphics pipeline
Normalized Device Coordinates: 3D coordinates in a specific range between [-1.0, +1.0]
Vertex Buffer Objects (VBO): Memory that can store a large amount of vertex data in the GPU's memory.
- After binding the buffer using glBindBuffer(), glBufferData() function can be used to store data in VBO
Vertex Array Object (VAO): Memory that can store the vertex attribute configurations (describes the data written into VBO)
- After bound using glBindVertexArrays(), any subsequent vertex attribute calls from that point will be stored in VAO
- VBO is actually NOT part of VAOs state; the actual association between an attribute index and a buffer is made through the glVertexAttribPointer
Element Buffer Objects (EBO): A buffer that stores vertex attribute indices. These specify to OpenGL which vertices create a primitive (ex: triangle).
- Used to avoid redundant data for primitives with shared vertex attributes.
- The EBO bound while a VAO is bound is stored as the VAO's EBO. Unbinding the EBO while the VAO is bound will unbind the EBO from the VAO.
== ECT ==
- The areas of the graphics pipeline that are configurable are the Vertex Shader, Geometry Shader, and Fragment Shader
- In Modern OpenGL we are REQUIRED to define at least a vertex and fragment shader of our own (There are no default vertex/fragment shaders on the GPU)
- Geometry shader is optional and usually left to its default shader
- OpenGL only processes 3D normalized device coordinates, any coordinates outside of the range [-1.0,+1.0] will be clipped/discarded.
- Unlike usual screen coordinates, the positive y-axis points in the up direction and (0,0,0) coordinate is in the center.
+++ GLSL +++
### Swizzling:
vec2 someVec;
vec4 differentVec = someVec.xyxx;
vec3 anotherVec = differentVec.zyw;
vec4 otherVec = someVec.xxxx + anotherVec.yxzy;
### Input Variables & Output Variables
Vertex Shaders:
- Receives its input straight from the vertex data (stored using glBindBuffer/glBufferData functions)
Fragment Shaders:
- Requires a vec4 color output variable, since fragment shaders need to generate final output color
- failing to specify an output color will render your object black (or white)
Uniforms: Global variables that can be accessed from any shader at any stage in the shader program.
- Whatever the uniform value is set to, it will keep its value until it is reset or update
- If you declare a uniform that isn't used anywhere in your GLSL coed, the compiler will silently remove the variable from the compiled version
- Finding the uniform location does not require you to use the shader program first
- Updating a uniform requires you to first use the program (glUseProgram), it sets the uniform on the currently active shader program
### Accessing Vector Data
Positionally: xyzw
Color: rgba
Texture Coordinates: stpq
Ex: vec4 aVec = vec4(0.1, 0.2, 0.3. 0.4)
aVec.x = aVec.r = aVec.s = 0.1
aVec.y = aVec.g = aVec.t = 0.2
aVec.z = aVec.b = aVec.p = 0.3
aVec.w = aVec.a = aVec.q = 0.4
++ Matrix Math ++
Transpose: Swap the columns and rows
|a b c|T |a d g|
|d e f| = |b e h|
|g h i| |c f i|
Matrix Multiplication
Identity matrix: Multiplying any matrix N by identity matrix will produce the same matrix N.
|1 0 0 0| |X| = |X|
|0 1 0 0| |Y| = |Y|
|0 0 1 0| |Z| = |Z|
|0 0 0 1| |W| = |W|
Scaling matrix:
|1 0 0 0| |X| = |1X|
|0 2 0 0| |Y| = |2Y|
|0 0 3 0| |Z| = |3Z|
|0 0 0 4| |W| = |4W|
Translation matrix:
|1 0 0 1| |X| = |X+1W|
|0 1 0 2| |Y| = |Y+2W|
|0 0 1 3| |Z| = |Z+3W|
|0 0 0 1| |W| = |W |
Matrix transformations:
- The rows of a square transformation matrix can be interpreted as the basis vectors of the new coordinate space after transformation.
Ex:
multiplying a 2D vector by the following matrix:
|3 3| <---- new basis vector p
|-3 3| <---- new basis vector q
Modifies the basis vectors of [1,0](x) and [0, 1](y)
|y
|^
||
--------==>x----
|
|
to [3,3](p) and [-3,3](q).
^q | ^p
\ | /
\ | /
\|/
---------------
|
|
This rotates the vector 45 degrees counter clockwise about the origin.
Not only that, but the vector will experience a uniform scaling due to the
basis vectors increasing in length from 1 to ~4.24
Rotations:
- Rotations in 3D are specified with an angle AND a rotation axis.
Rotation matrix around the X-Axis (where A is the angle):
|1 0 0 0| |X| = |X |
|0 cosA -sinA 0| |Y| = |YcosA-ZsinA|
|0 sinA cosA 0| |Z| = |YsinA+ZcosA|
|0 0 0 1| |1| = |1 |
Rotation matrix around the Y-axis
|cosA 0 sinA 0| |X| = |XcosA+ZcosA |
|0 0 0 0| |Y| = |Y |
|-sinA 0 cosA 0| |Z| = |-XsinA+ZcosA|
|0 0 0 1| |1| = |1 |
Rotation matrix around the Z-axis
|cosA -sinA 0 0| |X| = |XcosA-YsinA|
|sinA cosA 0 0| |Y| = |XsinA+YcosA|
|0 0 0 0| |Z| = |Z |
|0 0 0 1| |1| = |1 |
++ Coordinate Systems ++
There are 5 coordinate systems important to us:
- Local Space (Object Space)
- Coordinate system that is local to the object
- World Space
- Coordinates of all the vertices relative to the game world
- View Space (Camera Space or Eye Space)
- Coordinates of all vertices relative to the user's view
- Clip Space
- OpenGL expects the coordinates to be within a specific range and any coordinate that falls outside of this range is clipped
- Screen Space
Transformation Matrices for transforming coordinates between spaces:
- Model Matrix
- Local Space => World Space
- A transformation matrix that translates, scales, and/or rotates objects to place it in the world at a location/orientation it belongs to
- View Matrix
- World Space => View Space
- Projection Matrix
- View Space => Clip Space
- Transforms coordinates within a specified range (e.g. -1000 to 1000 in each dimension) to device coordinates, (-1.0, 1.0).
- All coordinates outside of this range will not be mapped between (-1.0, 1.0) and therefore be clipped.
- If only a part of a primitive is outside the clipping volume, OpenGL will reconstruct the triangle as one or more triangles to fit inside clipping range
Vertex coordinates first start in local space as local coordinates then are further processed to world coordinates, view coordinates, clip coordinates and eventually end up as screen coordinates.
LOCAL SPACE ===MODEL MATRIX===> WORLD SPACE ===VIEW MATRIX===> VIEW SPACE ===PROJECTION MATRIX===> CLIP SPACE ===VIEWPORT TRANSFORMATION===> SCREEN SPACE
- A nice illustration can be found here (https://learnopengl.com/Getting-started/Coordinate-Systems)
- When modifying your object, it makes most sense to do this in local space
- When calculating certain operations on the object with respect to the position of other objects, it makes most sense in world coordinates
Frustum: Viewing box that a projection matrix creates
- Each coordinate that ends up inside the frustum will end up on the user's screen
Projection: Process of converting coordinates within a specified range to NDC (Normal Device Coordinates) that can easily be mapped to 2D view-space coordinates
- "projects" 3D coordinates to the easy-to-map-to-2D NDCs
Perspective Division: Dividing the x, y, and z components of the position vectors by the vector's homogeneous w component
- transforms the 4D clip space coordinates to 3D normalized device coordinates
Orthographic projection matrix defines a cube-like frustum
- defines the visible coordinates and is specified by a width, a height, and a near and far plane
- produces unrealistic results since the projection doesn't take perspective into account
Perspective projection matrix maps a given frustum range to clip space
- Manipulates the w value of each vertex coordinate in such a way that the further away a vertex coordinate is from the viewer, the higher this w component become
V(clip) = M(projection) * M(view) * M(model) * V(local)
- Note that the order of matrix multiplication is reversed (we need to read matrix multiplication from right to left)
== Camera ==
1. Camera position: Vector in world space that points to the camera's position
2. Camera direction: Normalized vector in that points in the direction from the camera's position to the camera's target (in practice, points in opposite direction)
* normalize((Camera Position Vector) - (Camera Target Vector))
3. Right axis: A right vector that represents the positive x-axis of the camera space
* normalize(cross(vec3(0,0,1), cameraDirection))
4. Up Axis: a vector that points in the camera's positive y-axis
* cross(cameraDirection, cameraRight)
Three Euler angles:
* Imagine a plane sitting on the origin with it's head and tail pointing towards +Z/-Z
1. Pitch: When the plan rotates around the X-axis
* This causes the plane to look up or down
2. Yaw: When the plan rotates around the Y-axis
* This causes the plane to look left or right
3. Roll: When the plan rotates around the Z-axis
* This determines how much the left wing points up or down (and inversely for the right wing)
+++ Lighting +++
Ambient Lighting: Even when dark usually light somewhere in the world (moon, distant light)
- this ambient light is a constant that will give every object some color.
Diffuse Lighting: Directional impact a light object has on an object.
- The more a part of an object faces the light source, the brighter it becomes
Specular Lighting: Bright part of a light that appears on shiny objects
- Specular highlights are often more inclined to the color of the light than the color of the object
Attenuation: Reduced intensity of light, over the distance a light ray travels
Directional Light: A light source modeled to be infinitely far away is called a directional light since all it's light rays have the same direction.
Point Light: A light source with a given position somewhere in a world that illuminates in all directions where the light rays fade out over distance(attenuate)
+++ Depth Testing +++
Depth testing must be enabled using glEnable(GL_DEPTH_TEST)
Z-Fighting: A common visual artifact when two triangles are so closely aligned to each other that the depth buffer does not have enough precision to determining which one is in front of the other.
==== Physically Based Rendering ====
- For a PBR lighting model to be considered physically based, it has to satisfy the following:
- Be based on the microfacet surface model
- Be energy conserving
- Use a physically based BRDF
- Microfacet model: A theory that describes that any surface at a microscopic scale can be described by tiny little perfectly reflective mirrors called microfacets
- The way in which these little mirrors are aligned determines if a surface is rough (chaotically aligned) or smooth (similarly aligned)
- Incoming light rays are more likely to scatter along completely different directions on rough surfaces, resulting in a more widespread specular reflection.
- On a smooth surface, the light rays are more likely to reflect in roughly the same direction, giving smaller and sharper reflections.
- When light hits a surface, it gets split into both a refraction part and a reflection part.
- Reflection is light that directly gets reflected and doesn't enter the surface; specular lighting
- Refraction is the remaining light that enters the surface and gets absorbed; diffuse lighting
- Light rays re-emerging out of the surface contribute to the surface's observed color
- Usually rendering techniques simplify scattered light by assuming a small area of impact, eliminating the possibility of light exiting from a distant point of entry
- Subsurface scattering techniques aim to improve visual quality by not simplifying the real physics of
- Dielectric: non-metallic surface
+++ GLSL functions +++
- radians(float degrees)
- degrees(float radians)
- sin(float angleInRadians) [as well as cos, tan, asin, acos, atan, sinh, cosh, tanh, asinh, acosh, atanh]
- pow(float base, float exponent)
- exp(float x) = e^x
- exp2(float x) = 2^x
- log(float x) = ln(x)
- log2(float x) = log_base2(x)
- sqrt(float x)
- inversesqrt(float x)
- abs, sign, floor, ceil, trunc, fract, round, roundEven
==== Experimentation notes ====
- When accidentally not setting the height map up properly, I used an albedo map in GL_TEXTURE0 as the height map. It seemed to create feel of a layer of ice lying on top of the surface.