ゲーム開発者向けのカンファレンス「CEDEC+KYUSHU 2023」が、2023年11月25日(土)に開催されました。
本記事は、ゲームプログラマを目指す高校生や専門学校生に向け、ゲームに活用されている数学的知識が実例とともに解説されたセッション「ゲームプログラマを目指す前に知っておきたい数学」をレポートします。
ゲーム開発者向けのカンファレンス「CEDEC+KYUSHU 2023」が、2023年11月25日(土)に開催されました。
本記事は、ゲームプログラマを目指す高校生や専門学校生に向け、ゲームに活用されている数学的知識が実例とともに解説されたセッション「ゲームプログラマを目指す前に知っておきたい数学」をレポートします。
TEXT / じく
EDIT / 神谷 優斗
登壇したのは、Massive Game Technology 川野 竜一氏。著書に「DirectX 12の魔導書 3Dレンダリングの基礎からMMDモデルを踊らせるまで」があります。現在は、専門学校で非常勤としてゲームプログラミングを教えるほか、HIKKYの外部委託としてグラフィックスプログラミングにも携わっています。
以前は「通常のゲーム開発であれば高校数学ができれば大丈夫」と言われていたようですが、表現力が上がった現在は高校数学だけでは十分ではないと川野氏は語ります。
ここでの「高校数学」とは、数Ⅰ・数Ⅱ・数Ⅲ・数A・数B・数C・行列にあたる、理系大学の合格に必要な数学を指しています。また、数学的知識だけでなく、簡単な力学や波などの物理学的知識も必要であるそうです。
文系や総合学科などで学ぶ範囲の数学では、必要条件すら満たしていないことが多いと川野氏は言います。
プログラマーの業務においては、計算自体はコンピュータが行ってくれます。√・log・sin・cosなどを計算するのはコンピュータの仕事であり、単に計算が苦手であることは問題にはなりません。
数学的な観点でのプログラマーの役割は、式を組み立てることにあります。解決すべき問題を数学的に捉え、問題を解決できる数式を作りあげることが求められます。
例えば、上記画像で挙げている「2つの球の当たり判定を取る」場合。
この問題を解決するにあたり、プログラマーは「2つの球が重なっている条件は何だろう?」と考える必要があります。球の定義は「中心からの距離が等しい」こと。ならば、2つの球の中心間の距離(P1 – P2)と、半径の和(r1 + r2)を比較すればよいことになります。
つまり、2つの球体が当たる条件は、‖P1 – P2‖ < r1 + r2(※)と求められます。
※「‖……‖」はベクトル空間における長さや距離を表現する概念「ノルム(norm)」を意味する数学記号
式の組み立てには、「定義」を知るのも重要であるとのこと。定義とは、√やlog、sinなどがそれぞれ「何を意味しているのか?」を表す不変の概念です。例えば、以下が定義にあたります。
・sinやcosは角度を三角比に変換する関数であると同時に、半径1の円周上の座標である
・Σや∫は「ともかく定義内の値を全部合計する」演算子である
式は問題に応じて自らが組み立てるものですが、定義は覚える必要があります。川野氏は、定義は言葉と捉えることもでき、値や数式に対して何をすべきかという言葉が数学の定義になると説明しました。
公式と定義を混同することは、挫折の要因になりえます。川野氏は、ゲームプログラミングの書籍などに記載される数式ひとつひとつを言葉ととらえ、その言葉を理解するのに定義が大切になると語りました。
講演では、ゲームプログラミングに必要な数学的知識のうち、最低限必要であるベクトルについて解説されました。
ベクトルとは、いわば「矢印」です。例えば、多くの2D・3Dゲームエンジンでは、空間上の位置や移動量をベクトルで扱います。ベクトルの知識がなければ、オブジェクトを動かすこともままなりません。
ベクトルとは、空間をいくつかの軸に分け(2次元にあればXY、3次元であればXYZが一般的)、それぞれの軸に沿った方向に進む大きさを表現したものです。
2次元で考えた場合、X軸に沿って進んだ距離(Vx)とY軸に沿って進んだ距離(Vy)を辺と考えると、直角三角形ができあがります。ベクトル((Vx, Vy))は直角三角形の斜辺にあたり、ベクトルの長さVは以下の式で示されます。
‖V‖ = √(Vx2+Vy2)
ベクトル同士を足すと、単純にベクトルの移動量を合計した1つのベクトルになります。
A = (Vx, Vy)とB = (Bx, By)を加算した場合、Aの終点(矢印の先)とBの始点(矢印の根本)を重ね、Aの始点とBの終点を結んだ矢印が結果のベクトルとなります。
式にすると、以下のようになります。
A + B = (Ax + Bx, Ay + By)
例えば、 A = (3, 1) , B = (1, 2) の場合、A + B = (4, 3) となります。
加算では2つのベクトルを統合した一方で、分解は1つのベクトルを2つのベクトルに分離します。
ベクトルV = (Vx, Vy)は、各軸に沿ったベクトル X = (Vx, 0)、Y = (0, Vy)に分離できます。
これを拡張して考えると、X軸やY軸に平行でないベクトルにも分解できます。
上記画像では、VはX(紫の矢印)とY(青の矢印)の加算と考えられる一方で、XとYはVを分解したものとも考えられます。
ベクトルの向きは変えずに大きさのみ1にする正規化(normalize)は、レンダリングなどによく用いられます。
正規化の使用例として、シューティングゲームの自機狙い弾が挙げられました。
自機座標をP(px, py)、敵座標をE(ex, ey)とすると、敵から自機に向かうベクトルはV(vx, vy) = P(px, py) – E(ex, ey)となります。しかし、このベクトルを弾の速度として適用すると、一瞬で自機の座標に到達してしまいます。
そこで、Vを正規化すると大きさが1に揃います。正規化したVに自機狙い弾のスピードを乗算すれば、距離によらず一定の速さで弾を動かせます。
Vの大きさを1にするにはV自身の大きさで割ればよいため、正規化の式は次のようになります。
ベクトルの内積とは、2つのベクトルの成分同士を「乗算して加算する」演算です。ゲームでは、カリングなどに使用されます。
ベクトルAがA = (Ax, Ay)、ベクトルBがB = (Bx, By)であるとき、AとBの内積「A・B」は次の式で求められます。
A・B = AxBx + AyBy
加法定理を用いると、 A・B = ‖A‖‖B‖cosθ が導出され、以下が成り立ちます。
cosθ = (A・B) / (‖A‖‖B‖)
射影:‖A‖cosθ = (A・B) / ‖B‖
cosθはAとBのなす角がわかります。2直線の角度は、レンダリングに使用するシェーダーや、ボーンのアニメーションなどに必要です。
射影は、AからBに光を当てたときに影となるベクトルを指します。Bが正規化されていれば、内積と射影長は一致します。
法線ベクトルは「面に垂直なベクトル」です。
法線ベクトルは3D空間で多用されます。前述のカリングでは、3Dモデルの各面が視界に対して表側か裏側かを判別し、裏側であれば描画しない処理を行います。このとき、法線ベクトルが面の向いている方向として機能します。
以上の内容を踏まえて、坂道の加速度やおはじきに関する応用例が示されました。
斜面を移動するオブジェクトの加速度を計算するためには、斜面の角度が必要です。しかし、三次元空間における斜面の角度は、計算コストがかかります。
そこで、ゲームの物理演算では、垂直方向の重力加速度と、坂道の法線ベクトルを使用して簡易的に坂道に対する加速度を計算しています。
物体が坂道を転がる場合、物体は重力に対する垂直抗力(※)により斜面に垂直な力は打ち消されます。打ち消される力は、重力加速度と坂道の法線ベクトルの内積で求められます。
※ 面に対して力を加えたとき、面に垂直な方向にかかる反発力
そして、打ち消されずに残った力が推進力となります。重力ベクトルをG、正規化された坂道の法線ベクトルをN、推進力をAとすると、Aは次の式で求められます。
A = G – N(N・G)
式からわかるように、坂道の角度を測る必要なく、2つのベクトルの計算によって加速度を求めることができました。
なお、以上の式をプログラムにしたものが、川野氏のGitHubリポジトリにて公開されています。
ゲームの物理演算では衝突も扱います。講演では、回転や摩擦を考慮しないおはじきを例に、衝突の計算方法について解説されました。
物体の衝突においては、衝突前後で関与した物体の運動量の和が変わらない「運動量保存の法則」が成り立ちます。上記画像のように同じ質量のおはじきが真正面から衝突した場合、ちょうど運動量が交換されます。
では、真正面の衝突でなかった場合はどうなるでしょうか?斜めに衝突した場合、衝突時の法線ベクトル方向にだけ運動量が移動し、残りは元のおはじきに残ります。その結果、2つのおはじきはそれぞれもとの方向とは別方向に移動します。
円形同士の衝突では、互いの中心点を結ぶ線が法線方向となります。
法線方向がわかれば、運動量の変化を求めることが可能です。元の運動量を法線方向と非法線方向に分解。法線方向が相手に伝わり非法線方向が自分に残るため、内積(射影)を使って大きさを算出します。
最初移動しているおはじきの速度ベクトルをV0、衝突後のそれぞれのベクトルをV1、V2、法線ベクトルをNとすると、衝突されたおはじきの運動量変化は次の式で表されます。
V1 = V0(V0・N)
運動量保存の法則よりV0 = V1 + V2 であるため、V2が求められます。
V2= V0(1 – V0・N)
運動量の計算においても、川野氏のGitHubリポジトリにサンプルコードが公開されています。
最後に川野氏は、ゲーム系専門学校に対しては授業で行う以上に数学を取り組むこと、高校生に対しては理系数学を学ぶことを勧めました。一方で、数学が分からなくても力技でもとにかく作り続ける根性でゲーム業界に入った学生もいるとエールを送り、講演を締めくくりました。
川野 竜一氏 XアカウントMassive Game Technology 公式サイト『ゲームプログラマを目指す前に知っておきたい数学』- CEDEC+KYUSHU 2023ゲーム会社で16年間、マニュアル・コピー・シナリオとライター職を続けて現在フリーライターとして活動中。 ゲーム以外ではパチスロ・アニメ・麻雀などが好きで、パチスロでは他媒体でも記事を執筆しています。 SEO検定1級(全日本SEO協会)、日本語検定 準1級&2級(日本語検定委員会)、DTPエキスパート・マイスター(JAGAT)など。
西川善司が語る“ゲームの仕組み”の記事をまとめました。
Blenderを初めて使う人に向けたチュートリアル記事。モデル制作からUE5へのインポートまで幅広く解説。
アークライトの野澤 邦仁(のざわ くにひと)氏が、ボードゲームの企画から制作・出展方法まで解説。
ゲーム制作の定番ツールやイベント情報をまとめました。
ゲームメーカーズ スクランブル2025で行われた講演のアーカイブ動画・スライドをまとめました。
GAME CREATORS CONFERENCE ’25で行われた講演レポートをまとめました。
GDC 2025で行われた講演レポートをまとめました。
UNREAL FEST 2024で行われた講演レポートやインタビューをまとめました。
東京ゲームショウ2024で展示された作品のプレイレポートやインタビューをまとめました。
CEDEC2024で行われた講演レポートをまとめました。
BitSummitで展示された作品のプレイレポートをまとめました。
ゲームメーカーズ スクランブル2024で行われた講演のアーカイブ動画・スライドをまとめました。
CEDEC2023で行われた講演レポートをまとめました。
東京ゲームショウ2023で展示された作品のプレイレポートやインタビューをまとめました。
UNREAL FEST 2023で行われた講演レポートをまとめました。
BitSummitで展示された作品のプレイレポートをまとめました。
ゲームメーカーズ スクランブルで行われた講演のアーカイブ動画・スライドをまとめました。
UNREAL FEST 2022で行われた講演レポートやインタビューをまとめました。
CEDEC2022で行われた講演レポートをまとめました。