➩ Add an extra number per pixel: color buffer (RGB) and z-buffer (Z).
➩ Start with all pixels at max distance (far distance of the camera).
➩ When drawing a pixel \(\left(x, y\right)\) with color \(c\) at depth \(z\), if \(z\) value is smaller than the current \(\left(x, y\right)\) z-value (closer to the camera), replace the pixel color with \(c\) and z-value with \(z\).
📗 Affine transformations in 2D were represented by linear transformations in 3D (3 by 3 matrices in HTML Canvas \(\begin{bmatrix} a & c & e \\ b & d & f \\ 0 & 0 & 1 \end{bmatrix}\)), similarly affine transformations in 3D can be represented by linear transformations in 4D (modelMatrix is 4 by 4).
➩ Translation in 3D can be viewed as shearing in 4D on the \(z = 1\) hyperplane.
➩ Rotation and scaling in 3D can still be rotation and scaling in 4D.
➩ A 3D point \(\begin{bmatrix} x \\ y \\ z \end{bmatrix}\) can be represented by 4D point with \(w = 1\), \(\begin{bmatrix} x \\ y \\ z \\ 1 \end{bmatrix}\) (homogeneous coordinate system)
➩ Arbitrary 4D linear transformations can be applied to \(\begin{bmatrix} x \\ y \\ z \\ 1 \end{bmatrix}\), and the result can be projected back onto \(w = 1\) hyperplane (\(\begin{bmatrix} x' \\ y' \\ z' \\ w' \end{bmatrix}\) can be projected back as \(\begin{bmatrix} \dfrac{x'}{w'} \\ \dfrac{y'}{w'} \\ \dfrac{z'}{w'} \\ 1 \end{bmatrix}\)).
📗 The simplest (the one used by THREE.js) vertex shader computes the position of a vertex projected onto the screen: gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0).
➩ projectionMatrix projects a point in 3D camera space onto 2D screen space.
➩ modelViewMatrix projects a point in the 3D scene space onto 3D camera space.
➩ vec4(position, 1.0) is the homogeneous coordinates of the position attribute of the vertex.
📗 Note: 1.0 is a float and 1 is an int, they are different in shader program.
📗 For most of the workbook exercises, vertex shader does not need to be changed.
➩ smoothstep: smoothstep(t1, t2, x) is the smooth version of step, goes from 0.0 to 1.0 smoothly for x between t1 and t2. This is useful to get smooth transition between two colors.
Math
📗 smoothstep performs smooth Hermite interpolation: for x between t1 and t2, t = (x - t0) / (t1 - t0); and smoothstep(t1, t2, x) = t * t * (3.0 - 2.0 * t).
📗 The simplest fragment shader uses a constant color for every fragment (pixel): gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0) colors every pixel of the object (group of triangles), the last 1.0 is transparency.
📗 Interesting appearances (shading) can be created using changing the way the pixels are colored: all of these happen in the fragment shader.
📗 Uniforms can be created by JavaScript and passed in the THREE.ShaderMaterial, for example, THREE.ShaderMaterial(uniforms = {t: {value: 0.0}, u: {value: 0.0}}, ...).
📗 Attributes can be created and set for THREE.BufferGeoemtry bg too, for example, bg.setAttribute("v", ...).
📗 Change the vertex displacement or fragment color as a function of t (time) or u (slider value).