トップページ > 記事閲覧
シェーダで画像をそのまま表示すると画像が乱れる
名前:waruo 日時: 2019/04/20 11:13

いつもお世話になっております。 MakeScreenで作ったテクスチャを、以下の2通りで表示しようとしています。 1. DrawGraphで表示 2. DrawPolygonIndexed3DToShaderで、画像がそのまま表示されるようなシェーダで表示 しかし、以下のような乱れが生じてしまいます。 1. で表示した場合 https://i.imgur.com/lFVlemR.png 2. で表示した場合 https://i.imgur.com/mc2XF6f.png これはどういった原因から起こるのでしょうか。申し訳ありませんが、調査いただきたく存じます。 プログラムは以下となります。 -------------- C++ プログラム -------------- #include "DxLib.h" int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { ChangeWindowMode(TRUE); SetUseDirect3DVersion(DX_DIRECT3D_9); if (DxLib_Init() == -1) { return -1; } // プロジェクション空間において、画面いっぱいに描画するためのポリゴン2つを初期化する。 VERTEX3DSHADER vertex[4]; // w[1] w[0] // w[2] w[3] VECTOR w[4] = { VGet(+1.0f, +1.0f, 0.0f), VGet(-1.0f, +1.0f, 0.0f), VGet(-1.0f, -1.0f, 0.0f), VGet(+1.0f, -1.0f, 0.0f), }; // pos以外のメンバは使わないので0初期化 for (int i = 0; i < 4; i++) { vertex[i].pos = w[i]; vertex[i].spos = FLOAT4({ 0, 0, 0, 0 }); vertex[i].norm = VGet(0, 0, 0); vertex[i].tan = VGet(0, 0, 0); vertex[i].binorm = VGet(0, 0, 0); vertex[i].dif = GetColorU8(0, 0, 0, 0); vertex[i].spc = GetColorU8(0, 0, 0, 0); vertex[i].u = 0; vertex[i].v = 0; vertex[i].su = 0; vertex[i].sv = 0; } unsigned short index[6] = { 0, 1, 2, 2, 3, 0 }; // ピクセルの乱れと向きが分かるようなテクスチャを作る。 int rx = DEFAULT_SCREEN_SIZE_X, ry = DEFAULT_SCREEN_SIZE_Y; int random_texture = MakeScreen(rx, ry, false); SetDrawScreen(random_texture); for (int x = 0; x < rx; x++) { for (int y = 0; y < ry; y++) { if ((x + y) / 4 % 2 == 0) { DrawPixel(x, y, GetColor(x / (float)rx * 255, y / (float)ry * 255, 255)); } else { DrawPixel(x, y, GetColor(0, 0, 0)); } } } SetDrawScreen(DX_SCREEN_BACK); // シェーダを読み込む int VertexShaderHandle = LoadVertexShader("shader/bin/projection_vs.vso"); int PixelShaderHandle = LoadPixelShader("shader/bin/ssao3_ps.pso"); SetUseVertexShader(VertexShaderHandle); SetUsePixelShader(PixelShaderHandle); SetUseTextureToShader(1, random_texture); // 描画する while (!ScreenFlip() && !ProcessMessage() && !ClearDrawScreen() && !CheckHitKey(KEY_INPUT_ESCAPE)) { // →を押したらニアレスト描画 if (CheckHitKey(KEY_INPUT_RIGHT)) { SetDrawMode(DX_DRAWMODE_NEAREST); DrawPolygonIndexed3DToShader(vertex, 4, index, 2); } // ←を押したらバイリニア描画 else if (CheckHitKey(KEY_INPUT_LEFT)) { SetDrawMode(DX_DRAWMODE_BILINEAR); DrawPolygonIndexed3DToShader(vertex, 4, index, 2); } // それ以外なら自作シェーダを使わずに描画 else { DrawGraph(0, 0, random_texture, true); } } return DxLib_End(); } -------------- 頂点シェーダー -------------- // 頂点シェーダーの出力 struct VS_OUTPUT { float4 ProjectionPosition : POSITION; // 座標( 射影空間 ) float2 TextureCoord0 : TEXCOORD0; // テクスチャ座標 }; // main関数 VS_OUTPUT main(float4 VPos : POSITION) { VS_OUTPUT Out; Out.ProjectionPosition = VPos; Out.TextureCoord0.x = (+VPos.x + 1.0f) / 2.0f; Out.TextureCoord0.y = (-VPos.y + 1.0f) / 2.0f; return Out; } -------------- ピクセルシェーダー -------------- sampler ssao_texture : register(s1); float4 main(float2 uv : TEXCOORD0) : COLOR { return tex2D(ssao_texture, uv); }
メンテ

Page: 1 |

Re: シェーダで画像をそのまま表示すると画像が乱れる ( No.1 )
名前:管理人 日時:2019/04/21 04:34

手元の環境では乗せていただいたプログラムとシェーダーで現象が再現しなかったので 確実に直るとは断言できませんが、恐らく頂点シェーダーの main関数を以下のように することで直ると思います // main関数 VS_OUTPUT main(float4 VPos : POSITION) { VS_OUTPUT Out; Out.ProjectionPosition = VPos; Out.ProjectionPosition.x -= 1.0f / 640.0f; Out.ProjectionPosition.y -= 1.0f / 480.0f; Out.TextureCoord0.x = (+VPos.x + 1.0f) / 2.0f; Out.TextureCoord0.y = (-VPos.y + 1.0f) / 2.0f; return Out; } <最近点サンプリング> https://docs.microsoft.com/ja-jp/windows/uwp/graphics-concepts/nearest-point-sampling ↑こちらの解説がそのままお伝えしたい解説になっているかはちょっと微妙ですが、 Direct3D 9 まではスクリーン座標でのピクセルの中心座標の扱いとテクスチャ座標での ピクセルの中心座標の扱いが異なるため、レンダリングするポリゴンの座標を x と y それぞれ -0.5ピクセル分ずらしてやらないとスクリーン座標のピクセルの中心にテクスチャ座標の ピクセルの中心が来ないので、最近点サンプリング( DX_DRAWMODE_NEAREST )だと描画結果が 崩れる場合があります( ただ、非常に微妙な座標であるため、私の環境では正常に描画されたように、 環境によって崩れたり正常に描画されたりします ) DrawGraph も x と y の値を -0.5 して描画しているので、waruoさんの環境でも正常に描画 されているのだと思います 因みに Direct3D 10 以降はこのスクリーン座標の中心の扱いとテクスチャ座標の中心の扱いが 同じになったため、このような -0.5 ずらす必要はなくなっています ( なので DrawGraph も Direct3D 11 を使う場合は -0.5 ずらさずに描画しています )
メンテ
Re: シェーダで画像をそのまま表示すると画像が乱れる ( No.2 )
名前:waruo 日時:2019/04/21 07:34

DxLibというよりDirectXの仕様だったのですね。 載せていただいた修正案により、画像の乱れはなくなりました。 ありがとうございました。
メンテ

Page: 1 |

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

   クッキー保存