サンプル9


  今回は、前回の続きという感じで、ミップマップについての話です。今回も、ppmread.c、ppmread.h、texture2.ppmが必要です。


目次

ミップマップとは

  まず、今回のプログラムを実行した結果を見てみます。

Mipmap

  右側が普通にテクスチャマップしたもので、左側がミップマップを使ったものです。これを見ると、単にテクスチャを拡大/縮小して張り付けると、縮小された場合に、不自然になります。今回は、静止画なのであまり気にならないかも知れませんが、動画の場合この部分がチラチラして、結構目立ちます。
 

いい加減に縮小
ちゃんと縮小
1/2したものを2倍
1/4したものを4倍

  普通にテクスチャマップすると、上の表の左の列のように縮小されます。1/4にした時点でかなり崩れています。それに対し、右の列では、1/4でもまだ何とか数字を読める程度に形が残っています。ミップマップでは、右の列の様な縮小の仕方をするのですが、これをリアルタイムにやっていると処理がとっても重くなってしまいます。そこで、ミップマップの場合は、あらかじめ元のテクスチャの1/2、1/4、1/8・・・の大きさのテクスチャを持っていて、それを張り付けることによって、縮小部がチラチラするという問題を解決しています。


ミップマップを使う場所

  上で解説したように、ミップマップを使うと、テクスチャを張ったときの不自然さを解消してくれます。しかし、ミップマップをすると、普通のテクスチャマップよりも処理が重くなります。さらに、元のテクスチャ以外に、縮小したテクスチャを持つため、メモリも余分に使います。ですから、ミップマップを使わなくていい場所は、極力使わない方が(特にゲームを作ったりするときは)良いと思います。少くとも、次のような場合は、ミップマップは不要でしょう。

縮小されることがないとき

  ミップマップは当然、不要ですね。どんなときかと言えば、テクスチャを張ったポリゴンが視点から遠くに行かない場合です。たとえば、ゲームの自分のキャラクタなどです。普通、常に手前に大きく表示されていますよね。
地味なテクスチャを張るとき
  テクスチャの模様によっても、ミップマップは不要です。例えば、草地を表現するようなテクスチャの場合を見てみます。
 
 
元のテクスチャ
1/8して8倍

  このように、似たような色だけのテクスチャは、いい加減に縮小してもそんなに不自然にはなりません。このような場合も、ミップマップは不要です。


サンプルプログラム

  では、サンプルプログラムを見て、実際にどうやってミップマップを使うか見てみましょう。
    ミップマップを使うためには、ミップマップとはで解説したように、1/2、1/4、1/8・・・に縮小したテクスチャを作る必要があります。ただ、ちゃんと縮小するとなると、フーリエ変換などが必要になり、はっきり言ってめんどくさいわけです。でも、OpenGLでは、GLUライブラリの中に、ミップマップをつくってくれる便利な関数がいます。それが、ppmread.cのReadPPMMipmap()の中で使われている、gluBuild2DMipmaps()です。

GLint gluBuild2DMipmaps(GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data)

  glTexImage2D()と似ていて、glTexImage2D()から、levelとborderが無くなっただけです。他の引数は同じなので、解説は、サンプル8を読んでください。
それから、他に違うのは、glTexParami()の設定です。

void glTexParameteri(GLenum target, GLenum pname, GLint param)

  ミップマップを使わないときは、pnameがGL_TEXTURE_MIN_FILTERのとき、paramにGL_NEARESTかGL_LINEARを渡しましたが、ミップマップをするときは、GL_NEAREST_MIPMAP_NEAREST、GL_LINEAR_MIPMAP_NEAREST、GL_NEAREST_MIPMAP_LINEAR、GL_LINEAR_MIPMAP_LINEARのいずれかを渡します。最初のNEAREST/LINEARは、GL_NEAREST/GL_LINEARと同じで、テクスチャのピクセル間の補完の方法です。最後のNEAREST/LINEARは、ミップマップの場合は1/2、1/4・・・に縮小されたテクスチャが何枚もあると言いましたが、1/2と1/4のテクスチャの間、1/4と1/8のテクスチャの間・・・の補完です。もちろん、GL_LINEAR_MIPMAP_LINEARが一番きれいな絵になりますが、一番処理が重くなります。

戻る