« サブカテゴリー | メイン | RD-XS38(3) 番組ナビ お気に入り »
2006年02月12日
RenderMonkey(2) テクスチャパラメータ
新規にワークスペースを作ってみます。これはとても簡単で、RenderMonkey を立ち上げた後に [Effect Workspace で右クリック] → [Add Default Effect] → [DirectX/OpenGL] でそれぞれ選択が可能です。この雛型を選択するだけでそのまま動作するエフェクトが作成されます。
fig.1 Add Default Effect
例えば Textured Bump を選択します。デフォルト状態ではモデルは Sphere.3ds が選択されています[fig.2(a)]。モデルは前回示したように簡単に変更することができます[fig.2(b)]。
fig.2 (a) モデル変更前
fig.2 (b) モデル変更後
また Vertex Program / Fragment Program も自動的に生成されているので、あとは好きなように編集をすることが可能です。
uniform vec3 fvLightPosition; uniform vec3 fvEyePosition; varying vec2 Texcoord; varying vec3 ViewDirection; varying vec3 LightDirection; attribute vec3 rm_Binormal; attribute vec3 rm_Tangent; void main( void ) { gl_Position = ftransform(); Texcoord = gl_MultiTexCoord0.xy; vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex; vec3 fvViewDirection = fvEyePosition - fvObjectPosition.xyz; vec3 fvLightDirection = fvLightPosition - fvObjectPosition.xyz; vec3 fvNormal = gl_NormalMatrix * gl_Normal; vec3 fvBinormal = gl_NormalMatrix * rm_Binormal; vec3 fvTangent = gl_NormalMatrix * rm_Tangent; ViewDirection.x = dot( fvTangent, fvViewDirection ); ViewDirection.y = dot( fvBinormal, fvViewDirection ); ViewDirection.z = dot( fvNormal, fvViewDirection ); LightDirection.x = dot( fvTangent, fvLightDirection.xyz ); LightDirection.y = dot( fvBinormal, fvLightDirection.xyz ); LightDirection.z = dot( fvNormal, fvLightDirection.xyz ); }
uniform vec4 fvAmbient; uniform vec4 fvSpecular; uniform vec4 fvDiffuse; uniform float fSpecularPower; uniform sampler2D baseMap; uniform sampler2D bumpMap; varying vec2 Texcoord; varying vec3 ViewDirection; varying vec3 LightDirection; void main( void ) { vec3 fvLightDirection = normalize( LightDirection ); vec3 fvNormal = normalize( ( texture2D( bumpMap, Texcoord ).xyz * 2.0 ) - 1.0 ); float fNDotL = dot( fvNormal, fvLightDirection ); vec3 fvReflection = normalize( ( ( 2.0 * fvNormal ) * fNDotL ) - fvLightDirection ); vec3 fvViewDirection = normalize( ViewDirection ); float fRDotV = max( 0.0, dot( fvReflection, fvViewDirection ) ); vec4 fvBaseColor = texture2D( baseMap, Texcoord ); vec4 fvTotalAmbient = fvAmbient * fvBaseColor; vec4 fvTotalDiffuse = fvDiffuse * fNDotL * fvBaseColor; vec4 fvTotalSpecular = fvSpecular * ( pow( fRDotV, fSpecularPower ) ); gl_FragColor = ( fvTotalAmbient + fvTotalDiffuse + fvTotalSpecular ); }
これだけでも shader プログラムの取り掛かりとしては非常に敷居が低くなっています。
RenderMonkey 以外にも shader プログラムのコードを自動生成してくるソフトとし ShaderGen があります[fig.5]。このソフトは OpenGL の固定機能を OpenGL Shading Language に置き換えてくれるもので、従来の OpenGL の固定機能を知っている人が shader プログラムを始める場合には有用なソフトだと思います。
fig.5 ShaderGen 3.0
さてここまでは前フリで、今回は基本となるテクスチャの扱いを簡単にまとめます。ワークスペースは新規に Screen-Aligned Quad を選択します[fig.6]。
fig.6 Screen-Aligned Quad
ここでテクスチャを base.tga から ati.tga に変更します。これはテクスチャの向きを確認するためです。base.tga から ati.tga に変更するとテクスチャの向きが上下が逆になっていることがわかります。これを直す方法はいろいろとありますが、ここでは Vertex Program を変更します。
varying vec2 texCoord; void main(void) { gl_Position = vec4( gl_Vertex.xy, 0.0, 1.0 ); gl_Position = sign( gl_Position ); // Texture coordinate for screen aligned (in correct range): // texCoord = (vec2( gl_Position.x, - gl_Position.y ) + vec2( 1.0 ) ) / vec2( 2.0 ); texCoord = (vec2( gl_Position.x, gl_Position.y ) + vec2( 1.0 ) ) / vec2( 2.0 ); }
また、これだけでは何なので Fragment Program も変更してみます。
uniform sampler2D Texture0; varying vec2 texCoord; void main(void) { // gl_FragColor = texture2D( Texture0, texCoord ); gl_FragColor = texture2D( Texture0, texCoord*2.0 ); }
ここまでの変更で fig.9 の状態になっているはずです。
fig.9 texture, Vertex Program, Fragment Program 変更
さてここからが本題で、今回注目するのは Texture Parameter です。これは Texture0 をダブルクリックかマウス右クリックで Edit を選択します[fig.10]。
fig.10 Texture State Editor の選択
ここでは glTexParam{i|f|v}, glTexEnv{i|f|v} に関連するパラメータの設定を行うことができます。デフォルトでは GL_TextureMinify = GL_LINEAR_MIPMAP_LINEAR, GL_TextureMagnify = GL_LINEAR が設定されています[fig.11]。
fig.11 Texture State Editor デフォルト値
さてここで Fragment Program に戻り、以下の様に編集してみます[fig.12]。
uniform sampler2D Texture0; varying vec2 texCoord; void main(void) { // gl_FragColor = texture2D( Texture0, texCoord ); gl_FragColor = texture2D( Texture0, fract(texCoord*2.0) ); }
この変更を行うと表示されているテクスチャの中央にスジが入るのが確認できると思います[fig.13]。
fig.13 スジが現れた状態
最初に RenderMonkey を使ったとき、何故テクスチャ座標の算出に fract, floor などを使うとこのスジが現れるのかがわかりませんでした。そのときにはまだ Texture State Editor の出し方がわからなかったため RenderMonkey のバグかとも思いましたが、実際にはこれは GL_TextureMinify が影響しています。というわけで Texture State Editor に戻り GL_TextureMinify を GL_LINEAR に変更します[fig.14]。
fig.14 GL_TextureMinify の変更
この変更により GL_LINEAR_MIPMAP_LINEAR の効果は得られなくなりますがテスクチャのスジは消せます。MIPMAP 画像が見れないので RenderMonkey がどんな MIPMAP を生成しているか謎ですが、うまく MIPMAP のレベル調整ができれば実際のプログラム上では問題はないでしょう。
私はこの問題にはまり「RenderMonkey の fract, floor ってバグってる?」と思いいろいろと検索をしてしました。結果的に web 上では情報が見つからなかったのですが、この問題のおかげでちょっとは RenderMonkey に慣れることができたな、と思います。
また、これ以外のパラメータも変更してみて下さい。特に fract を外して GL_TextureWrap{S|T|R} を変更すると普通に REPEAT/CLAMP 系の動作を確認することができます。
投稿者 napier : 2006年02月12日 19:08
トラックバック
このエントリーのトラックバックURL:
http://will.squares.net/mt/mt-modified-tb.cgi/283