Game Programming

Game Programming


プログラミング

ゲーム作成の中で、プログラミングは実は限られた一部。

でも、新しい効果とかを出すには必須。

ゲーム機の寿命は短い。

比較的特殊なCPUや、デバイス(GPU)を取り扱う

従って、常に新しいもの勉強する必要がある。


ライブラリを作成する

自分で、いろんなツールを作成していく。

自分で道具を作っていく。


線形代数

3D を取り扱うゲームでは必須。

線形代数は、もっとも役に立つ数学。

フーリエ変換とかも、線形代数の一部。


ゲームの設計、企画

物語を作れる方が良い。これは、プログラミングとかの技術とは別物。


演出

かっこの良い動作

登場のさせかた

見せる順序

これも、プログラミングとは関係ない。


大学で、なんでゲームプログラムを勉強するの?

Real-time Programming の例題として

複雑な実際のプログラミングを体験する

チームプログラミングを体験する

その中で、出てきたプログラミングの問題を解決する


2Dモデリング

色彩

ドットで書いていっても良い

でも、今は結構大きいので大きな絵を書く必要がある。


3Dモデリング

Blender というフリーのツールがあります。

是非使ってみよう。


ポリゴン

三角形を集めて、3Dの物体を作る。

三つの点があるので、

    (x_1, y_1, z_1)
    (x_2, y_2, z_2)
    (x_3, y_3, z_3)

の9つのデータが必要。


Texture

ポリゴンに貼られた 2D の画像

なくても良いが...


3D Object

ポリゴンが集まってできた一つのオブジェクト


XML

Blender からの出力を、XML にして書き出す。

Cerium Engine は、これを表示する。


シーングラフ

3D Object の集合が作る木構造

   move()       シーングラフの各ノードの動作
   collsion()   シーングラフの相互作用


move の例

    void
    ball_move(SceneGraphPtr node, int w, int h)
    {
	node->xyz[0] += 4;
    }
    void
    ball_coll(SceneGraphPtr node, int w, int h, SceneGraphPtr tree)
    {
	if (node->xyz[0] > 600) node->remove();
    }


Rendering

シーングラフを画面上に表示する

普通、Open/GL とか GPU とか使うんだけど、

うちでは、

    Cell を使って、ソフトウェアで1dotずつ書く

(一つは教育的配慮。一つはCeriumの例題として)


Polygon の座標の計算

まず、シーングラフから、ポリゴンの座標を計算する


Span

同じ y 座標の直線を取り出す。

光の方向と、Polygon の向き (法線)の情報が必要。


Z Buffer

描画した z 座標を覚えておく

置くにあるものは描画しない


プログラミング

C とか C++ が多いです。

Java 3D を使っても良い。

OpenSceneGraph と言うのが便利。

Open/GL を使って Rendering を行う。

しかし、PS3 では使いにくい。


Real-time Programming

だいたい、メインループがある。

   SceneGraph *scene_graph = make_scene_graph();
   while(running) {
       get_input();
       scene_graph->move();
       scene_graph->collision();
       scene_graph->rendering(display);
   }


PS3 のアーキテクチャ

PS3 には、6個のSPUと、2個のPPUがある。恒常的にSPUを使わないと速くならない。

100%並列化では、実行時間は 1/6

50%並列化すると、1/6*0.5 + 0.5 = 0.58

80%では、 1/6*(0.8)+0.2 = 0.33


動作をタスクに分解する

コピーをパイプラインで隠しながらTaskを実行する。

かなりめんどくさいです。


SIMD 演算

SPU 上では、4 float (4byte x 4) の演算が高速

128bit register が128個もある。


4 x 4 行列

座標は三次元で十分なんだが、平行移動を含むには、4 x 4 行列が便利

斉次行列と呼ばれる。


平行移動


拡大縮小

省略


回転


回転の合成


ポリゴンの頂点と法線ベクトル

ポリゴンは三角形。法線ベクトルは、その三角形に垂直なベクトル。


外積

垂直なベクトルは、外積で計算する。

| ex ey ez |
| Ax Ay Az |
| Bx By Bz |

(A x, Ay, Az)

と、

(B x, By, Bz)

の外積を取ると、

(A y * B z - A z * B y , A z * B x - A x * B z , A x * B y - A x * B y )

となります。大きさが|A|*|B|で、AとBに直交したベクトルになります。

A との内積を取ってみて、直交していることを確認しよう。


内積

ベクトルへの射影を計算します。

A x * B x + A y * B y + A z * B z


衝突判定

法線ベクトルとの射影を取ることによって計算するのが簡単。

距離を使っても良い。


逆行列

回転行列は、θを-θにすれば良い。

回転行列以外の逆行列の計算は繁雑。なるべく使わない。


車の衝突

                        名前 _______________ 学籍番号 ___________

車がコースを走っている。コースの道と、壁を法線ベクトルと、位置ベクトルで表す。車は位置 Cp と速度 Cv を持っている。車の方向は速度と同じ方向だとしよう。

Wn Wp
Rn Rp
Cv Cp

    


問題1 並行移動

Cv = (2,2,1,1)

Cp = (1,1,1,1)

1 clock で、これだけの位置を動くとする。

車をを動かす斉次行列を書き、それを用いて、次の車の位置を計算せよ。

 
 
 
 
 
 
 
  


問題2 回転

車の向きを道に並行に45度回転させたい。この回転を表す斉次行列を作り、車の速度ベクトルを計算せよ。

Rn = (0,0,1,1)

  

sin(45度) = 0.7, cos(45度) = 0.7 として計算することにする。


 
 
 
 
 
 
 
 
 

車の車輪は、1 clock の間にCvと直行した方向に45度回転するとする。

車の車輪の回転を表す行列を前の計算結果を利用して求めよ。


 
 
 
 
 
 
 
 
 


問題3 衝突判定

次の clock で車が壁に衝突するかどうかを判定したい。

Cp+Cv

を計算し、それが壁の向うにあるかどうかを調べる。

法線ベクトルWn = (1,1,0,1)

として、今は衝突してなくて、次のclockで 車が衝突する

Wp

の例を示せ。






問題3 のおまけ

衝突は、正確には1 clock の間で起きる。衝突の起きる時間を解答の例に対して計算せよ。






問題3 のおまけのおまけ

パラメータ表示を使って、条件を満たすすべてのWp を計算せよ。衝突時間をパラメータを使って表せ。