#region OpenTK

OpenTKがGitHubで更新されるようになりました。NuGetから手に入れることができるようになりました。
現在は.NET Coreに対応する機運があるようです。

テクスチャをポリゴンに貼る

テクスチャとは

テクスチャ(Texture)の意味は、表面の質感や手触りを指す概念のようです(Wikipediaより)。3DCGでも、意味通りに質感を表現することに使います。

物体の模様の表現など、ゲームなどでは必ずと言っていいほど使われている技術です。

テクスチャで広がる可能性

模様の表現に使われるテクスチャですが、実際にはテクスチャはさまざまな用途に用いられます。

通常のテクスチャにはRGBAの色情報が格納されていることが多いのですが、これに法線情報と高さ情報を格納してライティングで使用することで、表面のざらつきや凸凹を表現することができます。

さらに、テクスチャに物体周辺の景色を格納してライティングでそれを参照することで、ガラスによる屈折や金属による反射を表現することができます。

また、テクスチャが受け渡すことができる量が大きいことを利用して、汎用のデータコンテナとして利用することもあります。

テクスチャの技術は、3DCGのいたるところに用いられています。

まずは使い方を覚えましょう

Show Texture
これでもポリゴンは一枚です

ソースコードは、テクスチャを扱うための最低限のコードにしています(カメラ操作除く)。

		//ウィンドウの起動時に実行される。
		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);

			GL.ClearColor(Color4.Gray);

			GL.Enable(EnableCap.Texture2D);

			//テクスチャ用バッファの生成
			texture = GL.GenTexture();

			//テクスチャ用バッファのひもづけ
			GL.BindTexture(TextureTarget.Texture2D, texture);

			//テクスチャの設定
			GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
			GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);

			//テクスチャの色情報を作成
			int size = 8;
			float[, ,] colors = new float[size, size, 4];
			for (int i = 0; i < colors.GetLength(0); i++)
			{
				for (int j = 0; j < colors.GetLength(1); j++)
				{
					colors[i, j, 0] = (float)i / size;
					colors[i, j, 1] = (float)j / size;
					colors[i, j, 2] = 0.0f;
					colors[i, j, 3] = 1.0f;
				}
			}
			
			//テクスチャ用バッファに色情報を流し込む
			GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, size, size, 0, PixelFormat.Rgba, PixelType.Float, colors);
		}

テクスチャの利用手順はVBOのそれと似ていて、最初にテクスチャの使用を許可します(128行目)。

次にGenTetureでテクスチャを格納する領域を確保して、識別番号を取っておきます(131行目)。

テクスチャに対して操作を行うときは、BindTextureで対象のテクスチャをひも付けをしてから行います(134行目)。ここでは、2次元のテクスチャとしてひも付けしていますが、対象ごとに違うテクスチャをひも付けしておけます。

137行目と138行目はテクスチャの設定なのですが、ここではテクスチャ拡大や縮小したときにどう扱うかを指定します。テクスチャ設定の中でもこれは必須の設定です。とりあえずはこれが必要だと言うことだけ覚えておいてください。

色情報の生成については特に書きませんが、多くの場合は画像(または画像化したデータ)を外部ファイルから読み込んで使います。そして、TexImage2Dで対象のテクスチャに情報を流し込みます(155行目)。

		//ウィンドウの終了時に実行される。
		protected override void OnUnload(EventArgs e)
		{
			base.OnUnload(e);

			//使用したテクスチャを削除
			GL.DeleteTexture(texture);
		}

VBOと同じように、終了時はテクスチャを格納する領域を削除します。

			//ポリゴン表示
			GL.Color4(Color4.White);

			GL.Begin(BeginMode.Quads);

			GL.TexCoord2(1.0, 1.0);
			GL.Vertex3(1, 1, 0);

			GL.TexCoord2(0.0, 1.0);
			GL.Vertex3(-1, 1, 0);

			GL.TexCoord2(0.0, 0.0);
			GL.Vertex3(-1, -1, 0);

			GL.TexCoord2(1.0, 0.0);
			GL.Vertex3(1, -1, 0);

			GL.End();

ここはポリゴンを一つ描画している単純なコードです。

テクスチャをポリゴンに対して適応する場合、TexCoord?を用います(今回は2次元テクスチャのためTexCoord2)。TexCoordで指定する数字は、頂点に対応するテクスチャ座標です。ちょうど色を指定したのと同じように、頂点に属性を持たせます。

テクスチャの座標

さて、テクスチャの座標とは何でしょうか。

Texture Coordinate
2次元の場合s軸とt軸

テクスチャの座標は上のように1.0四方の正方形の中に圧縮されて入っています。TexCoordではこの座標を指定します。

指定する場合は0.0から1.0以外の値でもよくて、はみ出している場所は指定した方法で補完されます(テクスチャの繰り返しや、終端の色で塗りつぶすなど)。

もちろん、すべての領域を使わなければいけないわけでもありませんし、複数のポリゴンに適応しても構いません。歪んでいても大丈夫です。

また、両面表示する場合は裏側にも適応されています。表裏の同じ位置なら同じ色です。

OutOfRangeSmallMultiPolygonWarp

記事

外部リンク

Thanks