トップページ > 記事閲覧
きれいな画像変形縮小描画
名前:8127 日時: 2019/08/14 22:32

お世話になっています。 単刀直入にですが、 ・2000x2000pixくらいの人物の画像(髪の毛の線など細かい部分を含む)を800x600くらいの画面に DrawPolygonIndexed2D()を使い変形させながら描画したい です。 ですが、普通に組むと細かい部分がジャギってしまいます。 (おそらく普通のDrawExtendGraphなどでも起こる現象であるが、画像が変形していると特に目立つ) SetDrawMode(DX_DRAWMODE_BILINEAR)は、拡大処理の時しか効かない?ようで、特に変化はありませんでした。 workaroundとして、800x600の倍のサイズのスクリーンを用意して一度そこに倍サイズで描画し、 後でGraphFilterBlt(DX_GRAPH_FILTER_DOWN_SCALE)できれいに縮小する手も試しましたが、 すさまじく重くなってしまい断念しました。 ※出力先のグラフィックハンドルは「SetDrawScreen で描画対象にできるグラフィックハンドル」です。 ※PCはdynabook satellite(2010年発売)でおそらくシェーダーモデル2.0は使えるとは思います workaroundでよいので、どなたかよい方法をご存知の方はいらっしゃらないでしょうか。
メンテ

Page: 1 |

Re: きれいな画像変形縮小描画 ( No.1 )
名前:管理人 日時:2019/08/16 02:15

バイニリア補間( DX_DRAWMODE_BILINEAR )で綺麗に縮小できるのはアルゴリズム上2分の1サイズまでなので、 2000x2000pixの画像の場合1000x1000pix以下に縮小するとジャギが発生します ただ、3Dモデルのテクスチャを読み込むための関数 MV1LoadTexture で画像を読み込むとミップマップ付きの テクスチャとなるので、SetDrawMode(DX_DRAWMODE_BILINEAR);を実行した状態では1000x1000pix以下に縮小描画しても ジャギが発生しなくなります // 3Dモデルに貼り付けるのに向いた画像の読み込み方式で画像を読み込む // ( 戻り値 -1:エラー 0以上:グラフィックハンドル ) int MV1LoadTexture( char *FilePath ) ; ただし、制約として2のn乗のサイズ( 1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192...)以外のサイズの画像を この関数で読み込むと内部で一番近くて大きい2のn乗サイズのテクスチャに変換されてしまい若干滲んでしまうので、 読み込む画像を予め2のn乗サイズにしておいてください( 2000x2000pixの画像の場合は2048x2048pixのサイズにしてください ) あと、つい最近まで Direct3D 9 を使用した場合にはミップマップが適用されていなかったので、 よろしければこちらの最新バージョンをお使いください m(_ _;m https://dxlib.xsrv.jp/temp/DxLibVCTest.zip // Windows版 VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.zip // Windows版 BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCC2Test.zip // Windows版 C++ Builder 10.2 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.zip // Windows版 MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用
メンテ
Re: きれいな画像変形縮小描画 ( No.2 )
名前:8127 日時:2019/08/17 01:52

管理人様、 お早い対応ありがとうございます。 MV1LoadTexture()を使った場合、きれいに描画されることを確認しました。 >ただし、制約として2のn乗のサイズ( 1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192...)以外のサイズの画像を >この関数で読み込むと内部で一番近くて大きい2のn乗サイズのテクスチャに変換されてしまい若干滲んでしまうので、 例えば、81×27pixの画像を読み込んだ時には、若干にじむどころか、縦横比が大きく変わって 128×32の画像に引き延ばされてしまいますがこれは意図した挙動でしょうか。 (128×32の画像の左上に元の大きさの81×27の画像があり、DevitationGraphしたときと同じ挙動になると思いましたが・・・)
メンテ
Re: きれいな画像変形縮小描画 ( No.3 )
名前:管理人 日時:2019/08/17 04:40

> 例えば、81×27pixの画像を読み込んだ時には、若干にじむどころか、縦横比が大きく変わって > 128×32の画像に引き延ばされてしまいますがこれは意図した挙動でしょうか。 すみません仕様を失念していました はい、仕様となります 既にご覧の通り、少し滲む、所ではなく、2のn乗サイズのテクスチャに変換されます > (128×32の画像の左上に元の大きさの81×27の画像があり、DevitationGraphしたときと同じ挙動になると思いましたが・・・) ミップマップという技術は、例えば元の画像が 512x512pix の場合、予め 256x256pix, 128x128pix, 64x64pix, 32x32pix, 16x16pix, 8x8pix, 4x4pix, 2x2pix, 1x1pix に 縮小した画像( ジャギっていない縮小画像 )を用意して、描画時の縮小度に応じて使用する画像を決定する( 例えば DrawExtendGraph( 0, 0, 32, 32, GraphHandle, TRUE ); で 描画した場合は 512x512pix のテクスチャではなく 32x32pix のテクスチャが使用される )というものです( どの縮小画像を使用するかはGPUが自動で決定してくれます ) このとき、例えば元が 512x512pix の画像から作り出された 2x2pix のテクスチャの一番左上のピクセル( 座標 x=0 y=0 )には、512x512pix の ときの左上側 256x256pix の情報が縮小されて含まれています、ということは、仮に 81x27pix の画像を 128x32pix のテクスチャの左上に 等倍で配置して、残りは透明色(R=0 G=0 B=0 A=0)にした場合、ミップマップ用に作成される縮小テクスチャの元の画像と透明色の境界に当たる 部分は、縮小度合が高いテクスチャほど元の画像の色と透明色が混ざった色のピクセルが多くなります R=0 G=0 B=0 A=0 のピクセルは、『完全な透明のピクセル』というだけではなく、R=0 G=0 B=0 という、『真っ黒のピクセル』でもあるため、 これが透明ではないピクセルと混ざると、混ざった部分が『黒』色に傾き、結果的に境界部分が黒くなります また、ライブラリ側で勝手にテクスチャ解像を変更しているので、残りの部分を透明色にしてしまうと3Dモデルではよくある 『テクスチャ座標を1.0以上にして同じ画像をリピートさせる』ことができなくなってしまいます というわけで、ミップマップを使用する場合は 2の n乗サイズにしないと都合の悪いことが多く、MV1LoadTexture で読み込まれた 画像は勝手に 2の n乗サイズに引き伸ばされます… ( 尚、縮小するほど隣接するピクセルと色が混ざるので、LoadDivGraph で読み込むような、一つの画像に沢山のアニメパターンを 配置するような画像ともミップマップは相性が良くありません…( 大きく縮小すると隣のパターンの色が滲み出てしまうため ) )
メンテ
Re: きれいな画像変形縮小描画 ( No.4 )
名前:8127(解決) 日時:2019/08/17 17:04

管理人様、 ミップマップについてご丁寧な解説ありがとうございます。 LoadDivGraphで周囲の色が染みだす現象は知っていたので納得できました。 live2d(directXフロントエンド)が頑なに2^Nサイズの画像しか受け付けないのも恐らく本件と同じことが原因でしょう。 今回はありがとうございました。
メンテ
Re: きれいな画像変形縮小描画 ( No.5 )
名前:8127 日時:2019/08/17 17:13

ごめんなさい解決していません。 > R=0 G=0 B=0 A=0 のピクセルは、『完全な透明のピクセル』というだけではなく、R=0 G=0 B=0 という、『真っ黒のピクセル』でもあるため、 > これが透明ではないピクセルと混ざると、混ざった部分が『黒』色に傾き、結果的に境界部分が黒くなります こちらは乗算済アルファを用いた場合はどうなるのでしょうか。 (本来自分で試すべきでしょうが・・・すみません)
メンテ
Re: きれいな画像変形縮小描画 ( No.6 )
名前:管理人 日時:2019/08/18 01:48

> こちらは乗算済アルファを用いた場合はどうなるのでしょうか。 > (本来自分で試すべきでしょうが・・・すみません) お察しの通り乗算済みアルファを使用する場合は余分な部分を透明な色にしておいても 境界部分が黒くなることはありません( 乗算済みアルファ有能… ただ、『万能』ではないので 完全に置き換えるということができない… )
メンテ
Re: きれいな画像変形縮小描画 ( No.7 )
名前:8127(解決) 日時:2019/08/18 20:45

>境界部分が黒くなることはありません 回答ありがとうございます、参考にさせていただきます。 (ただミップマップは縮小して平均する都合上、loaddivGraphを使う場合は境界だけでなく 隣の画像も考えないといけない分使いづらそうな気がします・・・) >『万能』ではない 万能であれば常に乗算済アルファで扱えばいいですもんね。 制限として、確か乗算ブレンドができないか何かであったと思います。 今回はありがとうございました。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存