WPFで環境マッピング
WPF 3Dの壁を破ろうシリーズ(?)第3弾です。
WPFではテクスチャ座標のような頂点単位のデータを動的に変更できないので、基本的には環境マッピングはできません。しかし「WPFでモーフィング」や「WPFでスキニング」と同じようにカメラ方向と法線方向から頂点座標データを毎フレーム生成してやれば実現できます。
球状環境マッピングのテクスチャ座標の生成はそれほど難しくありません。u = Nx/2 + 0.5, v = Ny/2 + 0.5(Nx, Nyはビュー空間での法線ベクトル)を頂点座標に書き込むだけです。詳細はDirect3Dのドキュメントを参照してください。ただしこの式は左手座標系なので、WPFの右手座標系に適用するとき少し変更する必要があります。
しかし、現在よく使われているキューブ環境マッピングはこの手法では適用できません。キューブ環境マッピングでは6つのテクスチャを使用し、法線の方向によって立方体(キューブ)のどの面のテクスチャを使うかを変更する必要があるためです。
private void mySceneChanged(object sender, EventArgs e)
{
if (this.IsLoaded)
{
myScene.Children.Clear();
myScene.Children.Add(GetTeapot());
}
}
MeshGeometry3D EditTexCoord(MeshGeometry3D m)
{
Matrix3D c = myScene.Transform.Value;
foreach (Vector3D n in m.Normals)
{
Vector3D nc = Vector3D.Multiply(n, c);
Point uv = new Point(nc.X*0.5+0.5, -nc.Y*0.5+0.5);
m.TextureCoordinates.Add(uv);
}
m.Freeze();
return m;
}
private ModelVisual3D GetTeapot()
{
MeshGeometry3D myMesh = myTeapot.Clone() ;
myMesh = EditTexCoord(myMesh);
GeometryModel3D myGeom = new GeometryModel3D();
myGeom.Geometry = myMesh;
myGeom.Material = new DiffuseMaterial(myBrush);
ModelVisual3D myModel = new ModelVisual3D();
myModel.Content = myGeom;
return myModel;
}

マイクロソフト㈱エバンジェリスト。北海道大学理学部物理学科卒。リアルタイム3Dグラフィックスを専門とし、グラフィックスやシェーダに関する技術文章を執筆・講演。 DirectX SDK日本語ドキュメントの開発に携わるとともに、Windows Presentation Foundation プログラミング(オーム社)、Game Programming Gemsシリーズ、リアルタイム レンダリング第2版(ボーンデジタル)、Texturing & Modeling, A Procedural Approach などを翻訳・監修、XAMLプログラミング(ソフトバンク クリエイティブ)を執筆。趣味は薪割り。