プログラミング演習3 李 亜民クラス 第2回 ラスタライズ 今回の内容 概念説明 作業 ラスタライズ scan/span クラスの穴埋め 課題について 概念説明 ラスタライズ scan/span 3Dグラフィックスパイプライン ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ 本日は⑥について解説 3Dモデル構築 モデル変換 バーテックス処理 ビューポート変換 バックフェースカリング ラスタライズ ピクセルシェーディング Zバッファの適用 :第3回 :第1回 :第4回 :第1回 :第3回 :第2回 :第4回 :第3回 ラスタライズ ポリゴン(ベクトル集合)→ピクセル集合の変換を行う 各ピクセルに座標、色、材質等のパラメータを割り当て、ピク セルシェーダに渡す この講義では、ポリゴンは3つの頂点で構成されるものとする ラスタライズは、各ポリゴンについて処理を行う ラスタライズの流れ(1)データ取得 ラスタライザに頂点データが渡される ラスタライズの流れ(2)バッファ初期化 右/左端バッファを用意し、それぞれを大きい/小さい値で初期化 左をInteger.MAX_VALUE、右をMIN等(∞である必要は無い) ラスタライズの流れ(3)Scan(1辺目) y方向に補間してバッファに格納 右端はバッファ値より大きいこと、左端は小さいことを条件に上書き ラスタライズの流れ(4)Scan( 2辺目) 書き込み条件を考慮しつつ同様に繰り返し ラスタライズの流れ(5)Scan( 3辺目) 直線の描画と異なり、単純にy軸について補間すれば良い x座標は飛び飛びになりうる ラスタライズの流れ(5)Span LBuffからRBuffまでx軸方向に補間 補間されて得られたピクセルをピクセルシェーダに送信 本日は、ここで得られた座標をそのまま単色で塗りつぶす Scan:エッジ方向補間 指定された辺について保管し、左右バッファに格納 Scan(v1, v2, LBuff[], RBuff[]) // 繰り返し方向確認 if (v1.y > v2.y) swap(v1, v2) // 水平なら描画しない if (v1.y == v2.y) return // 補間 for y = v1.y to v2.y Pixel p = lerp(…) if (…) LBuff[p.y] = p if (…) RBuff[p.y] = p 擬似コード通りである必要はない。各自工夫を! Span:x軸方向補間 左右にバッファを用意し、各エッジ(辺)ごとに補間 Span(LBuff[], RBuff[]) // 補間 for y = 0 to Screen Height // 面が存在するか確認し、無ければスキップ if RBuff[y].x <= LBuff[y].x continue Pixel p = lerp(…); pを塗りつぶし ラスタライズに関する注意 左右バッファは面ごとに初期化し直す必要がある for each face バッファ初期化 Scan(A, B) Scan(B, C) Scan(C, A) Span(LBuff, RBuff) 上書きの条件や初期化する値など、左右のバッファで処 理が異なる部分をよく確認すること 作業 クラスの穴埋め Vertexクラス(未完成) メンバ変数 コンストラクタ Vector v : 変換後座標 Vector ov : 変換前座標 変換前x,y,z指定 (任意に追加して下さい) メソッド Pixel lerp(…) 線形補間(未完成) Vector.lerp(…)同様、x,y,zそれぞれについて補間すれば良い 補間して以後、変換前座標は不要なので、返り値はPixelに Faceクラス メンバ変数 コンストラクタ Vertex A,B,C (頂点) Vertex3つで指定 メソッド 特になし(追加は任意で) Pixelクラス(未完成) メンバ変数 コンストラクタ int x, y, z : 座標 double型x, y, z指定(Math.roundでint型に) メソッド Pixel lerp(…) 線形補間(未完成) Vertex.lerp(…)同様 第2回課題 1. 任意の三角形を作成し、単色で塗りつぶして下さい クラス:lec02に記述 initに初期化処理を記述 render(), drawFace(),scan(),span()の穴埋め その他、任意にメソッドを追加(setTriangle()等) 2. [発展] ダブルバッファリングを実装して下さい。 Canvasクラスを改変 バッファを用意し、drawPointではバッファに書き込み 書き込み完了後、drawImage(…)でバッファを表示 詳しい方法については、各自で調べる等してください ダブルバッファリング(Canvasを改変) // インスタンス変数宣言 public void paint (Graphics g){ Image buf; // バッファをクリア Graphics bufG; bufG.clearRect(0,0,700,700); // レンダリング render(); public void init (){ … // バッファから一気に描画 // バッファの初期化処理を追加 g.drawImage(buf,0,0, this); buf = createImage(700,700); } bufG = buf.getGraphics(); } public void drawPoint (…){ // バッファに描画するように変更 bufG.setColor(c); bufG.drawLine(x,y,x,y) } 課題の実行例
© Copyright 2024 ExpyDoc