トップページ > 過去ログ > 記事閲覧
画像の乱れについて
名前:pmt 日時: 2012/08/09 22:57

自分の環境の問題かもと思いましたが判断がつかないのでよければ確認お願いします。 DrawBillboard3D()等でPNG画像を表示した際、画像に乱れが出ています。 参考(表示結果をキャプチャしたもの) http://db.tt/dw9JSdv5 元画像 http://db.tt/buZquhUX 右上隅あたりの横線が3箇所欠けています。ちょうど画像の対角線上あたりに並んでいるようです。 ソースは以下になります。 #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { SetGraphMode( 1280 , 720, 32 ) ; ChangeWindowMode( true) ; if( DxLib_Init() == -1 ) // DXライブラリ初期化処理 { return -1; // エラーが起きたら直ちに終了 } int hBG = LoadGraph( "64x64.png" ); int hScreen = MakeScreen( 1280, 720, true) ; SetDrawScreen( hScreen ) ; DrawBillboard3D( VGet( 0.0f, 0.0f, 0.0f ), 0.0f, 0.0f, 1280.0f, 0.0f, hBG, false ) ; SetDrawScreen( DX_SCREEN_BACK ) ; DrawGraph( 0, 0, hScreen, false ) ; ScreenFlip() ; WaitKey() ; // キーの入力待ち((7-3)『WaitKey』を使用) DxLib_End() ; // DXライブラリ使用の終了処理 return 0 ; // ソフトの終了 } 実際に作業しているコードではより顕著に症状が現れており 画面の対角線を境に右下半分の表示だけがかなり乱れます。 MakeScreen()のサイズを適当に±1とかしてみると乱れが収まったりするのですが理屈はよく分かりません。 あと、左端と右上1ラインがダブって表示されているのは3D表示上の仕様でしょうか?

Page: 1 |

Re: 画像の乱れについて ( No.1 )
名前:いっち 日時:2012/08/10 00:57

私の環境でも完全な状態で表示されませんが、 3Dの世界では誤差は当たり前なのでこんなものかなというふうに感じました。 ただ、以下のようにZ座標を少しいじると良い感じになったので、特定の値で何らかの問題があるのかもしれません。 > DrawBillboard3D( VGet( 0.0f, 0.0f, 0.0f ), 0.0f, 0.0f, 1280.0f, 0.0f, hBG, false ) ; ↓↓↓↓ > DrawBillboard3D( VGet( 0.0f, 0.0f, 0.01f ), 0.0f, 0.0f, 1280.0f, 0.0f, hBG, false ) ;
Re: 画像の乱れについて ( No.2 )
名前:pmt 日時:2012/08/11 16:00

いっちさん、ありがとうございます。 DrawBillboard3D()についてはその対処法でなんとか凌げそうです。 ちなみに自環境では-0.01fあたりで丁度いい感じに表示出来るようです。 同様に実際の作業中のコードでも試してみたのですが、こちらはうまくいきませんでした。 要点をまとめたコードは以下になります。 参考 http://db.tt/cjMTtcKQ 元画像 http://db.tt/kAbLgWNP #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { SetGraphMode( 1280 , 720, 32 ) ; ChangeWindowMode( true) ; if( DxLib_Init() == -1 ) {return -1; } int hBG = LoadGraph( "test1280.png" ); int pshandle = LoadPixelShader( "SamplePS.pso" ) ; int hScreen = MakeScreen( 1280, 720, true) ; VERTEX2DSHADER Vert[ 6 ] ; SetUseTextureToShader( 0, hScreen ) ; SetUsePixelShader( pshandle ) ; float vw = 1280.0f; float vh = 720.0f; float vz = 0.0f; Vert[ 0 ].pos = VGet( 0.0f, 0.0f, vz ) ; Vert[ 0 ].rhw = 1.0f ; Vert[ 0 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 0 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 0 ].u = 0.0f ; Vert[ 0 ].v = 0.0f ; Vert[ 0 ].su = 0.0f ; Vert[ 0 ].sv = 0.0f ; Vert[ 1 ].pos = VGet( vw, 0.0f, vz) ; Vert[ 1 ].rhw = 1.0f ; Vert[ 1 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 1 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 1 ].u = 1.0f ; Vert[ 1 ].v = 0.0f ; Vert[ 1 ].su = 1.0f ; Vert[ 1 ].sv = 0.0f ; Vert[ 2 ].pos = VGet( 0.0f, vh, vz ) ; Vert[ 2 ].rhw = 1.0f ; Vert[ 2 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 2 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 2 ].u = 0.0f ; Vert[ 2 ].v = 1.0f ; Vert[ 2 ].su = 0.0f ; Vert[ 2 ].sv = 1.0f ; Vert[ 3 ].pos = VGet( vw, vh, vz ) ; Vert[ 3 ].rhw = 1.0f ; Vert[ 3 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 3 ].spc = GetColorU8( 0, 0, 0, 0 ) ; Vert[ 3 ].u = 1.0f ; Vert[ 3 ].v = 1.0f ; Vert[ 3 ].su = 1.0f ; Vert[ 3 ].sv = 1.0f ; Vert[ 4 ] = Vert[ 2 ]; Vert[ 5 ] = Vert[ 1 ]; SetDrawScreen( hScreen ) ; DrawBillboard3D( VGet( 0.0f, 0.0f, -0.01f ), 0.0f, 0.0f, 1280.0f, 0.0f, hBG, false ) ; SetDrawScreen( DX_SCREEN_BACK ) ; DrawPolygon2DToShader( Vert, 2 ) ; ScreenFlip() ; WaitKey() ; // キーの入力待ち((7-3)『WaitKey』を使用) DxLib_End() ; // DXライブラリ使用の終了処理 return 0 ; // ソフトの終了 } SamplePS.psoはDXライブラリの\Tool\ShaderCompiler\Sampleと同じものです。
Re: 画像の乱れについて ( No.3 )
名前:いっち 日時:2012/08/12 01:12

(No.2)のコードを拝見しましたが、やはりこんなものかなという感想です。 その他に感じた雑感です。 ・描画の前に SetDrawMode を DX_DRAWMODE_BILINEAR に設定すれば症状は緩和されると思います ・DrawBillboard3D を行わずに直接テクスチャとして渡すか、DrawGraph の方が良いと思います ・デフォルトのカメラ設定で希望通りの描画結果が得られる根拠があるのでしょうか? 管理人さん> シェーダーに渡すテクスチャのサイズとuv座標についてちょっと違和感を覚えたので GetGraphTextureSize で hScreen のサイズを調べてみたところ 1280x720 でした。 私の認識では自動的に2の乗数に調整されるものと思っていたのですが、MakeScreen では調整が行われないのでしょうか? 調整が行われないとしたら、それは全ての環境でその様な挙動になるのでしょうか? (Ver3.05e以前のDXライブラリではそのように調整されているようでした。) また、シェーダーに渡すテクスチャのサイズは2の乗数である必要は無いのでしょうか? //-- 以下、テストコード ("BlendGraph.bmp"を使用)--// #include "DxLib.h" int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) { ChangeWindowMode( TRUE ); SetWindowText( "DxLib:" DXLIB_VERSION_STR ); if ( DxLib_Init( ) == -1 ) return -1; int white = GetColor( 255, 255, 255 ); SetUseDivGraphFlag( FALSE ); int gh[3]; gh[0] = LoadGraph( "BlendGraph.bmp" ); gh[1] = MakeGraph( 640, 480 ); gh[2] = MakeScreen( 640, 480 ); int x[3],y[3],u[3],v[3]; for ( int i = 0; i < 3; i++ ) { GetGraphSize( gh[i], x+i, y+i ); GetGraphTextureSize( gh[i], u+i, v+i ); } SetDrawScreen( DX_SCREEN_BACK ); while ( ProcessMessage( ) == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) { ClearDrawScreen( ); for ( int i = 0; i < 3; i++ ) DrawFormatString( 0, i*20, white, "gh[%d]:%d:%d:%d:%d", i, x[i], y[i], u[i], v[i] ); ScreenFlip( ); } DxLib_End( ); return 0; }
Re: 画像の乱れについて ( No.4 )
名前:pmt 日時:2012/08/12 07:07

いっちさん度々ありがとうございます。 >(No.2)のコードを拝見しましたが、やはりこんなものかなという感想です。 すると不具合の可能性は薄いということになりますね。 念の為に補足ですが上のコードで問題が出ているのはDrawPolygon2DToShader()です。 説明が不足してたらすいません。 DrawPolygon2DToShader()については何か対処法などあるでしょうか? DX_DRAWMODE_BILINEARについてはその為にDrawBillboard3D()を選択している様な ところがあるので最終的には必要なところで使用していく予定です。 >デフォルトのカメラ設定で希望通りの描画結果が得られる根拠があるのでしょうか? 質問がよくわかりませんが、実際に作業しているコードには一応カメラ設定などもあります。 何分知識不足なので穴はあるかもしれません。 例として上げているコードは症状が再現出来るだけのものということで こちらで検証して無関係だった処理は極力省いたとお考えください。
Re: 画像の乱れについて ( No.5 )
名前:管理人 日時:2012/08/12 08:23

私もいっちさんと同じく3Dの計算誤差が歪みを生み出しているのかと思いましたが、 歪みが発生している描画は DrawPolygon2DToShader だったのですね、手元でも確認できました 解決方法は簡単で、DrawPolygon2DToShader の座標を設定している箇所の、xとyすべてに対して 0.5f を引くと正常な描画結果が得られます ↓本当にそのまま、ただ引くだけです Vert[ 0 ].pos = VGet( 0.0f - 0.5f, 0.0f - 0.5f, vz ) ; Vert[ 1 ].pos = VGet( vw - 0.5f, 0.0f - 0.5f, vz ) ; Vert[ 2 ].pos = VGet( 0.0f - 0.5f, vh - 0.5f, vz ) ; Vert[ 3 ].pos = VGet( vw - 0.5f, vh - 0.5f, vz ) ; この 0.5f を引くと何故正常に描画されるのかについては頂点のスクリーン座標とテクスチャ座標から どのように実際の画像内のドットが参照されるのかが関係しているのですが、 説明すると長くなってしまうのでご興味がありましたら microsoft のこちらのページをご覧になってください <最近点サンプリング> http://msdn.microsoft.com/ja-jp/library/cc373044.aspx > いっちさん 描画可能画像を作成する際にグラフィックスデバイスが対応している場合は2のn乗ではない解像度で テクスチャを作成するようになっています 2のn乗以外のサイズのテクスチャの作成にグラフィックスデバイスが対応しているかどうかが問題なので、 作成できた場合はシェーダーで使用するテクスチャが2のn乗になっていなくても問題ありません
Re: 画像の乱れについて ( No.6 )
名前:pmt(解決) 日時:2012/08/12 22:33

管理人さん、おかげさまで納得行く結果が得られるようになりました。 原因もわかって適切に対処できたので助かります。 ありがとうございました。
Re: 画像の乱れについて ( No.7 )
名前:いっち 日時:2012/08/16 19:11

管理人さん> > 描画可能画像を作成する際にグラフィックスデバイスが対応している場合は2のn乗ではない解像度で > テクスチャを作成するようになっています なるほど。ちなみにどの程度のグラフィックスデバイスであれば対応しているかお分かりになりますでしょうか?
Re: 画像の乱れについて ( No.8 )
名前:管理人 日時:2012/08/19 23:35

GeForce2 MX400 などの辺りから対応しているみたいです ( Intelのチップセットでも 2002年頃に登場したものから対応しているようです ) ただ、完全に 2の n乗サイズのテクスチャと同等の扱いができるのは GeForce6シリーズくらいからで、 GeForce6 より前のチップやオンボードチップのグラフィック機能などでは制限付きでの対応となっているようです ( 「テクスチャのループ貼りが使えない」や「圧縮テクスチャフォーマットである DXT が使えない」など )
Re: 画像の乱れについて ( No.9 )
名前:いっち 日時:2012/08/24 00:34

管理人さん> 情報ありがとうございます。 現行の仕様で問題があるわけではなく単なる好奇心なのですが、 LoadGraph や MakeGraph で作られたテクスチャのサイズが MakeScreen と違い2の累乗数になるのは何か理由があるのでしょうか? (おそらく MakeGraph は LoadGraph に仕様を合わせているということなのだと思いますが)
Re: 画像の乱れについて ( No.10 )
名前:管理人 日時:2012/08/26 00:00

LoadGraph の仕様に合わせているというよりは描画可能画像だけ例外的に 2 の n乗ではない画像を使用している、という感じです 2 の n乗ではないテクスチャも 2 の n乗のテクスチャと全く同じように扱えるデバイスが一般的になったらすべてのテクスチャを 2 の n乗ではないテクスチャにする予定です( あと10年くらい掛かりそうですが・・・ )
Re: 画像の乱れについて ( No.11 )
名前:いっち(解決) 日時:2012/08/27 21:05

回答ありがとうございます。 単純に必要なHWレベルの問題なのですね。 納得しました。

Page: 1 |