변형
수학 잘하세요? 일단 전 못함.
이제 우리는 객체를 생성하고, 색을 입히고, 텍스처를 사용하여 세부적인 모습을 부여하는 방법을 알게 되었습니다. 하지만 이러한 객체들은 모두 정적인 객체이기 때문에 여전히 그다지 흥미롭지 않습니다. 매 프레임마다 정점을 변경하고 버퍼를 재구성하여 객체를 움직이게 만들 수도 있지만, 이는 번거롭고 상당한 처리 능력을 요구합니다. 객체를 변형(transform)하는 훨씬 더 나은 방법이 있는데, 바로 (여러 개의) 행렬 객체를 사용하는 것입니다.
transform
transform은 변형, 변환 등 여러가지 의미로 번역됩니다. 이 번역에서는 변환 또는 변형만 사용하겠습니다.
행렬은 처음에는 다소 어렵게 느껴질 수 있지만, 익숙해지면 매우 유용한 강력한 수학적 개념입니다. 행렬에 대해 이야기하려면 약간의 수학적 개념이 필요하며, 수학에 관심 있는 독자들을 위해 추가 자료를 제공하겠습니다.
하지만 변환을 완전히 이해하려면 행렬을 논하기 전에 벡터에 대해 좀 더 자세히 살펴봐야 합니다. 이 장의 목표는 앞으로 다룰 주제에 대한 기본적인 수학적 배경 지식을 제공하는 것입니다. 내용이 어렵게 느껴지더라도 최대한 이해하려고 노력하고, 필요할 때 언제든 다시 이 장을 참고하여 개념을 복습하세요.
벡터
가장 기본적인 정의로, 벡터는 방향 그 자체입니다. 벡터는 방향(direction)과 크기(magnitude)(또는 강도나 길이)를 가지고 있습니다. 벡터를 보물지도의 방향처럼 생각해 볼 수 있습니다. '왼쪽으로 10걸음, 북쪽으로 3걸음, 오른쪽으로 5걸음'에서 '왼쪽'은 방향이고 '10걸음'은 벡터의 크기입니다. 따라서 보물지도의 방향은 세 개의 벡터로 이루어져 있습니다. 벡터는 어떤 차원이든 가질 수 있지만, 보통 2차원에서 4차원 벡터를 사용합니다. 벡터가 2차원일 때는 평면상의 방향을 나타내고(2D 그래프를 생각해 보세요), 3차원일 때는 3차원 세계의 어떤 방향이든 나타낼 수 있습니다.
아래 그림에서 각 벡터는 2차원 그래프에서 화살표(x, y)로 표현된 세 개의 벡터를 볼 수 있습니다. 벡터는 3차원보다 2차원으로 나타내는 것이 더 직관적이므로, 이 2차원 벡터들을 az 좌표가 0인 3차원 벡터로 생각할 수 있습니다. 벡터는 방향을 나타내므로 벡터의 원점은 벡터의 값을 바꾸지 않습니다. 아래 그래프에서 벡터 \(\textcolor{red}{\vec{v}}\) 와 \(\textcolor{blue}{\vec{w}}\) 는 원점이 다르더라도 크기가 같다는 것을 알 수 있습니다.

벡터를 표현할 때 수학자들은 일반적으로 벡터 머리 위에 작은 막대가 있는 기호( \(\vec{v}\) )로 나타내는 것을 선호합니다. 또한, 공식에서 벡터를 표시할 때는 일반적으로 다음과 같이 나타냅니다.
\[
\vec{v} =
\begin{pmatrix}
\textcolor{red}{x} \\
\textcolor{green}{y} \\
\textcolor{blue}{z}
\end{pmatrix}
\]
벡터는 방향을 나타내기 때문에 위치로 시각화하기가 어려울 때가 있습니다. 벡터를 위치로 시각화하려면 방향 벡터의 원점을 (0,0,0)으로 설정하고 특정 방향을 가리키는 지점을 나타내는 위치 벡터를 만들 수 있습니다. (원점을 다르게 지정하고 '이 벡터는 이 원점에서 공간의 저 지점을 가리킨다'라고 표현할 수도 있습니다.) 따라서 위치 벡터 (3,5)는 원점 (0,0)을 기준으로 그래프에서 (3,5)를 가리킵니다. 이처럼 벡터를 사용하면 2차원 및 3차원 공간에서 방향과 위치를 설명할 수 있습니다.
일반 숫자와 마찬가지로 벡터에도 여러 가지 연산을 정의할 수 있습니다(이미 보신 것도 있을 겁니다).
스칼라 벡터 연산
스칼라(scalar)는 한 자리 숫자입니다. 스칼라를 포함하는 벡터를 더하거나 빼거나 곱하거나 나눌 때는 벡터의 각 요소에 스칼라를 더하거나 빼거나 곱하거나 나누면 됩니다. 덧셈의 경우 다음과 같습니다.
\[
\begin{pmatrix}
\textcolor{red}{1} \\
\textcolor{green}{2} \\
\textcolor{blue}{3}
\end{pmatrix}
+ x
\;\rightarrow\;
\begin{pmatrix}
\textcolor{red}{1} \\
\textcolor{green}{2} \\
\textcolor{blue}{3}
\end{pmatrix}
+
\begin{pmatrix}
x \\
x \\
x
\end{pmatrix}
=
\begin{pmatrix}
\textcolor{red}{1} + x \\
\textcolor{green}{2} + x \\
\textcolor{blue}{3} + x
\end{pmatrix}
\]
여기서 \(+\)는 \(+\), \(-\), \(\cdot\) 또는 \(\div\)가 될 수 있으며, \(\cdot\)는 곱셈 연산자입니다.
벡터 반전
벡터를 반전시키면 방향이 반대인 벡터가 됩니다. 북동쪽을 가리키는 벡터는 반전 후 남서쪽을 가리키게 됩니다. 벡터를 반전시키려면 각 성분에 마이너스 부호를 붙입니다(스칼라 값 -1을 사용하여 스칼라와 벡터의 곱으로 나타낼 수도 있습니다).
\[
-\vec{v}
=
-
\begin{pmatrix}
\textcolor{red}{v_x} \\
\textcolor{green}{v_y} \\
\textcolor{blue}{v_z}
\end{pmatrix}
=
\begin{pmatrix}
-\textcolor{red}{v_x} \\
-\textcolor{green}{v_y} \\
-\textcolor{blue}{v_z}
\end{pmatrix}
\]
덧셈과 뺄셈
두 벡터의 덧셈은 성분별 덧셈으로 정의됩니다. 즉, 한 벡터의 각 성분을 다른 벡터의 동일한 성분에 더하는 것입니다.
\[
\vec{v}
=
\begin{pmatrix}
\textcolor{red}{1} \\
\textcolor{green}{2} \\
\textcolor{blue}{2}
\end{pmatrix},
\vec{k}
=
\begin{pmatrix}
\textcolor{red}{4} \\
\textcolor{green}{5} \\
\textcolor{blue}{6}
\end{pmatrix}
\;\rightarrow\;
\vec{v} + \vec{k}
=
\begin{pmatrix}
\textcolor{red}{1} + \textcolor{red}{4} \\
\textcolor{green}{2} + \textcolor{green}{5} \\
\textcolor{blue}{3} + \textcolor{blue}{6}
\end{pmatrix}
=
\begin{pmatrix}
\textcolor{red}{5} \\
\textcolor{green}{7} \\
\textcolor{blue}{9}
\end{pmatrix}
\]
시각적으로 보면, 벡터 v=(4,2)와 k=(1,2)에서 두 번째 벡터를 첫 번째 벡터의 끝점 위에 더하여 결과 벡터의 끝점을 찾는 방식(머리-꼬리 방식)과 같습니다.

일반적인 덧셈과 뺄셈처럼, 벡터 뺄셈은 두 번째 벡터의 부호를 반전시킨 덧셈과 같습니다.
\[
\vec{v}
=
\begin{pmatrix}
\textcolor{red}{1} \\
\textcolor{green}{2} \\
\textcolor{blue}{3}
\end{pmatrix},
\quad
\vec{k}
=
\begin{pmatrix}
\textcolor{red}{4} \\
\textcolor{green}{5} \\
\textcolor{blue}{6}
\end{pmatrix}
\;\rightarrow\;
\vec{v} - \vec{k}
=
\begin{pmatrix}
\textcolor{red}{1} + (-\textcolor{red}{4}) \\
\textcolor{green}{2} + (-\textcolor{green}{5}) \\
\textcolor{blue}{3} + (-\textcolor{blue}{6})
\end{pmatrix}
=
\begin{pmatrix}
-\textcolor{red}{3} \\
-\textcolor{green}{3} \\
-\textcolor{blue}{3}
\end{pmatrix}
\]
두 벡터를 서로 빼면 두 벡터가 가리키는 위치의 차이가 되는 벡터가 나옵니다. 이는 두 점 사이의 차이를 나타내는 벡터를 구해야 하는 특정 경우에 유용합니다.

길이
벡터의 길이/크기를 구하려면 수학 시간에 배웠던 피타고라스 정리를 사용합니다. 벡터의 x축과 y축 성분을 삼각형의 두 변으로 생각하면 벡터는 삼각형을 이룹니다.

두 변의 길이(x, y)가 알려져 있고 기울어진 변의 길이 \(\textcolor{red}{\vec{v}}\)를 알고 싶으므로 피타고라스 정리를 사용하여 다음과 같이 계산할 수 있습니다.
\[
\lVert {\textcolor{red}{\vec{v}}} \rVert
=
\sqrt{\textcolor{green}{x}^2 + \textcolor{blue}{y}^2}
\]
여기서 \(\lVert {\textcolor{red}{\vec{v}}} \rVert\)는 벡터 \(\textcolor{red}{\vec{v}}\)의 길이를 나타냅니다. 이는 \(z^2\)를 추가함으로써 3D로 쉽게 확장할 수 있습니다.
이 경우 벡터 (4, 2)의 길이는 다음과 같습니다.
\[
\lVert {\textcolor{red}{\vec{v}}} \rVert
=
\sqrt{\textcolor{green}{4}^2 + \textcolor{blue}{2}^2}
=
\sqrt{{\textcolor{green}{16}} + {\textcolor{blue}{4}}}
=
\sqrt{20}
\approx 4.47
\]
즉 4.47(근사값)입니다.
벡터에는 특별한 종류가 있는데, 이를 단위 벡터라고 합니다. 단위 벡터는 길이가 정확히 1이라는 추가적인 특징을 가지고 있습니다. 어떤 벡터든 각 성분을 벡터의 길이로 나누면 단위 벡터 \(\hat{n}\)을 구할 수 있습니다.
\[
\hat{n}
=
\frac{\vec{v}}{\lVert \vec{v} \rVert}
\]
이를 벡터 정규화(normalizing)라고 합니다. 단위 벡터는 머리 위에 작은 지붕 모양으로 표시되며, 특히 방향만 중요한 경우(벡터의 길이가 바뀌어도 방향은 변하지 않음) 다루기가 훨씬 쉽습니다.
벡터-벡터 곱셈
두 벡터의 곱셈은 다소 특이한 경우입니다. 일반적인 벡터 곱셈은 시각적인 의미가 없기 때문에 명확하게 정의되어 있지 않지만, 곱셈을 할 때 선택할 수 있는 두 가지 특정한 경우가 있습니다. 하나는 내적(\(\vec{v}\cdot\vec{k}\))이고 다른 하나는 외적(\(\vec{v}\times\vec{k}\))입니다.
내적
내적
원문에서는 내적이 아닌 "dot product"라는 단어를 사용하였습니다. 이는 점곱이라고도 불리지만 이 번역에서는 내적으로 통일하겠습니다.
두 벡터의 내적은 두 벡터 길이의 스칼라곱에 두 벡터 사이 각도의 코사인 값을 곱한 것과 같습니다. 만약 이 설명이 어렵게 느껴진다면 공식을 살펴보세요.
\[
\vec{v}
\cdot
\vec{k}=
\Vert\vec{v}\Vert
\cdot
\Vert\vec{k}\Vert
\cdot
\cos\theta
\]
두 벡터 사이의 각도는 세타(\(\theta\))로 나타냅니다. 이것이 왜 흥미로울까요? 만약 \(\vec{v}\)와 \(\vec{k}\)가 단위 벡터라면, 그 길이는 1이 됩니다. 그러면 공식은 사실상 다음과 같이 간단해집니다.
\[
\hat{v}
\cdot
\hat{k}=
1\cdot1
\cdot
\cos\theta=
\cos\theta
\]
내적은 두 벡터 사이의 각도만을 나타냅니다. 코사인 또는 코사인 함수는 각도가 90도일 때 0이 되고, 0도일 때 1이 된다는 것을 기억하실 겁니다. 따라서 내적을 이용하면 두 벡터가 직교하는지 평행한지 쉽게 판별할 수 있습니다 (직교한다는 것은 두 벡터가 서로 직각을 이룬다는 의미입니다). 사인 또는 코사인 함수에 대해 더 자세히 알고 싶으시다면 칸 아카데미의 삼각법 기초 강의 영상을 참고하시기를 추천합니다. (한국어 자막이 있습니다!)
두 개의 단위 벡터가 아닌 벡터 사이의 각도를 계산할 수도 있지만, 그럴 경우 결과에서 두 벡터의 길이를 모두 나누어야 \(\theta\) 값만 남게 됩니다.
그렇다면 내적은 어떻게 계산할까요? 내적은 각 성분의 곱셈 결과를 더하는 것입니다. 두 개의 단위 벡터를 예로 들면 다음과 같습니다(두 벡터의 길이가 모두 정확히 1임을 확인할 수 있습니다).
\[
\begin{pmatrix}
\textcolor{red}{0.6} \\
-\textcolor{green}{0.8} \\
\textcolor{blue}{0}
\end{pmatrix}
\cdot
\begin{pmatrix}
\textcolor{red}{0} \\
-\textcolor{green}{1} \\
\textcolor{blue}{0}
\end{pmatrix}=
({\textcolor{red}{0.6}}*{\textcolor{red}{0}})+
(-{\textcolor{green}{0.8}}*{\textcolor{green}{1}})+
({\textcolor{blue}{0}}*{\textcolor{blue}{0}})=
-0.8
\]
이 두 단위 벡터 사이의 각도를 계산하기 위해 코사인 함수의 역함수 \(cos^{-1}\)를 사용하면 143.1도가 나옵니다. 이로써 두 벡터 사이의 각도를 계산했습니다. 내적은 나중에 조명 계산을 할 때 매우 유용하게 사용됩니다.
외적
외적은 3차원 공간에서만 정의되며, 평행하지 않은 두 벡터를 입력으로 받아 두 입력 벡터 모두에 직교하는 세 번째 벡터를 생성합니다. 두 입력 벡터 또한 서로 직교하는 경우, 외적은 세 개의 직교 벡터를 생성하게 되는데, 이는 앞으로의 장에서 유용하게 사용될 것입니다. 다음 이미지는 3차원 공간에서 외적의 표현을 보여줍니다.
\[
\begin{pmatrix}
\textcolor{red}{A_x} \\
\textcolor{green}{A_y} \\
\textcolor{blue}{A_z}
\end{pmatrix}
\times
\begin{pmatrix}
\textcolor{red}{B_x} \\
\textcolor{green}{B_y} \\
\textcolor{blue}{B_z}
\end{pmatrix}
=
\begin{pmatrix}
\textcolor{green}{A_y}\cdot\textcolor{blue}{B_z}
-
\textcolor{blue}{A_z}\cdot\textcolor{green}{B_y} \\[6pt]
\textcolor{blue}{A_z}\cdot\textcolor{red}{B_x}
-
\textcolor{red}{A_x}\cdot\textcolor{blue}{B_z} \\[6pt]
\textcolor{red}{A_x}\cdot\textcolor{green}{B_y}
-
\textcolor{green}{A_y}\cdot\textcolor{red}{B_x}
\end{pmatrix}
\]
보시다시피, 그다지 논리적으로 보이지는 않습니다. 그래도 이 방법을 그대로 따라하면 입력 벡터와 직교하는 또 다른 벡터를 얻을 수 있게 됩니다.
행렬
벡터에 대한 거의 모든 내용을 살펴보았으니 이제 행렬에 대해 알아볼 차례입니다! 행렬은 숫자, 기호 및/또는 수학적 표현식으로 이루어진 직사각형 배열입니다. 행렬의 각 항목을 행렬 요소라고 합니다. 아래는 2x3 행렬의 예입니다.
\[
\begin{bmatrix}
1 & 2 & 3 \\
4 & 5 & 6
\end{bmatrix}
\]
행렬은 (i,j)와 같이 행과 열을 나타내는 인덱스로 사용됩니다. 따라서 위의 행렬은 2x3 행렬(3개의 열과 2개의 행, 즉 행렬의 크기(dimensions))이라고 합니다. 이는 2차원 그래프에서 (x,y)와 같이 인덱스를 사용하는 방식과는 반대입니다. 예를 들어, 값 4를 얻으려면 (2,1) (두 번째 행, 첫 번째 열)과 같이 인덱스를 사용해야 합니다.
행렬은 기본적으로 수학적 표현식의 직사각형 배열일 뿐입니다. 행렬은 매우 훌륭한 수학적 속성을 가지고 있으며, 벡터와 마찬가지로 덧셈, 뺄셈, 곱셈과 같은 여러 연산을 정의할 수 있습니다.
덧셈과 뺄셈
두 행렬 간의 덧셈과 뺄셈은 각 요소별로 수행됩니다. 따라서 일반적인 숫자 계산에 익숙한 규칙이 동일하게 적용되지만, 두 행렬 모두에서 동일한 인덱스를 가진 요소에 적용됩니다. 이는 덧셈과 뺄셈이 같은 크기의 행렬에 대해서만 가능하다는 것을 의미합니다. 3x2 행렬과 2x3 행렬(또는 3x3 행렬과 4x4 행렬)은 서로 더하거나 뺄 수 없습니다. 두 2x2 행렬의 덧셈이 어떻게 작동하는지 살펴보겠습니다.
\[
\begin{bmatrix}
\textcolor{red}1 & \textcolor{red}2 \\
\textcolor{green}3 & \textcolor{green}4
\end{bmatrix}
+
\begin{bmatrix}
\textcolor{red}5 & \textcolor{red}6 \\
\textcolor{green}7 & \textcolor{green}8
\end{bmatrix}
=
\begin{bmatrix}
{\textcolor{red}1}+{\textcolor{red}5} & {\textcolor{red}2}+{\textcolor{red}6} \\
{\textcolor{green}3}+{\textcolor{green}7} & {\textcolor{green}4}+{\textcolor{green}8}
\end{bmatrix}
=
\begin{bmatrix}
\textcolor{red}6 & \textcolor{red}8 \\
\textcolor{green}{10} & \textcolor{green}{12}
\end{bmatrix}
\]
행렬 뺄셈에도 동일한 규칙이 적용됩니다.
\[
\begin{bmatrix}
\textcolor{red}4 & \textcolor{red}2 \\
\textcolor{green}1 & \textcolor{green}6
\end{bmatrix}
-
\begin{bmatrix}
\textcolor{red}2 & \textcolor{red}4 \\
\textcolor{green}0 & \textcolor{green}1
\end{bmatrix}
=
\begin{bmatrix}
{\textcolor{red}4}-{\textcolor{red}2} & {\textcolor{red}2}-{\textcolor{red}4} \\
{\textcolor{green}1}-{\textcolor{green}0} & {\textcolor{green}6}-{\textcolor{green}1}
\end{bmatrix}
=
\begin{bmatrix}
\textcolor{red}{2} & -\textcolor{red}{2} \\
\textcolor{green}{1} & \textcolor{green}{5}
\end{bmatrix}
\]
행렬-스칼라 곱셈
행렬-스칼라 곱은 행렬의 각 요소에 스칼라 값을 곱하는 것입니다. 다음 예는 곱셈을 보여줍니다.
\[
\textcolor{green}2 \cdot \begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix} = \begin{bmatrix} \textcolor{green}2 \cdot 1 & \textcolor{green}2 \cdot 2 \\ \textcolor{green}2 \cdot 3 & \textcolor{green}2 \cdot 4 \end{bmatrix} = \begin{bmatrix} 2 & 4 \\ 6 & 8 \end{bmatrix}
\]
이제 왜 그 숫자들을 스칼라라고 부르는지 이해가 될 것입니다. 스칼라는 기본적으로 행렬의 모든 요소를 자신의 값으로 확대/축소합니다. 이 예에서는 모든 요소가 2로 확대/축소되었습니다.
지금까지는 괜찮았습니다. 우리가 다룬 사례들은 그다지 복잡하지 않았거든요. 하지만 행렬-행렬 곱셈을 시작하면서부터는 상황이 달라졌습니다.
행렬-행렬 곱셈
행렬 곱셈은 복잡한 연산이라기보다는 익숙해지기 어려운 연산입니다. 행렬 곱셈은 기본적으로 미리 정의된 규칙들을 따르는 것을 의미합니다. 다만 몇 가지 제약 조건이 있습니다.
- 두 행렬을 곱하려면 왼쪽 행렬의 열 개수와 오른쪽 행렬의 행 개수가 같아야 합니다.
- 행렬 곱셈은 교환법칙이 성립하지 않습니다. 즉, \(A \cdot B \neq B \cdot A\)입니다.
두 개의 2x2 행렬의 곱셈 예시부터 시작해 보겠습니다.
\[
\begin{bmatrix} \textcolor{red}1 & \textcolor{red}2 \\ \textcolor{green}3 & \textcolor{green}4 \end{bmatrix} \cdot \begin{bmatrix} \textcolor{blue}5 & \textcolor{purple}6 \\ \textcolor{blue}7 & \textcolor{purple}8 \end{bmatrix} = \begin{bmatrix} \textcolor{red}1 \cdot \textcolor{blue}5 + \textcolor{red}2 \cdot \textcolor{blue}7 & \textcolor{red}1 \cdot \textcolor{purple}6 + \textcolor{red}2 \cdot \textcolor{purple}8 \\ \textcolor{green}3 \cdot \textcolor{blue}5 + \textcolor{green}4 \cdot \textcolor{blue}7 & \textcolor{green}3 \cdot \textcolor{purple}6 + \textcolor{green}4 \cdot \textcolor{purple}8 \end{bmatrix} = \begin{bmatrix} 19 & 22 \\ 43 & 50 \end{bmatrix}
\]
지금쯤이면 방금 무슨 일이 일어났는지 이해하려고 애쓰고 계실 겁니다. 행렬 곱셈은 왼쪽 행렬의 행과 오른쪽 행렬의 열을 이용하여 일반적인 곱셈과 덧셈을 결합한 것입니다. 다음 이미지를 통해 좀 더 자세히 설명해 보겠습니다.

먼저 왼쪽 행렬의 맨 위 행을 가져온 다음 오른쪽 행렬에서 열을 하나 선택합니다. 선택한 행과 열에 따라 결과 2x2 행렬의 어떤 출력값이 계산될지가 결정됩니다. 왼쪽 행렬의 첫 번째 행을 선택하면 결과값은 결과 행렬의 첫 번째 행에 들어가고, 열을 선택했을 때 첫 번째 열을 선택하면 결과값은 결과 행렬의 첫 번째 열에 들어갑니다. 빨간색 사각형이 바로 그런 경우입니다. 오른쪽 아래 결과를 계산하려면 첫 번째 행렬의 맨 아래 행과 두 번째 행렬의 가장 오른쪽 열을 사용합니다.
최종 값을 계산하기 위해 먼저 행과 열의 첫 번째 요소를 일반 곱셈으로 곱하고, 두 번째, 세 번째, 네 번째 요소 등도 같은 방식으로 곱합니다. 그런 다음 각 곱셈 결과를 모두 더하면 최종 결과가 나옵니다. 여기서 왼쪽 행렬의 열 크기와 오른쪽 행렬의 행 크기가 같아야 한다는 조건이 있다는 것도 이해가 될 것입니다. 그렇지 않으면 연산을 완료할 수 없기 때문입니다!
그 결과는 (n,m) 차원의 행렬이 되는데, 여기서 n은 좌변 행렬의 행 수이고 m은 우변 행렬의 열 수입니다.
머릿속으로 곱셈을 떠올리는 데 어려움을 느끼더라도 걱정하지 마세요. 손으로 직접 계산해 보면서 어려움이 있을 때마다 이 페이지로 돌아오세요. 시간이 지나면서 행렬 곱셈은 자연스럽게 익숙해질 것입니다.
좀 더 큰 예제를 통해 행렬 곱셈에 대한 논의를 마무리해 보겠습니다. 색깔을 이용하여 패턴을 시각화해 보세요. 유용한 연습으로, 직접 곱셈 결과를 계산해 보고 결과 행렬과 비교해 보세요. (행렬 곱셈을 직접 손으로 계산해 보면 금방 이해할 수 있을 겁니다.)
\[
{\small
\begin{bmatrix} \textcolor{red}4 & \textcolor{red}2 & \textcolor{red}0 \\ \textcolor{green}0 & \textcolor{green}8 & \textcolor{green}1 \\ \textcolor{blue}0 & \textcolor{blue}1 & \textcolor{blue}0 \end{bmatrix} \cdot \begin{bmatrix} \textcolor{red}4 & \textcolor{green}2 & \textcolor{blue}1 \\ \textcolor{red}2 & \textcolor{green}0 & \textcolor{blue}4 \\ \textcolor{red}9 & \textcolor{green}4 & \textcolor{blue}2 \end{bmatrix} = \begin{bmatrix} \textcolor{red}4 \cdot \textcolor{red}4 + \textcolor{red}2 \cdot \textcolor{red}2 + \textcolor{red}0 \cdot \textcolor{red}9 & \textcolor{red}4 \cdot \textcolor{green}2 + \textcolor{red}2 \cdot \textcolor{green}0 + \textcolor{red}0 \cdot \textcolor{green}4 & \textcolor{red}4 \cdot \textcolor{blue}1 + \textcolor{red}2 \cdot \textcolor{blue}4 + \textcolor{red}0 \cdot \textcolor{blue}2 \\ \textcolor{green}0 \cdot \textcolor{red}4 + \textcolor{green}8 \cdot \textcolor{red}2 + \textcolor{green}1 \cdot \textcolor{red}9 & \textcolor{green}0 \cdot \textcolor{green}2 + \textcolor{green}8 \cdot \textcolor{green}0 + \textcolor{green}1 \cdot \textcolor{green}4 & \textcolor{green}0 \cdot \textcolor{blue}1 + \textcolor{green}8 \cdot \textcolor{blue}4 + \textcolor{green}1 \cdot \textcolor{blue}2 \\ \textcolor{blue}0 \cdot \textcolor{red}4 + \textcolor{blue}1 \cdot \textcolor{red}2 + \textcolor{blue}0 \cdot \textcolor{red}9 & \textcolor{blue}0 \cdot \textcolor{green}2 + \textcolor{blue}1 \cdot \textcolor{green}0 + \textcolor{blue}0 \cdot \textcolor{green}4 & \textcolor{blue}0 \cdot \textcolor{blue}1 + \textcolor{blue}1 \cdot \textcolor{blue}4 + \textcolor{blue}0 \cdot \textcolor{blue}2 \end{bmatrix} \\ = \begin{bmatrix} 20 & 8 & 12 \\ 25 & 4 & 34 \\ 2 & 0 & 4 \end{bmatrix}
}
\]