プロフィール

Na-7

Author:Na-7
SE(システムエンジニア)として約15年間システム系ソフト会社を勤めあげ、2008年3月退社。現在、ゲーム制作会社設立を目指して活動中。


アクセスカウンター


最新記事


最新コメント


最新トラックバック


月別アーカイブ


カテゴリ


DATE: CATEGORY:スポンサー広告
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
Wrap01
開発中の自作地形
テクスチャの境界が目立って見栄えが悪い状態。Mirrorモードに対応すると境界を目立たなくすることができる。



◎測定その1

前回ラストで「5枚目のテクスチャ切り替えが極端に遅い」と書きましたが、これに関していろいろ試してみました。

・全モデル共通テクスチャを使用した場合
(頂点数:63504、プリミティブ数:21168、インデックス:なし、DrawPrimitives発行数:1、マテリアルバッチ適用済)
(テクスチャ解像度:2048×2048、GenerateMipmaps:True、透明度情報:あり)

※M:モデル数、T:テクスチャ数

M:1、T:1、固定視点:60fps、飛行テスト:60~60fps
M:2、T:1、固定視点:55fps、飛行テスト:55~60fps
M:3、T:1、固定視点:42fps、飛行テスト:42~60fps
M:4、T:1、固定視点:33fps、飛行テスト:33~60fps
M:5、T:1、固定視点:27fps、飛行テスト:27~40fps
M:6、T:1、固定視点:22fps、飛行テスト:17~32fps
M:7、T:1、固定視点:18fps、飛行テスト:18~30fps
M:8、T:1、固定視点:17fps、飛行テスト:17~30fps
M:9、T:1、固定視点:15fps、飛行テスト:15~30fps
M:10、T:1、固定視点:12fps、飛行テスト:12~24fps

これがこのPCの基本性能に相当するわけですが、こうして見ると、予想以上に描画性能が悪いですね。

5モデルで20~30フレームという当初目標は、結構ハードルが高かったのか…どうりで市販ゲームも遅いわけだw



◎測定その2

モデル毎にテクスチャを変更して測定しました。

M:1、T:1、固定視点:60fps、飛行テスト:60~60fps
M:2、T:2、固定視点:55fps、飛行テスト:55~60fps
M:3、T:3、固定視点:42fps、飛行テスト:42~60fps
M:4、T:4、固定視点:27fps、飛行テスト:27~60fps
M:5、T:5、固定視点:9fps、飛行テスト:9~11fps
M:6、T:6、固定視点:9fps、飛行テスト:9~11fps
M:7、T:7、固定視点:7fps、飛行テスト:7~9fps
M:8、T:8、固定視点:5fps、飛行テスト:5~7fps
M:9、T:9、固定視点:5fps、飛行テスト:5~6fps
M:10、T:10、固定視点:4fps、飛行テスト:4~5fps

1~4モデル目までは、先の計測結果と同程度の値なのに、5モデル目から極端に遅くなっています。



◎枚数か?キャッシュか?

前回は「4枚目と5枚目の差はXNAかハードによるものではないか?」という推測を書きましたが、よく考えると、枚数ではなくて、キャッシュ効果の可能性もありそうです。

どちらかはっきりさせるために、5モデルを準備し、1枚ずつ単色テクスチャに差し替えてみました。

M:5、T差し替え:0、固定視点:9fps、飛行テスト:9~11fps
M:5、T差し替え:1、固定視点:8fps、飛行テスト:8~10fps
M:5、T差し替え:2、固定視点:25fps、飛行テスト:25~41fps
M:5、T差し替え:3、固定視点:25fps、飛行テスト:25~41fps
M:5、T差し替え:4、固定視点:26fps、飛行テスト:26~40fps
M:5、T差し替え:5、固定視点:29fps、飛行テスト:29~40fps

2枚目の差し替えで極端に違ったので、どうやらキャッシュ効果だったようです。

「枚数による」という前回の推測は誤りでした。
ごめんなさいm_(_ _)_m



◎ミラー対応

テクスチャの境界が目立つので(冒頭図参照)、境界を目立たなくさせるためにテクスチャアドレスモードをミラーモード対応にしましょう。

これは既に経験済ですが、何度やっても混乱します。テクスチャアトラス&パターンテクスチャ&6頂点な上に、Mirrorモードで反転して…って頭がパンクしそうです。

wrap02   wrapからmirrorに変更した直後
Wrapモード(左図)からMirrorモードに切り替えた直後(右図)

見た目縦長なのに気付かず、表示されたパターンを読み違えていたのですが、パターンに番号を記入したらようやく理解しました。

これで大丈夫!…と思ったのですが、「ここを合わせるとこっちがずれる」といった感じで、どうやってもパターンが合いません。何故??



◎次回予告

次回は「4月の総括と5月の目標」の予定です。

スポンサーサイト

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
地形4種類(道なし)
開発中の自作地形
頂点データを6つに分割した。テクスチャが4枚以下であれば20fps以上で表示される模様。画面は道モデル無し状態。



◎謎の現象

「カメラ位置や注視点を特定の座標に設定すると、地形モデルの一部が消失することがある」という謎の現象が発生しました。

インデックス廃止04A

画面左上にカメラ座標を表示しました。この位置からカメラを手前に引くと現象が発生します。

インデックス廃止04B   インデックス廃止04C

これは一例で、カメラ位置によっては、カメラ位置を変えずに注視点を変更するだけで発生します。手前の地形が表示されて、奥の地形が消えることもあります。

何でしょうね?この現象は?



◎原因調査

謎の現象を解明するために、とりあえず思い付く限りのことを試してみました。

・単独モデルでも複数モデルでも再現する
 →描画速度やメモリ容量に関連する可能性は低い

・他のテクスチャに差し替えても再現する
 →テクスチャの模様は関係ない

・テクスチャのGenerate Mipmapsを変更しても再現する
 →Mipmap設定は関係ない

・BasicEffectでもカスタムエフェクトでも再現する
 →エフェクト設定は関係ない

・透過処理をONにしてもOFFにしても再現する
・アルファ無しテクスチャに差し替えても再現する
 →透過処理やアルファ設定は関係ない

・スプライトバッチを外しても再現する
 →スプライトバッチは関係ない

・法線データを全て真上(0, 1, 0)に設定しても再現する
 →法線は関係ない

・頂点データ、ワールド行列、プロジェクション行列等は
 一切変更していない
 →View行列のカメラ座標と注視点のみ影響している

・地形の下に別のモデルを配置すると、現象再現時は
 下のモデルが表示される
 →地形の手前に何かが表示されて地形が隠れた
  わけではない

ソースを何度見なおしても、設定をあちこち変更しても、原因がわかりません。まいったね、こりゃ…。



◎PIXを利用した表示状態解析

仕方がないので、PIXで表示状態を詳細にチェックすることにしました。

PIXデバッグ画面

正常時と現象再現時のフレームをキャプチャし、頂点データ、テクスチャ設定、デバイス設定等を1日がかりで総チェック。隅々まで調べたつもりですが、どこにもおかしな差異は発見できませんでした。

これだけ調べて手掛かりすら掴めないなんて…かなりゲンナリです。



◎休養

ここまで全く進展がありませんが、ちょっと疲れて気が滅入ってきたので、丸1日休養にあてました。

行き詰った時には気分転換も必要です。GWの一部前借りということで(笑)



◎原因判明

休養明け。飛行テストプログラムを改造したり、PIXの値をトレースしたりしましたが、なかなか進展はありません。

ふと気になってDrawPrimitivesメソッドのマニュアルを確認したら、引数primitiveCountの説明に「使用できるプリミティブの最大数を調べるには、MaxPrimitiveCount を確認します。」とありました。

で、その値を調べたら、65535でした。うわ~ショック!!
地形モデルのプリミティブ数は倍近くあります。つまり、ハードの上限値を超えていたわけです。

エラーにならないし(インデックスは上限超えるとエラー)、複数モデルでも正常に表示されたりするので、なかなか気付けませんでした。

ハード制限に気付かずに3日も悩むなんて…悔しいやら情けないやら。



◎6分の1地形

頂点数が上限を超えているなら、頂点データを分割すれば問題を回避できるはずです。とりあえずデータを6つに分解し、そのうちの1つを表示するようにしました。

インデックス廃止05

ああ、やっとまともに表示されましたね。しかし頂点数は全地形の6分の1なのに、フレームレートは8fps。

先にマテリアルバッチを適用しましたが、それだけではフレームレートは変わりませんでした。頂点をさらに5倍描くことを考えると、B案の技術を導入しても、本当に早くなるのか不安です。



◎テクスチャは4枚以内で

いろいろ試していたら「5枚目のテクスチャ切り替えが極端に遅い」ことに気付きました。テクスチャを4枚以内に抑えるだけで、軽く20fps以上出るのです!

地形4種類(道なし)
道なしバージョン

5地形モデルのうち、1つのテクスチャを他と同じテクスチャに指定した場合は24~25fps、地形モデルを4種類に減らした場合は27~28fpsです。つまり、4枚目から5枚目へのテクスチャ切り替えに16fps、6万頂点の描画に3fpsかかっている計算になります。

これは推測ですが、ハードまたはXNAが同時にテクスチャを扱う上限が4枚と決まっているのでしょう。もしかしたら、4枚以内だとハードの機能を利用して、5枚以上はソフトウェアで描画しているのかもしれません。

これほど違うなら、何がなんでも4枚以内に抑えるべきかも?!



2009/4/30追記
「5枚目のテクスチャ切り替えが極端に遅い」というのは誤りで、実はメモリキャッシュ効果でした。ごめんなさい。



◎次回予告

ずーっと1桁fpsで四苦八苦してましたが、急にヒントらしきものを見つけたのかもしれません。他のモデルを同時に表示した場合とか、いろいろ試してみます。

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
インデックス廃止01
デバッグ中の自作地形
インデックスを廃止し、頂点データのみでテクスチャアトラスを試みた画面。飛行テストで謎の浮遊大陸が現われた??


◎不均一なシェーダー入力

HLSL内で頂点描画順序をカウントしたいのですが、グローバル変数は均一データと見なされるため、カウンターに使えないことがわかりました。では、不均一なデータはどのように扱えば良いのでしょうか?

HLSLマニュアルの「不均一なシェーダー入力とセマンティック」では、「不均一データ=頂点データ」と見なしているらしく、セマンティックを利用したシェーダー入出力の事しか書かれていません。

セマンティックは後続のグラフィック パイプライン ステージにデータを引き継ぐためのものであって、次の頂点にデータを引き継ぐものではありません。つまりダメってことです。



◎反復レジスタ

描画時にプリミティブ数を渡しているんだから、GPU側で描画頂点数をカウントしているはず!

…と思ってHLSL組み込み関数を調べてみましたが、現在の頂点描画数を取得する関数は無さそうです。

こちらの記事の図に「反復レジスタ」というものが描かれています。読み取り専用レジスタですが、GPUは多分これを使って描画頂点数をカウントしてると思うので、この値を取得できれば何とかなりそうな気がしますが…変数宣言時にiレジスタを指定するとエラーになります。

HLSLで反復レジスタを参照する方法を探しても見当たらないので、アセンブリ言語とかでないとアクセスできないのかもしれません。


ここまで調べた結論としては「HLSLで頂点描画順序をカウントする方法は無い」ようです。
何でその程度のことが出来ないかなぁ(--;



◎メモリ6倍?

HLSL側で解決できないなら、HLSL側で処理できるように頂点フォーマットを改造するしかありません。しかしそれには大きな問題があります。

・1つの頂点に複数のテクスチャ座標を与えても、
 HLSL側で使い分けが判別できない
  ↓
・頂点データとテクスチャ座標データを1対1で割り当てて、
 HLSL側の使い分けを不要とする
 (頂点データ共有方式をやめる必要がある)
  ↓
・頂点数が6倍に増えてしまう
 (1つの頂点データを6つのポリゴンが共有しているため)

描画頂点数は変わらないので、描画速度は落ちませんが、メモリは圧迫します。カウントできないために頂点バッファを6倍消費するハメに…うわ~嫌すぎ!!

待てよ…6頂点のうち2つは共通だから、インデックス方式なら4倍に抑えられますね?それでも4倍消費しますけど。

…そこまでして、やる意味あるのかなぁ?



◎あまり早くない?

描画速度を上げるために取り組んでいるテクスチャアトラスですが、実現したらどれほど早くなるのでしょうか?

よく考えたら、描画プログラムは既に出来あがっている状態なので、速度効果は今すぐ確認できるはずです。

…確認したら、8~9fpsでした。G案の時点で5~6fpsだったので、1.6倍です。あれ?期待してたほど早くないですね?


このままだと、テクスチャアトラスを実現したとしてもデメリットが強すぎる(やる意味ない?)ので、速度がいまいちな理由を探ります。



◎速度比較テスト

いろいろ試したら、テクスチャ設定変更後のeffect切り替えに時間がかかることが判ってきました。(テクスチャ設定行をコメントアウトするだけで、20fpsを超えました)

でも、テクスチャ切り替え回数は、75回→5回と大幅に減らしています。テクスチャ切り替えに時間がかかるなら、以前より格段に早くなって然るべきでしょう。

…もしかして、テクスチャのデータ量が多いと、切り替えに時間がかかるのでしょうか?
試しに、地形モデル1~4のテクスチャを、データ量が少ない1色テクスチャに差し替えてみました。

テクスチャ切り替え速度検証02

うわ~20fps超えてる…テクスチャのデータ量が多いと、サンプラの準備に時間がかかる、ということかもしれません。

…えっ?切り替えじゃなくて、複雑な模様を描画するのに時間がかかるんじゃないかって?
では、改めて1モデルで試してみましょう。

テクスチャ切り替え速度検証03   テクスチャ切り替え速度検証04
複雑テクスチャ(左図)と一色テクスチャ(右図)

複雑テクスチャが35fps、一色テクスチャが36fpsでした。
テクスチャの複雑さは描画速度に殆ど影響しないが、エフェクト切り替えに時間がかかる、ということですね。マテリアルバッチが有効と言われる理由も納得できます。


ついでに、テクスチャの解像度やファイルサイズも変更して試したところ、どちらも描画速度に影響しない、という結果になりました。



◎B案とマテリアルバッチの併用

テクスチャの切り替えに時間がかかるなら、B案の技術とマテリアルバッチを併用して、テクスチャの切り替え無しで一気に表示すると早くなるでしょうか?でも、最初に全テクスチャを準備するから、サンプラが扱う総データ量は変わらないんですけどね。


…で、強引に試したところ、16fpsでした。(8~9fpsの2倍)
ただし、頂点データやプログラムは中途半端な状態なので、最後まで実装したら、もう少し遅くなると思います。

目標の20fpsに届かないのは微妙ですが、ここまで来たら、やるだけやってみますかね。



◎頂点数の壁

…というわけで、実際にコーディングしたら、画面表示が乱れまくりました。頂点数が16ビット(65536)を超えたために、インデックスデータがおかしくなったようです。

そこで、IndexElementSizeの指定を16ビットから32ビットに変更したら、エラーで落ちました。エラーログを確認したら「This device does not support 32-bit indices.(このPCは32ビットインデックスをサポートしていません)」とのこと。

ぐはっ!ハードっすか!(><)



◎インデックスの廃止

ハードの制約を回避するには、インデックスを廃止するしかありません。当然データ量は6倍になります。「そこまでする価値あるのか?」と嘆きつつ、気力を振り絞ってコーディングしました。

インデックス廃止02   インデックス廃止03

とりあえずポリゴンやテクスチャは形になったようですが、飛行テストでカメラを特定の領域に移動すると、手前や奥の地形が急に消失したりします。なにコレ?

こういう現象って、厄介なんだよね~(ブツブツ)



◎次回予告

そろそろ限界を感じつつ、次回につづきます。

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
テクスチャアトラス縮小
統合したパターンテクスチャ(縮小画像)
16パターンの画像を1枚の画像に統合して生成するようパターンテクスチャ自動作成ツールを改修した。



◎地形変更テスト

G案改修後、ゲーム中に地形を変更するテストをしてなかったので、実施しました。

自作地形28   地形変更テスト
地形変更前(左図)と地形変更後(右図)

狭域、広域に関わらず約1秒で地形が変化します。
これで火計や洪水による地形変化もバッチリです!



◎そしてH案へ

「そろそろXSIもやらないと」と思いつつ、地形プログラム未完成のままでは落ち着かないので、結局H案(G案&F1案)に取り組むことにしました。



◎パターンテクスチャの統合

パターンテクスチャ自動作成ツールを改修して、パターンテクスチャを統合しました(冒頭図参照)。
2048×2048の中に、16パターン埋め込みました。

画像生成速度を考慮したプログラミングを試みたのですが、透明度情報を持つピクセルのGetPixel/SetPixelは癖があってなかなか思うようにいかず、結局ベタなプログラムになりました。

頻繁に実行するツールじゃないし、ベタでも1分かからないので、少しぐらい待つことにします。



◎大失敗!

パターンテクスチャが準備できたので、いよいよメインプログラムの改修です。
テクスチャ座標をセットして……できました!

テクスチャアトラス失敗01

ぐはっ…酷いもんですね。何が悪かったのでしょうか?パターン判定もテクスチャ座標値も異常は見当たらないようですが…うん?テクスチャ座標?

しまった~!!!

パターンテクスチャ方式をテクスチャアトラスに対応させるには、テクスチャ座標データを4倍に増やさないといけないのでした!昔それに気付いてテクスチャアトラスの採用見送ったの、すっかり忘れてました~!!!

ああ、今の自分のバカさ加減に呆れてしまいます(><)



◎GPUのメモリ空間

テクスチャ座標を4倍にしたら、メモリはどれほど圧迫されるのでしょうか?

現在の描画頂点数は51万だから、今後の増分を考慮して百万頂点と仮定すると、1頂点あたり3byte増えるから、3MB増える計算になります。

GPUのメモリ空間は未調査ですが、全体で128MB以上持っていると仮定すれば、多分大したことないよね?
よ~しこのまま続行だ~!



◎4種類のテクスチャ座標の使い分け

というわけで、まず頂点フォーマットを改造して、4種類のテクスチャ座標をセットしました。

0番:頂点右上に存在するパターンテクスチャの左下座標
1番:頂点左上に存在するパターンテクスチャの右下座標
2番:頂点右下に存在するパターンテクスチャの左上座標
3番:頂点左下に存在するパターンテクスチャの右上座標


ところで、4種類のテクスチャ座標を用意したものの、シェーダーは何を頼りに使い分ければ良いのでしょうか?テクスチャ番号やパターン番号では判断基準にならないし…う~む。

…そうか!インデックス番号ですね!
現在は、1マスにつき2ポリゴン(=6頂点)を

(始点)→右→右上、(始点)→右上→上

の順番で描画しているので、シェーダー内部で頂点描画順序をカウントし、順番の位置に相当するテクスチャ座標を使用すれば良さそうです。つまり、

0番→1番→3番→0番→3番→2番

上記の順番でテクスチャ座標を使用すれば良い、ということです。



◎均一のシェーダー入力

…で、プログラミングした結果が、こんな感じです。

テクスチャアトラス失敗02

HLSLサンプルコード

パターンがぐちゃぐちゃなのは、HLSLのcounter変数が常に0→1だからです。

頂点を描画する度に、カウントアップして欲しいのですが、externやsharedで宣言しても、定数レジスタを明示しても、毎回初期化されてしまうようです。まいったな~。


HLSLマニュアルを確認したら、「均一のシェーダー入力」という項目に「均一データは、シェーダーの複数の実行に対して一定です。」と書かれていました。
グローバル変数って、そういうものだったんですね…。



◎次回予告

パターンテクスチャ方式を維持しつつ、テクスチャアトラスを導入するのは、予想以上に難しいですね。

次回で決着するといいなぁw

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
自作地形28
開発中の自作地形
アルファ値を利用して複数の地形モデルを透過合成し、見た目や機能を損なうことなく高速化を実現した。



◎ビット演算

これまで何百種類ものパターンテクスチャを4次元配列で管理してきましたが、G案は複合テクスチャを廃止するので、今後は地形種別数×15種類になります。これに伴い、パターンテクスチャは2次元配列とビット演算で管理することにしました。

ビット演算の考え方は昔から知っていましたが、実際に経験したことは殆ど無かったので、少々苦戦しましたw
例えば、こんな感じ。

命題:iが0~15の時、iの各ビット値をi1~i4に格納する

int i1 = (i >> 3) & 0x1;
int i2 = (i >> 2) & 0x1;
int i3 = (i >> 1) & 0x1;
int i4 = i & 0x1;

目的は一応達成できましたが、これで良いのでしょうか?
もっと効率の良い方法がありそうな気がしますが…。

それと、0x1を0b1に変更するとエラーになるんですけど、C#言語は2進数表記できないんですかね?



◎インデックスバッファ不足

地形種別モデルを3個まで無事作成できましたが、4個目で落ちました。どうやらインデックスバッファ不足のようです。

調べてみると、インデックスバッファ配列(各頂点番号を格納)が冗長すぎて、インデックスバッファが不足する、という状況でした。

バッファ配列が冗長すぎなければ、当面は足りそうです。つまり、バッファ配列を最適な大きさで確保できるか?が焦点になりそうです。

これまで地形モデルは数個以内でしたし、パターン数が増えてもインデックスが分割されるだけなので、総インデックス数は不変でした。

しかしG案は、地形モデル数が増加する上に、パターンが重なる分だけ総インデックス数も増加します。どうすれば、効率的なバッファ確保ができるでしょうか?

確か XNA Creators Club に、一定の大きさのバッファを使い回すサンプルがあったと記憶してますが、今は改修中でソースがややこしい状態なので、即時導入はやめておきます。



◎安全性に対する懸念

今すぐできそうな手法としては、現在のインデックス配列をテンポラリとみなし、最終段階でインデックス配列を新たに作り直す方法です。
(テンポラリ配列の作成が完了した段階で、総インデックス数が判明します)

但し、この手法には懸念があります。

private static readonly Int16[] vertexIndices = new Int16[(数量)];

現在は、お手本に従い上記のように宣言してますが、後で作り直すためにはreadonlyキーワードを削除する必要があります。でもこれ…消すとヤバそうな気がしませんか?

試しにやってみたら、とりあえず動きました。でもかなり不安なので、この方法は安全性が確認できるまで封印します。これは推測ですが、readonlyは配列のガーベージコレクション対策かもしれません。インデックス配列はメモリ配置が変わるだけでヤバそうだし…。

結局、バッファ問題は先送りとし、当面は定数で細かく指定することにしました。先に地形モデル仕様(データ構造と描画方式)を確定させないと、バッファ事情も変わりそうなので。



◎SetPixelの謎

パターンテクスチャ自動作成ツールも改修が必要です。テクスチャにアルファ値を設定し、PNG形式で出力します。

しかしいざ作ってみると、SetPixelした座標とは無関係の座標のアルファ値まで勝手に変化したりして、かなりハマりました。その不思議な現象は、どうやら下記の初期化方法に問題があったようです。

(注:XNAではなくC#です)
for (int y = 0; y < height; y++)
 for (int x = 0; x < width; x++)
  srcB.SetPixel(x, y, Color.FromArgb(0, workB.GetPixel(x, y)));

上記の部分を下記のように修正したら直りました。

for (int y = 0; y < height; y++)
 for (int x = 0; x < width; x++)
 {
  Color color1 = work.GetPixel(x, y);
  Color color2 = Color.FromArgb(a, color1.R,color1.G, color1.B);
  work.SetPixel(x, y, color2);
 }



◎表示する順番

そんなこんなで苦戦しつつも、何とか5つの地形モデルを表示することができました。

自作地形27

うん?何か少し印象が違うような…ああ、川が干上がって途切れ途切れになってますね。川モデル表示後に河原モデルを表示したので、川の一部が河原に上書きされたようです。
モデルを表示する順番を変えたら直りました。(冒頭図参照)

洪水前後の水位の増減は、これを利用してできないかなぁ…(ぼそっ)



◎データ比較

ここで改修前後のデータを比較してみましょう。

描画プリミティブ数:38万 → 51万(1.3倍)
地形モデル数:2 → 5(2.5倍)
DrawIndexedPrimitives呼び出し回数:446 → 75(0.2倍)
1fps → 5fps(5倍)

「激重」から「ちょい重」ぐらいになりました。見栄えや機能を低下させずに早くなったのは嬉しいですね~!



◎マテリアルバッチの適用

マテリアルバッチを適用すれば、さらに早くなるかと期待してやってみましたが…結果から言うと、全然早くなりませんでした(--;

Effect取得に苦心してやっと動いたと思ったのに…。
1モデルあたりの規模が大きすぎるのかもしれません。

おかげでソースが中途半端な状態になっちゃったんだけど、元に戻した方がいいのかなぁ?う~む…。



◎次回予告

G案の改修が完了しました。
予想外の改修ボリュームでした…。
でもそこそこ早くなったので、やった甲斐はありましたね。

しばらく休みなしだったので、明日は1日お休みします。
次回は…XSIかな?

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

| BLOG TOP |
DATE: CATEGORY:雑記
XNA-ACLAndGraphicBoardCompatibility
ACLとグラボの相性問題について
開発段階と配布段階で発生しうる問題や回避策について解説している。動作テストの協力も呼び掛けている。



今回は特別告知です。

◎ACLご利用の皆様へ

掲示板でACL(XNA用Animation Component Library)の問い合わせ対応をしていたら、ACLにはかなり厄介な相性問題が存在することに気が付きました。

・GeForceのような超メジャー系グラボで
 相性問題が発生すること

・相性の良いグラボで開発している人は
 この問題に気付きにくいが、知らないと
 配布段階で問題になる可能性があること

詳細は「ACLとグラボの相性問題について」にまとめましたが、全てのACL利用者(ゲーム開発者)が注意すべき問題と思われるので、ACL利用者は必ず目を通しておいてください。

まだ気付いたばかりで情報が少ないので、情報収集にご協力をお願いします。

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
地形モデル透過テスト02
地形モデル透過テスト
地形モデルの透過合成テスト。地表モデルの一部が透けて、下側の川モデルが表示されている。



前々回の続きです。

◎HLSLのswitch

HLSLのif文をswitch文に変更してみましたが、私の環境ではsyntaxエラーになりました。vs3.0&ps3.0で試しても現象変わらず。Direct3D10でないと使えないのかもしれません。
まったく…マニュアルにサポートバージョンぐらい明記して欲しいですね…ブツブツ…。

HLSLスキルが未熟なためか、状況を打開するアイデアが浮かばないので、案は諦めて別の方法を検討します。



◎遅延対策案の再検討

3/27の記事のラストで、遅延対策案の優先順位を以下のように決めました。

A > B > E > C1 > C2 > D

案:ループを改善したが、DrawIndexedPrimitivesの
   呼び出し回数が多すぎて目標未達成

案:サンプラを効率的に管理できず断念


案と案がダメだったので、次の予定は案です。ですが、今は新たなアイデアがあるので、それらを含めて優先順位を再検討します。



◎新規対策案

F1案:
現在512×512のパターンテクスチャを2048×2048に集約し、マテリアル数を1/16とする。

F2案:
現在512×512のパターンテクスチャを128×128に落とした上で、2048×2048に集約し、マテリアル数を1/256とする。

案:
アルファ値を利用して複数の地形モデルを透過合成する。パターンテクスチャは、地形種別数×16種類のみ用意する。(2種類以上の複合テクスチャ廃止)

案:
F1案と案を両方実施する。



◎新規対策案のポイント解説

F1案は、テクスチャアトラスによるコンテンツ最適化です。
DrawIndexedPrimitives呼び出し回数:446→28
となるので、それなりの効果が期待できますが、ソースコードは複雑化します。コンテンツ管理方式を変更するので、パターンテクスチャ自動作成ツールの修正も必要です。また、今後地形種別が増えることを考慮すると、これだけでは効果不十分かもしれません。

F2案は、F1案の強化版です。
DrawIndexedPrimitives呼び出し回数:446→2
となるので、かなりの効果が期待できます。
反面、画質は確実に劣化しますし、コンテンツ管理やソースコードの複雑さは相当シビアになります。テクスチャを手描き修正する際の煩雑さを思うと、ちょっと気後れします。

案は、アルファ値を利用して地形モデルを透過合成し、2種類以上の複合テクスチャを廃止して、パターン数を減らします。
DrawIndexedPrimitives呼び出し回数:446→80
となるので、それなりの効果が期待できますが、これだけでは効果不十分かもしれません。尚、この案を採用する前に、アルファ値による透過可否を事前に検証すべきでしょう。

案は、
DrawIndexedPrimitives呼び出し回数:446→5
となるので、かなりの効果が期待できますが、F1案と案のデメリットも継承します。F2案と比べると、速度は若干劣りますが、画質は劣化しません。



◎透過可否の検証

地形モデルを重ね合わせた際、テクスチャの一部を透過して下側の地形モデルが表示されるか検証し、案の実現可否を判定します。


まず、2種類のテクスチャを貼り付けた2つの地形モデルを用意します。

地表テクスチャ(一部透過)   地表モデル
地表テクスチャ(左図:中央部透過)と地表モデル(右図)

川テクスチャ   川モデル
川テクスチャ(左図:透過なし)と川モデル(右図)

次に、川モデルを普通に配置します。
最後に、地表モデルを少し上方に配置します。この時、レンダリングステートを変更して、透過処理を施します。

GraphicsDevice.RenderState.AlphaBlendEnable = true;
GraphicsDevice.RenderState.SourceBlend = Blend.One;
GraphicsDevice.RenderState.DestinationBlend = Blend.One;

地形モデル透過テスト01

う~ん…色が混ざってますね。期待した結果とは違いますが、レンダリングステートの設定をうまくやれば、透過処理はできそうです。
レンダリングステートのパラメータは沢山あって、どれをどうすれば目的通りになるのか、まだよく知らないんですよね。
(「森のくまさん」のラストシーンは、思考錯誤に丸1日かかりました。ちゃんと理解してる人なら5分でできるかも…(^^;)


…で、半日ほど試行錯誤の後、何とか目的通り表示できました。(冒頭図参照)

GraphicsDevice.RenderState.AlphaTestEnable = true;
GraphicsDevice.RenderState.ReferenceAlpha = 0;
GraphicsDevice.RenderState.AlphaFunction = CompareFunction.NotEqual;

昔はマスキングと呼んでいましたが、XNAでは「アルファ抜き」と呼ぶようですね。アルファ抜きはアルファテストで実装するということを、ようやく理解しました(^^;


これで案は実現可能と思います。尚、モデルが複数になると描画速度が低下しますが、これは最後にマテリアルバッチの技法で改善します。



◎優先順位の検討

新規対策案を含めた新しい優先順位は以下の通りです。

G > F1 > H > F2 > E > C1 > C2 > D

最優先は案。デメリットが一番少ないので。

続いてF1案。デメリットが比較的少いので。
(状況次第では、そのまま案に移行します)

案でもダメな場合はF2案。なるべく避けたいですね~。

案には独特の魅力を感じますが、「画質も速度もデザイナー次第」なので、3D担当者未定の現状では、他の案を優先すべきと判断しました。



◎次回予告

次回は案を実装します。

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

| BLOG TOP |
DATE: CATEGORY:3Dテストプログラム開発
ClickOnceセットアップ実行画面
セットアップ実行画面
ClickOnceで作成したsetup.exeの実行画面。ゲーム実行に必要なランタイムをチェックしてインストールを促す。



◎XNA実行環境の問題

前回記事のコメントで、とくめーさんからXNA3.0が「ClickOnce」に対応していることを教えて頂きました。

昨年「XNA実行環境の問題について」に記述した通り、XNA実行環境には3つの問題があると考えていましたが、そのうちの1つ(ランタイムの問題)が改善されたようです。


とある事情により、サブPC(XNA3.0未導入)上でXNA3.0ゲームの動作テストを実施する必要が生じたので、これを機にClickOnceを試してみます。



◎試してみる

こちらの記事を参照しながら「プロジェクトの発行」を行い、生成されたsetup.exeをサブPCで実行すると、ランタイムのインストール画面が表示されました。

インストールに同意するとランタイムのインストールが開始されましたが、ここでわざとキャンセルすると、セットアップの中断処理が実施され、セットアップがキャンセルされました。ここまでは想定通りです。

ところが、setup.exeを再度実行すると…セットアップがまともに動きません(異常終了)。

サブPCの状態を確認すると、スタートメニューにはゲームが登録済、‘プログラムの追加と削除’にはXNA Framework3.0とゲームが登録済の状態でした。

どうやら、先程のセットアップ中断処理が中途半端で、レジストリ関係がクリアされずに残ってしまったようです。しっかりしてくれ~!>MS社



◎動きません

‘プログラムの追加と削除’からXNA Framework3.0とゲームを自分で削除し、セットアップを実行すると、セットアップは正常に動作し、インストールが完了しました。

これで直ったかな、と思いつつゲームを実行すると…何故か動きません。興味本位でキャンセルテストなんかやらなきゃ良かった…。

試しに、ゲームプログラム開発元の\bin\x86\ReleaseフォルダをサブPCにコピーしてexeファイルを実行すると、正常に動作しました。ランタイムは問題無くインストールされたようですね。

スタートメニューに登録されたゲームの呼び出し元(先?)を確認すると、最初の発行時に作成した「~.application」が呼び出されてました。つまり「ClickOnceは、Releaseフォルダの~.exeファイルとは別のものを配布する」ということです。



◎まとめ

当初の目的である「サブPCでのゲーム動作テスト準備(実行環境構築)」は達成されたため、中途半端ですみませんが、ClickOnceの検証はここまでとします。
…これ以上踏み込むとハマりそうで怖い(笑)

結局、ClickOnceで配布したゲームは未だに動きませんが、これは「セットアップの中断処理がたまたま誤動作したため」と思い込むことにしますw
まぁ、セットアップ中にキャンセルするケースなど稀でしょうから、その点はあまり心配していません。

しかし1つ覚えておきたいのは「何かトラブって一度ゲームが起動しなくなると、削除&再インストールでも動かないケースがある」ということです。

もしユーザからこのような報告を受けた場合は、下手にレジストリや配置マニフェスト(詳細はこちら)の修正を図るよりも、exeファイルを個別に配信した方が賢明と思います。



◎次回予告

ClickOnceが全く問題無いようなら、3Dテストプログラムの配布モジュールもこれで作り直そうと思っていたのですが、今回は見送りですね~。

ClickOnceはいずれまた扱うつもりですので、その時は踏み込んで検証します。

次回は「遅延対策案の再検討」です。

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
自作地形HLSLテスト01
HLSL描画テスト
頂点のパターン情報を元に、一度の描画命令で5種類のテクスチャを描き分けるテスト。if文は極端に遅かった。



◎Short4問題解決

4/4の記事のラストで、Short4型の使い方がわからず、「Short4は諦めて、Vector4にします」と書きましたが、その後XELFさんからコメントでコンストラクタを利用する方法を教えて頂きました。

早速試してみると、これで問題なくパックされたらしく、.ToVector4でパックされた値を戻すテストも成功しました。XELFさん、どうもありがとうございました!

…え?何故コンストラクタに気付かなかったのかって?
そりゃC#言語経験1年未満の初心者ですから(爆)

カスタム頂点のサンプルコード



◎ピクセルシェーダのif文

パターン番号をピクセルシェーダに渡せるようになったので、試しに5種類のパターンテクスチャを表示してみました。(冒頭図参照)

HLSLサンプルコード

地形モデル描画部分のXNAサンプルコード

PIXで確認すると、シェーダのoutput.patternNumber.xだけでなく、.y/.z/.wにもそれぞれ整数値が格納されていましたし、Roundを使わずともif文でパターン番号を判別して複数のテクスチャを表示できたので、動作結果は想定通りでした。

しかし、描画速度は想定を大きく下回って、11fpsでした。

ちなみに、ピクセルシェーダの最下行(return ~)以外を全てコメントにすると、30fpsです。つまり、ピクセルシェーダ内にif文を4つ入れたら、30fpsから11fpsまで下がったのです。
マジですか~!?



◎サンプラ配列の作成

if文方式では速度が遅すぎるので、サンプラを配列で指定する手法を試みます。

サンプラ型(DirectX HLSL)マニュアルを確認すると、Direct3D10ではサンプラ配列をサポートするために構文を少し変更しているようですが、実際にやってみると、Direct3D9でもサンプラ配列を作成することは出来ました。

HLSLサンプラ配列作成サンプルコード



◎サンプラ配列への動的アクセス

しかし、下記のように配列要素を動的に指定しようとすると、エラーになりました。

ピクセルシェーダ:
int x1 = input.patternNumber.x;
return tex2D(sm[x1], input.TextureCoordinate) * input.Color;

エラー:
sampler array index must be a literal expression

エラーを直訳すると「サンプラーの配列のインデックスはリテラル表現する必要があります」です。何じゃそりゃ?と思ってマニュアルを探ってみました。

マニュアル「Direct3D 9 での HLSL シェーダーの記述」の「サンプラーとテクスチャー オブジェクト」項目のラストには、サンプラーの動的配列アクセスについて記述されています。

ちょっと表現が解り難いのですが、これは「リテラルループ(固定ループ)では使用可能だが、コンパイル時に解決できない動的アクセスは使用不可」と述べているようです。

つまり、「サンプラ配列を使用した地形モデル描画構想」は実装不可能という結論になります。


もし可能であれば、XNAからパターンテクスチャ配列を丸ごとシェーダに渡して一気に描画したかったのですが…ああ、Direct3D10が使えたらなぁ…(嘆)



◎次回予告

う~ん…これが最後の壁なんですけど、if文も配列もダメとなると、苦しいですね~。

他の方法がないか考えます。何も思い付かなかったら、B案は諦めてC案に移るかも。

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
三度の飯より三国志
三度の飯より三国志
三国志関連サイト。武将列伝、三国志関連作品レビューなどがある。読者投稿可能。武将列伝内の魏延評が熱い。



◎活動方針&年間目標

2009年度の活動方針&年間目標は以下の通りです。


2009年度 活動方針(PDF形式)

活動方針は昨年から一貫してますので解説は省略します。


2009年度 年間目標(PDF形式)

できれば年度内に最終版をリリース(配布開始)したかったのですが、スケジュール的に厳しいので、開発目標は3段階に分割しました。

このゲームは「次回作もプレイしたい」と思ってもらえないと存在価値が無いので、期間限定で強引に仕上げたりせずに、品質を優先します。



◎開発スケジュール

今回最も重要な「年間開発スケジュール」です。

2009年度 開発スケジュール(PDF形式)

XNAでの開発ペースがある程度掴めてきたので、ようやく全体スケジュールを組むことができました。が、はっきり言ってキツイですね。3DCGが厳しいのは承知してましたが、プログラムもこんなにやることあったのか…。

途中でいろいろハマったり、勉強したり、「やることリスト」がガンガン増えていくことを考えると、このスケジュールはとても守れそうにない気がします。いや、きっと守れないに違いない(笑)

しかしまぁ、やる前からヘタレててもしょうがないので、とにかく一歩一歩地道に頑張りましょう。

それから、進捗状況は毎月チェックして、スケジュールは半年後に見直すこととします。



◎次回予告

前々回の地形プログラムの続きに戻ります。

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
XSIModTool
XSI Mod Tool
3DCG開発ツールXSIの無料版。XNAを標準開発ツールとして意識している。商用利用不可。



◎3月の目標達成度

今月から2009年度になりました。2008年度の総括は3/5の記事で実施済ですので、今回は3月分のみ総括します。

まずは先月の目標達成度から確認しましょう。

・地形モデルを完成させる
 →目標達成率:80%
 →当初予定していた機能は一通り実装済
 →性能問題対処中

・CG担当者を獲得する
 →目標達成率:40%
 →2DCG系は候補者と交渉中(注1)
 →3DCG系は候補者発見できず

・CGの発注条件を詳細化する
 →目標達成率:0%
 →ドキュメント系は全く進んでない


注1:正式にOKを頂いたら、ブログに紹介しますので
   お楽しみに!



◎3月の反省

・プログラム系は目標100%に届かなかったが、
 感触は悪くない
 →当面は現在のやり方で継続する

・2DCG担当候補者の感触は良好、品質は期待通り
 →モチベーションが維持できるようフォローすること

・3DCG担当者探しは、全く進展が無い
 →やり方を見直した方が良い(後述)

・ドキュメント系は全く進んでない
 →きちんと作業時間を割り当てて進めること



◎3DCG担当者について

何のアテも無く漠然と探すだけではなかなか見付かりそうにないので、方針を定めて対応します。

方針1:受け入れ態勢を強化する
・従来型のローポリモデル作者を中心に探してきたが、
 従来型の作者は既に目的(注2)を持って活動している
 人が多く、おっさんモデルを作成してくれそうにない
 注2:自作ゲームキャラや仕事上の建築物、
    趣味のメカ、美少女等

・最近はMaya、blender、XSI等の高機能ツール利用者が
 増加傾向にあり、これに対応できないと候補者が限定
 されてしまう
 →正直言ってMayaやblenderにはまだ腰が引けるが、
  まずは無料のXSI Mod Toolから修得する

方針2:しかるべきサイトで募集する
・方針1を実施しても、まだ見つからなければ、
 人材募集系のサイト(有料または無料)で募集する


私個人のデザイン技術を磨く気はありませんが、
XSIユーザの会話についていけるようになるだけでも、
充分意味があると思います。
やるからには、前向きに頑張るぞ~!



◎4月の目標

・2009年度年間計画
 →計画概要、目標、スケジュールを2日間で作成すること

・地形モデル
 →性能目標(20fps)を4日以内に達成すること

・XSI Mod Tool修得
 →3日以内に主要機能を一通り把握すること
 →城モデルを2日間で更新すること(モデリング練習)
 →槍兵モデルを3日間で更新すること(モーション練習)

・ドキュメント作成
 →シナリオ概要を1日でまとめること
 →CGの発注条件を1日でまとめること

・その他
 →ブログ更新/HP更新(3日間)
 →休息/予備(6日間)


作業項目毎に日数目標を立てたら、日割計画になっちゃいました。計画が細かすぎるかも。まだ進捗優先の段階じゃないので、日数は目安程度に考えて、柔軟に対応しましょう。

XSI修得に比重を置いたら、プログラムが地形モデルオンリーに…ようやくユニットに移れると思ったのに、ちょっと残念。
でも、全体スケジュールの観点から見ると、3DCG担当者確保を優先すべきなので、仕方ないですね。



◎次回予告

次回は、2009年度年間計画を作成します。

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
t-pot
t-pot
プロのゲームプログラマーのサイト。文字化けする場合は、ブラウザの表示設定を日本語(EUC)とすること。



◎HLSLの型と精度の問題

以前、HLSL内で頂点からパターン番号を取得し、パターンを3種類判別してテクスチャを表示する所までやりました。まずその状態に戻そうとしたのですが、パターン番号をうまく判別することができません。

調べていくと、こちらの記事に「整数計算は確実ではない」とあります。パターン番号は8桁整数で管理していたので、もしやこれが原因かと思い、float型に置き換えましたが、それでも思うようにいきません。

どうやら、パターン番号をColor.aに代入し、頂点シェーダからピクセルシェーダに受け渡す際に「1.0以上の値は自動的に丸められる」ようです。結局、以前と同じく「全て小数点以下にずらしてから受け渡す」ことにしました。

output.Color.a = input.Depth / 10000000;
(input.Depthにパターン番号が格納されている)

しかし、上記の処置を施しても、パターン番号が正確に判別できません。小数点以下3桁以内の値は取得できていて、小数点以下4桁目以降の値は取得できていないようでした。

「おかしいなぁ…いくらなんでもfloat型の有効桁数が3桁ってことはないはずだが…」と思いつつfloat型の有効桁数を確認すると「10進数では約7桁(完全なのは6桁まで)」とありました。

げっ、そんなに少なかったっけ?
今のパターン番号は8桁管理なので、1~2桁足りません。

まぁ、その問題は後で考え直すとして、今は有効桁数が6桁にも満たないことが問題です。もしかして「情報落ち」による誤差が発生しているのかと思い、一旦double型に変換してから計算してみましたが、駄目でした。



◎PIX登場

これ以上は実際の値を確認しないと、よくわかりません。というわけで、PIXを起動しました。シェーダーデバッガとして本格的に使うのは、これが初めてです。

適当なピクセルのレンダリング状況をPIXで確認すると…おや?少なくともPIXの画面を見る限り、Color.aの値は0.000~1.000、つまり小数点以下3桁までのようです。

本当に3桁しか無いのか、まいったな~(><)



◎値の受け渡し

有効桁数3桁ではパターン番号情報としては足りなさすぎるので、Color.aの他にピクセルシェーダにパターン番号を渡す方法を探ります。

・記憶域の修飾子
 →static、extern、uniform、sharedいずれを用いても
  ピクセルシェーダへの受け渡し不可。
 →(余談)DirectX HLSLには「nointerpolation:ピクセル
  シェーダーに渡す前に、頂点シェーダーの出力を
  補間しない」という修飾子がありました。欲しい…。

・定数レジスタ
 →Direct3D 9のasmシェーダーのリファレンスには、
  浮動小数点型定数レジスタがピクセルシェーダー
  入力レジスタと記述されていますが、
  このレジスタをHLSLで直接制御する方法が不明。
 →HLSL上では、適当に宣言した変数は
  自動的に定数レジスタに格納されるようですが、
  ピクセルシェーダから参照すると0になります。
  (:register(c0)などと指定した場合も同様)

・Color1セマンティクス
 →このセマンティクスを利用すると、値の受け渡しに成功。

というわけで、Color1セマンティクスの.r/.g/.b/.aに2桁ずつ番号を分解して格納し、ピクセルシェーダに受け渡すことにしました。



◎計算の誤差

output.patternNumber.a = (input.Depth % 100) / 100;

上記の計算結果をPIXで確認すると、誤差が0.005ありました。GPUによって差があるとは思いますが、誤差が0.5%もあったのはちょっと驚きです。

最近のパソコンって、意外といい加減なんですね…。



◎同志発見!

いろいろ調べていたら、こちらのQ&Aを見付けました。

最初は気付きませんでしたが、これって今私がやってることと一緒ですね!このQ&Aは過去に見掛けたことがありましたが、質問内容を読んで関係無いと判断し、ずっとスルーしてました(^^;

というわけで、Q&Aを参考に、以下のように変更します。

・VertexElementUsage.Depth → TextureCoordinateに変更
・誤差はround関数で対応する

あとは、頂点フォーマットにパターン番号を格納する「型」を何にするか、ですね。



◎頂点フォーマットの型

「今のパターン番号は8桁管理なので、float型では1~2桁足りない」という問題がありました。

float型でダメならint型にしたかったのですが、VertexElementFormatには単純な(1Dの)int型が存在しません。

う~ん…こうなると、Short4型が一番効率良さそうですね。



◎ベクトル型情報のパック

頂点フォーマットのパターン番号をshort[4]として、パターン番号を分解したら、地形表示がおかしくなりました。頂点バッファのサイズ指定を間違えたかと思って調べていたら「Short4構造体」を発見。short[4]ではなく、これを使ってパックしろってことだったんですね。

…ところが、このShort4型でパックする方法がさっぱり解りません。

こちらの記事を読んで「C#のインターフェイスとは何か?」ぐらいは理解したつもりですが、実際にXNAのIPackedVectorインターフェイスやPackFromVector4メソッドを使おうとしても、標準的な実装方法が全然分かりません。

・IPackedVectorは頂点フォーマットの引数の型として
 使用するものなのか?別途クラスか構造体を
 用意する必要があるのか?

・インターフェイスには実態が無い。PackFromVector4
 メソッドの実態はどのように用意すべきなのか?

ここで相当ハマりましたが、結局パック方法は解明できませんでした。サンプルも全然見当たらないし…遺憾ではありますが、Short4は諦めて、Vector4にします。



◎次回予告

4月になったので、次回は「3月の反省と4月の目標」です。

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

| BLOG TOP |

copyright © ゲーム制作の舞台裏 all rights reserved.Powered by FC2ブログ
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。