コンピュータグラフィックス 実習3: 光線追跡法 コンピュータグラフィックス 実習3: 光線追跡法 1 目的: 球面を対象とした光線追跡プログラムを作成し、3次元画像生成の理解を深める。 2 利用する関数: RayTraceSubクラスなどに以下のメソッドを用意している。 (1)double lambert(double ll[], double nn[], double L, double amb, double rho); 光源方向の単位ベクトルll、法線方向の単位ベクトルnn、光源の強さL、環境光の強さamb、 反射率rhoを与えると明るさを返す(図を参照)。 (2) double int_sphere(double cc[], double r, double ss[], double ee[], double x_int[], double n_int[]); 球の中心座標cc, 半径r, 視線方向の単位ベクトルss, 視点の位置eeを与えると、交点の位置 x_int, 交点での単位法線ベクトルn_intを詰め、t値を返す。t<0の場合は交点がない。 (3) double get_tex(BufferedImage *bimg_tex, int nx_tex, int ny_tex, double n_int[]); テクスチャ画bimg_tex, テクスチャ画像のサイズnx_tex, ny_tex, 交点の法線ベクトルn_int からテクスチャ値を返す。詳細は後述する。 (4)int load_tex(char *fname); // ExpRay2, ExpMyRay内 JPEG画像ファイル名fnameを与えると、読み込み、テクスチャ画像bimg_texに入れ、サイズを *p_width, *p_height につめる。ファイルがない場合には0を、成功した場合は1を返す。 (5)void draw_point(int ix, int iy, int intensity) // ExpRay*, ExpMyRay内 画素(ix,iy)の明るさをintensityと設定する(グレースケール)。 3 作成プログラム1:光線追跡 準備: http://www.cg.is.sci.toho-u.ac.jp/zukei/jikken3内のファイルをダウンロードする。 機能: 2つの球に対して、完全拡散反射モデルを用いた画像生成を行う。画素値の計算にはRT.lambert(…)を、 交点の計算にはRT.int_sphere(…)を利用する。ソースのファイル名はExpRay1.java。appletviewerで動作を 確認する。画像は白黒である。 幾何配置: Q1、Q2の中心を (30,30,256), (-30,-30,512),半径を90, 180とする。 画素数をnx×ny (実際は512*512)、焦点距離d=128、視点eeを原点、視軸をz軸に取る(図を参照)。 画像の原点は画面の中心(ix=nx/2, iy=ny/2)にとる。 反射特性: 光源の強度L = 196,方向llを(0.3,0.5,-1.0)正規化したもの、 環境光amb = 64,反射率 rho= 0.8とする。 Tips: ・球の中心座標は、 double cc[][] = new double [2][3], r[] = new double[2]; など配列にするとfor ループで処理しやすい。 ・画素(ix,iy) の3次元座標は、原点が(nx/2,ny/2,d)にあるので、 xs = (ix-nx/2, iy-ny/2, d) である。 ・画像キャプチャはAlt+Print で。 ・メンバーに RayTraceSub RT を設定しているので、このクラスのメソッドは RT.lambert(…)などで呼べる。 ・画素値の設定は、draw_point(ix,iy, intensity); で。
4 作成プログラム2: テクスチャマッピング 機能: テクスチャ画像(例えば、toho.jpgなど) を読み込み、球面に貼り付ける。 幾何配置、反射特性は前章と同じ。ソースのファイル名はExpRay2.java. テクスチャ関数: get_tex(…)を用いてテクスチャ値を求める。ここでは、交点の法線(中心から見た交点の方向)のx、y座標により テクスチャ値を決めている。(z方向に画像を投影する処理になっている。) Tips: ・テクスチャ画像の読み込みは、 load_tex(“toho.jpg”); などにより行う。 ・テクスチャ値に基づき反射率rho_texを変動させることで、テクスチャマッピングが実現できる。例えば、 double rho = 0.8; double rho_tex, ratio; ……… ratio = RT.get_tex( bimg_tex, nx_tex, ny_tex, n_int[]); rho_tex = rho * ratio; intensity = lambert( ll, ss, L, amb, rho_tex); などで実現できる。 5 報告事項 (1)ExpRay1.java, ExpRay2.javaのraytrace()のソースコードと処理結果画像のハードコピー。 (2)考察:何に関してでもよい。 6 報告期限: 2週間後、コンピュータグラフィックス授業開始時まで。 7 発展課題 拡散反射および交点計算のメソッド double my_lambert(double ll[], double ss[], double L, double amb, double rho) ; double my_int_sphere(double cc[], double r, double ss[], double ee[], double x_int[], double n_int[]); をExpMyRayクラスに作成し、これを用いたrattrace()をExpMyRay.javaを作成せよ。 ee screen x y z d Q1 Q2 n_int x_int ll ss