スレ立てるまでもない質問
スレ立てるまでもない質問
こちらのスレッドにはスレッドを立てるほどでもないと思った、単純な質問を投稿して下さい。
その判断は個人に任せます。
【質問例】
Q.現在のDirectX SDKの最新バージョンって何ですか?
など。
その判断は個人に任せます。
【質問例】
Q.現在のDirectX SDKの最新バージョンって何ですか?
など。
最後に編集したユーザー Ciel on 2010年10月26日(火) 20:28 [ 編集 1 回目 ]
oui C'est la Vie♪
Re: スレ立てるまでもない質問
ふと疑問に思ったので投稿させていただきます
DirectX9以降、DirectX10、DirectX11
今現在この中で一番多く使われているものって何でしょうか?
とくに9と10の使用はまったく別物だそうで(ネット情報の受け売り^^;
しかしXPユーザーもまだまだ生き残っているようです
参考までに聞かせてください
DirectX9以降、DirectX10、DirectX11
今現在この中で一番多く使われているものって何でしょうか?
とくに9と10の使用はまったく別物だそうで(ネット情報の受け売り^^;
しかしXPユーザーもまだまだ生き残っているようです
参考までに聞かせてください
Re: スレ立てるまでもない質問
ここで多く使われている DxLib が DirectX 9 対応なので、ここでは DirectX 9 が多く使われていますかね。
p.s. DxLib でつくってるゲームが Ubuntu 上の Wine で動いた。
p.s. DxLib でつくってるゲームが Ubuntu 上の Wine で動いた。
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。
中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。
中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。
Re: スレ立てるまでもない質問
ネットに公開されてる情報は、DirectX9が多いですね。
ただしMicrosoftが旧バージョンのサポートをどんどんしなくなっているので、出来るだけ最新の物でやった方が良いと思われます、
自分も質問なんですが、DirectXで開発した場合、環境依存を解決して作品を公開するにはどうしたら良いんですかね?
ずっとWin32APIで作っていたんで、Releaseモードで吐き出せば良いやと思っていましたが、DirectXはそんな単純なものじゃないみたいですね^^;
ただしMicrosoftが旧バージョンのサポートをどんどんしなくなっているので、出来るだけ最新の物でやった方が良いと思われます、
自分も質問なんですが、DirectXで開発した場合、環境依存を解決して作品を公開するにはどうしたら良いんですかね?
ずっとWin32APIで作っていたんで、Releaseモードで吐き出せば良いやと思っていましたが、DirectXはそんな単純なものじゃないみたいですね^^;
Re: スレ立てるまでもない質問
>>NNKさん
作成したDirectXのバージョンを記載しておいて、ビデオカードもそのバージョン対応のものを
使ってくださいって書いておき、最新のラインタイムをインストールしておいてくださいって、
書いておけばよいのではないでしょうか?
ビデオカードの違いによる、細かなエラーを避けるには、事前のビデオカードの性能を調べておいて、
それぞれのビデオカードの性能に応じた処理をさせるしかないのではないでしょうか?
恐らくDirect9で開発していれば、最近のPCであればほぼ問題なく動くとは思いますけどねぇ。。。
作成したDirectXのバージョンを記載しておいて、ビデオカードもそのバージョン対応のものを
使ってくださいって書いておき、最新のラインタイムをインストールしておいてくださいって、
書いておけばよいのではないでしょうか?
ビデオカードの違いによる、細かなエラーを避けるには、事前のビデオカードの性能を調べておいて、
それぞれのビデオカードの性能に応じた処理をさせるしかないのではないでしょうか?
恐らくDirect9で開発していれば、最近のPCであればほぼ問題なく動くとは思いますけどねぇ。。。
oui C'est la Vie♪
Re: スレ立てるまでもない質問
>>Ciel さん
自分の「最後に!」って日記のコメントを見て頂ければ解ると思いますが、なんとOSがVista以降のPCでも動作しない方が多くて・・・。
DirectX9で開発したんですけどね。
恐らくビデオカードの問題ではないと思いますが、もしからしたら自分のプログラムに問題があるかも知れませんが・・・。
もうちょっと調べてみます。
自分の「最後に!」って日記のコメントを見て頂ければ解ると思いますが、なんとOSがVista以降のPCでも動作しない方が多くて・・・。
DirectX9で開発したんですけどね。
恐らくビデオカードの問題ではないと思いますが、もしからしたら自分のプログラムに問題があるかも知れませんが・・・。
もうちょっと調べてみます。
Re: スレ立てるまでもない質問
10,11はVista以降でしか動きませんから、完全移行するとまだ60%以上いると言われるXPユーザーを切り捨てることになります。梨丸かじり さんが書きました:DirectX11まで出ているにもかかわらずDirectX9安定だったとは・・・
Re: スレ立てるまでもない質問
DirectX9のライブラリの
・d3dx9.lib (リリース版)
・d3dx9d.lib (デバッグ版)
この二つについて。
この組合せのライブラリは、バージョンを問わずありますよね。
それぞれ、リリース版、デバッグ版、だと聞いたのですが、何が違うんでしょうか。
また、前から気になっていた事でDirectXの「D3D」はDirect3Dの略だと思うんですが、「D3DX」は何の略なのでしょうか。
「D3DX」は拡張機能ライブラリだと聞いたので、「Direct3D eXtend」当りの略だと私は思ったのですが。
・d3dx9.lib (リリース版)
・d3dx9d.lib (デバッグ版)
この二つについて。
この組合せのライブラリは、バージョンを問わずありますよね。
それぞれ、リリース版、デバッグ版、だと聞いたのですが、何が違うんでしょうか。
また、前から気になっていた事でDirectXの「D3D」はDirect3Dの略だと思うんですが、「D3DX」は何の略なのでしょうか。
「D3DX」は拡張機能ライブラリだと聞いたので、「Direct3D eXtend」当りの略だと私は思ったのですが。
Re: スレ立てるまでもない質問
一般的な話になりますが、デバッグ版にはソースコードデバッグ用のシンボルが含まれていたり、診断用のトレースメッセージを出力するコードが含まれていたり、実行コードの最適化が行われていなかったりします。Fimbul さんが書きました:それぞれ、リリース版、デバッグ版、だと聞いたのですが、何が違うんでしょうか。
なのでデバッグ版は問題箇所の発見に役立つ代わりに実行速度が遅いです。
公式の記述は無いみたいですがたぶんそうでしょうね。Fimbul さんが書きました:「D3DX」は拡張機能ライブラリだと聞いたので、「Direct3D eXtend」当りの略だと私は思ったのですが。
ヘッダファイルにもD3DXとしか書かれてませんね…。
Re: スレ立てるまでもない質問
普段はデバッグ版を用いて、リリースビルドの時にリリース版を用いるのが無難なのでしょうか。ISLe さんが書きました:デバッグ版は問題箇所の発見に役立つ代わりに実行速度が遅いです。
公式にも無いんですね。ですが、すっきりしました。ISLe さんが書きました:公式の記述は無いみたいですがたぶんそうでしょうね。
Re: スレ立てるまでもない質問
無難という言葉の意図が分からないですが。Fimbul さんが書きました:普段はデバッグ版を用いて、リリースビルドの時にリリース版を用いるのが無難なのでしょうか。
マイクロソフトの開発製品(無償配布のSDK含む)はライセンス上、デバッグ版ライブラリの配布が許可されていません。
なので、デバッグビルドした実行形式を他人に渡すこともできません。
開発中は、デバッグ版でバグの原因究明して、リリース版でテストプレイします。繰り返しです。
配布するのはリリース版です。
というふうに使い分けるのが一般的だと思います。
Re: スレ立てるまでもない質問
と言う事は、掲示板で質問等をする時にライブラリを一緒にアップ出来ないんですね・・・ISLe さんが書きました:マイクロソフトの開発製品(無償配布のSDK含む)はライセンス上、デバッグ版ライブラリの配布が許可されていません。
なので、デバッグビルドした実行形式を他人に渡すこともできません。
Re: スレ立てるまでもない質問
本当はそうなんですよね。Fimbul さんが書きました:と言う事は、掲示板で質問等をする時にライブラリを一緒にアップ出来ないんですね・・・ISLe さんが書きました:マイクロソフトの開発製品(無償配布のSDK含む)はライセンス上、デバッグ版ライブラリの配布が許可されていません。
なので、デバッグビルドした実行形式を他人に渡すこともできません。
SDK丸ごとなら再配布が許可されているものはありますけど、開発環境は相手側で用意してもらうことになります。
Re: スレ立てるまでもない質問
ISLeさん返信ありがとうございました。
また、違う質問をさせてください。
3Dモデルの描画の話です。
1 モデルの描画をPeekMessageでメッセージ処理がない時に行う
2 モデルの描画をWM_TIMERやWM_PAINTで行う(PeekMessageでなくGetMessageを使う)
どちらがいいんでしょうか。
[追記]
WM_PAINTは無効領域が生じたら発行されると聞きました。
ですが、DirectXではウィンドウを隠したりWM_TIMERでInvalidateRect等を呼び出さなくても発行されている気がします。
モデルやカメラ、ライトを操作したりするとWM_PAINTが発行されるのでしょうか。
また、違う質問をさせてください。
3Dモデルの描画の話です。
1 モデルの描画をPeekMessageでメッセージ処理がない時に行う
2 モデルの描画をWM_TIMERやWM_PAINTで行う(PeekMessageでなくGetMessageを使う)
どちらがいいんでしょうか。
[追記]
WM_PAINTは無効領域が生じたら発行されると聞きました。
ですが、DirectXではウィンドウを隠したりWM_TIMERでInvalidateRect等を呼び出さなくても発行されている気がします。
モデルやカメラ、ライトを操作したりするとWM_PAINTが発行されるのでしょうか。
Re: スレ立てるまでもない質問
3Dモデル描画とか関係なしに、精度の高いタイミング(正確なフレームレートとか)を得たいなら前者ですね。Fimbul さんが書きました:3Dモデルの描画の話です。
1 モデルの描画をPeekMessageでメッセージ処理がない時に行う
2 モデルの描画をWM_TIMERやWM_PAINTで行う(PeekMessageでなくGetMessageを使う)
どちらがいいんでしょうか。
精度が悪くても負荷を低くしたいならウィンドウメッセージを使うのもありだと思います。
断言はできませんが、Direct3DのAPIで無効領域が発生することはないと思います。Fimbul さんが書きました:WM_PAINTは無効領域が生じたら発行されると聞きました。
ですが、DirectXではウィンドウを隠したりWM_TIMERでInvalidateRect等を呼び出さなくても発行されている気がします。
モデルやカメラ、ライトを操作したりするとWM_PAINTが発行されるのでしょうか。
ウィンドウプロシージャでWM_PAINTに対してBeginPaint,EndPaintを呼ばずにリターンすると無効領域がクリアされないままなのでWM_PAINTがいつまでも発行され続けますけど。
WM_PAINTに対してBeginPaint,EndPaintを呼び出して戻り値0でリターンするか、ハンドリングしないでDefWindowProcを呼び出してそのまま戻り値とするかどちらかが必須です。
Direct3Dを使うプログラムなら後者ですね。背景ブラシもNULLにして。
Re: スレ立てるまでもない質問
DefWindowProc に処理を渡したら無事にWM_PAINTは発行されなくなりました。ISLe さんが書きました:ウィンドウプロシージャでWM_PAINTに対してBeginPaint,EndPaintを呼ばずにリターンすると無効領域がクリアされないままなのでWM_PAINTがいつまでも発行され続けますけど。
WM_PAINTに対してBeginPaint,EndPaintを呼び出して戻り値0でリターンするか、ハンドリングしないでDefWindowProcを呼び出してそのまま戻り値とするかどちらかが必須です。
Direct3Dを使うプログラムなら後者ですね。背景ブラシもNULLにして。
背景ブラシもNULLにしましたが、これは何のためなんでしょうか。
また、ウィンドウを表示させて何もしなくてもなぜかWM_PAINTが発行されてました。
ウィンドウを表示した直後に無効領域が生じるか、WM_PAINTが発行されるようになっているのでしょうか。
Re: スレ立てるまでもない質問
Direct3Dを使って描画する場合はハメコミ合成状態なので、ウィンドウのクライアント領域は隠れています。Fimbul さんが書きました:背景ブラシもNULLにしましたが、これは何のためなんでしょうか。
なのでGDIでクライアント領域に描画するのは無駄です。
WM_PAINTのハンドラでBeginPaintを呼ぶと、WM_ERASEBKGNDがSENDされて背景ブラシでクライアント領域が塗り潰されます。
ウィンドウの背景ブラシをNULLにすると(デフォルトの)塗り潰しが行われないので無駄を減らせるというわけです。
ちなみにWM_ERASEBKGNDをハンドリングして戻り値1でウィンドウプロシージャを抜けるようにすれば背景を好きなように描画できます。
ウィンドウアプリではWM_PAINTをハンドリングしてクライアント領域に対する描画を行います。Fimbul さんが書きました:また、ウィンドウを表示させて何もしなくてもなぜかWM_PAINTが発行されてました。
ウィンドウを表示した直後に無効領域が生じるか、WM_PAINTが発行されるようになっているのでしょうか。
ウィンドウが最初に表示されるときにはもちろんクライアント領域が描画されなければならないので、最初はクライアント領域全体が無効領域です。
なのでクライアント領域が見えないからといってWM_PAINTを処理しないでおくとウィンドウを開いたときからずっと発行され続けることになります。
Re: スレ立てるまでもない質問
そういうことだったんですね。ISLe さんが書きました:ウィンドウが最初に表示されるときにはもちろんクライアント領域が描画されなければならないので、最初はクライアント領域全体が無効領域です。
なのでクライアント領域が見えないからといってWM_PAINTを処理しないでおくとウィンドウを開いたときからずっと発行され続けることになります。
新しい質問をさせてください。
BeginSceneとEndSceneについてです。
この二つは描画開始宣言と描画終了宣言であり、この間で描画を行わなければならないと良く聞きます。
また、BeginSceneとEndSceneの間は他のスレッドを停止させて描画に専念しているので、BeginSceneとEndSceneの間で処理に時間がかかる事を行ってはならないと聞きました。
ですが、FVFのDrawPrimitiveやメッシュのDrawSubsetをBeginSceneの前で行っても描画されます。
さらに、BeginSceneとEndSceneの間でモデルやカメラ、ライトの計算を行っているコードを良く見ますが、これもBeginSceneより前で行っても処理されます。
しかし、BeginSceneとEndSceneを消したら描画はされなくなりました。
ならば諸々の計算をした後、描画をして、BeginSceneとEndSceneはただ呼び出すだけで、この間は何もしない方がいいような気がします。
この二つの方法どちらが良いのでしょうか。
また、BeginSceneとEndSceneの本当の役割はなんでしょうか。
私が思った方法で描画がされるので、描画の開始終了宣言ではないと思うのですが・・・。
Re: スレ立てるまでもない質問
3Dの描画はGPUが行いますが、高速に処理するために、プログラムが発行した命令をそのまま実行するとは限りません。
BeginScene~EndSceneは一連の命令をGPUにプッシュするための指示です。
このあいだ描画に専念しているというのはまったくのデタラメですね。
EndSceneで締め切られた後、バッファがデバイス画面に表示されるまでのあいだに描画されます。
実際にどのように動作するかはGPU側の実装によりますが、GPU側にとっては命令がバラバラに送られるより、まとめて送られたほうが最適化しやすく、BeginScene/EndSceneはひとまとまりであることを示すための目印となります。
BeginScene~EndSceneのあいだにカメラやライトを変更すると最適化の邪魔になってパフォーマンスに少なからず悪影響を与えると思います。
実測しないと分からないですし環境によっても異なるでしょうが。
BeginScene~EndSceneは一連の命令をGPUにプッシュするための指示です。
このあいだ描画に専念しているというのはまったくのデタラメですね。
EndSceneで締め切られた後、バッファがデバイス画面に表示されるまでのあいだに描画されます。
実際にどのように動作するかはGPU側の実装によりますが、GPU側にとっては命令がバラバラに送られるより、まとめて送られたほうが最適化しやすく、BeginScene/EndSceneはひとまとまりであることを示すための目印となります。
BeginScene~EndSceneのあいだにカメラやライトを変更すると最適化の邪魔になってパフォーマンスに少なからず悪影響を与えると思います。
実測しないと分からないですし環境によっても異なるでしょうが。
Re: スレ立てるまでもない質問
これからは、BeginSceneとEndSceneの間で描画する様にします。ISLe さんが書きました:実際にどのように動作するかはGPU側の実装によりますが、GPU側にとっては命令がバラバラに送られるより、まとめて送られたほうが最適化しやすく、BeginScene/EndSceneはひとまとまりであることを示すための目印となります。
前私が書いた方法ですが、複数のモデルの移動を考えていませんでした。ISLe さんが書きました:BeginScene~EndSceneのあいだにカメラやライトを変更すると最適化の邪魔になってパフォーマンスに少なからず悪影響を与えると思います。
複数のモデルを動かそうとすると、モデルのワールド座標の計算はBeginSceneの前で行い、SetTransformでの設定はBeginSceneの間で行う事になりますよね。
ただ、マテリアルやテクスチャを変えたり、FVFで描画するためにライトを無効する処理はどうしても描画したいモデルの直前(BeginSceneとEndSceneの間)で行う必要があると思います。
これは、仕方がないのでしょうか。
あと、ポイントスプライトについて質問があります。
ポイントスプライトのサイズを0.3fぐらいに設定して、2つのポイントスプライトを描画して異なるテクスチャを貼りました。
しかし、ポイントスプライトのZ座標を大きくした時に、なぜか物体の見かけの大きさは変わりませんでした。
例えば、カメラの位置は(0, 0, -30)、注視点は原点、上向きベクトルはy方向だとして、(10, 0, 0)の位置の物体が奥に移動する(Z座標の値が大きくなる)と物体の見かけの位置が画面の中心によってきますが、これはポイントスプライトでも生じました。
なぜポイントスプライトの見かけの大きさが変わらないんでしょうか。
Re: スレ立てるまでもない質問
先の返信にも書きましたが、このあたりは実測をもとに試行錯誤するしかありません。Fimbul さんが書きました:ただ、マテリアルやテクスチャを変えたり、FVFで描画するためにライトを無効する処理はどうしても描画したいモデルの直前(BeginSceneとEndSceneの間)で行う必要があると思います。
これは、仕方がないのでしょうか。
GPUメーカーもどんどん工夫を進めているので何が最適なのかは分かりませんし将来的に変化する可能性もあります。
もっと重要なのはEndSceneのあと、Presentでデバイス画面を更新するまでのあいだ上手にGPUのレンダリングと並行して処理を進めることです。
EndSceneの直後にPresentしたりするとレンダリングが完了するまで無駄に待つことになります。
そういう仕様だからとしか言えないのですが…。Fimbul さんが書きました:なぜポイントスプライトの見かけの大きさが変わらないんでしょうか。
D3DRS_POINTSCALEENABLEをTRUEに設定すればカメラからの距離に応じたサイズに調整されるみたいですけど。
http://msdn.microsoft.com/ja-jp/library/cc373140.aspx
Re: スレ立てるまでもない質問
EndSceneの後、GPUがデータを受け取って描画を行い、バックバッファとフロントバッファを入れ替えるまでに、「GPUの描画処理時間以下の処理時間の処理」を行うと効率が良いと言う事でしょうか。ISLe さんが書きました:もっと重要なのはEndSceneのあと、Presentでデバイス画面を更新するまでのあいだ上手にGPUのレンダリングと並行して処理を進めることです。
EndSceneの直後にPresentしたりするとレンダリングが完了するまで無駄に待つことになります。
trueにしてあるんですけどね・・・。ISLe さんが書きました:そういう仕様だからとしか言えないのですが…。
D3DRS_POINTSCALEENABLEをTRUEに設定すればカメラからの距離に応じたサイズに調整されるみたいですけど。
ポイントスプライトにテクスチャを貼ってビルボードの代わりに出来ないかと思ったのですが、「まあポイントスプライトはこういうものだ」と思って使うのは諦めます。
Re: スレ立てるまでもない質問
GPUが働いている時間以下の処理でなければならない理由はないですね。Fimbul さんが書きました:EndSceneの後、GPUがデータを受け取って描画を行い、バックバッファとフロントバッファを入れ替えるまでに、「GPUの描画処理時間以下の処理時間の処理」を行うと効率が良いと言う事でしょうか。
GPUとプログラムの処理のどちらが先に終わるかではなくて、互いに相手の処理が終わるのを待っている無駄な時間を少なくすることに意味があるので。
ポイントスケール係数(D3DRS_POINTSCALE_A/D3DRS_POINTSCALE_B/D3DRS_POINTSCALE_C)を設定してないから大きさが変わらないとか。ISLe さんが書きました:trueにしてあるんですけどね・・・。
ポイントスプライトにテクスチャを貼ってビルボードの代わりに出来ないかと思ったのですが、「まあポイントスプライトはこういうものだ」と思って使うのは諦めます。
どのみちポイントスプライトのサイズ計算は透視変換とは異なるのでビルボードの代わりにはならないですけどね。
Re: スレ立てるまでもない質問
済みません。私が何か勘違いしている様で理解できません。ISLe さんが書きました:GPUが働いている時間以下の処理でなければならない理由はないですね。
GPUとプログラムの処理のどちらが先に終わるかではなくて、互いに相手の処理が終わるのを待っている無駄な時間を少なくすることに意味があるので。
GPUが描画を完了したらバッファを入れ替えて表示をしますよね。
描画が完了した時に、別の処理をしていてすぐにバッファを入れ替えられないと無駄な時間が発生しませんか。
ポイントスケール係数を設定したら見た目の大きさが変わりました。ISLe さんが書きました:ポイントスケール係数(D3DRS_POINTSCALE_A/D3DRS_POINTSCALE_B/D3DRS_POINTSCALE_C)を設定してないから大きさが変わらないとか。
どのみちポイントスプライトのサイズ計算は透視変換とは異なるのでビルボードの代わりにはならないですけどね。
ビルボードの代わりにならないのは残念です。
Re: スレ立てるまでもない質問
フレームレートを一定に保つため、レンダリングが完了してからバッファを入れ替えるまで時間が空きます。Fimbul さんが書きました:GPUが描画を完了したらバッファを入れ替えて表示をしますよね。
描画が完了した時に、別の処理をしていてすぐにバッファを入れ替えられないと無駄な時間が発生しませんか。
そのあいだメインCPUを何もせず待たせるのはもったいないですよね。
フレーム落ちしなければどちらが後でもかまわないのですよ。
例えば背景のモブとか他のオブジェクトに影響与えないオブジェクトの内部処理を前のフレームから進めておいて、バッファを入れ替えたらすぐにシーンをプッシュ、レンダリングしている間にメインオブジェクトの内部処理を行いシーンをプッシュ…と交互に進めると並行処理を活用できます。
描画だけなら手前のオブジェクトから描画するほうが速かったりとかありますけど、並行処理を絡めると逆転することがいろいろあります。
負荷のバランスはゲームタイトルごとに、環境にも左右されるので試行錯誤です。
カプコンのMTフレームワークはそのあたりを自動化してるらしいですけど。
Re: スレ立てるまでもない質問
なんとなく分かった様な、難しいですね・・・。ISLe さんが書きました:フレームレートを一定に保つため、レンダリングが完了してからバッファを入れ替えるまで時間が空きます。
そのあいだメインCPUを何もせず待たせるのはもったいないですよね。
フレーム落ちしなければどちらが後でもかまわないのですよ。
例えば背景のモブとか他のオブジェクトに影響与えないオブジェクトの内部処理を前のフレームから進めておいて、バッファを入れ替えたらすぐにシーンをプッシュ、レンダリングしている間にメインオブジェクトの内部処理を行いシーンをプッシュ…と交互に進めると並行処理を活用できます。
描画だけなら手前のオブジェクトから描画するほうが速かったりとかありますけど、並行処理を絡めると逆転することがいろいろあります。
負荷のバランスはゲームタイトルごとに、環境にも左右されるので試行錯誤です。
こういう最適化は是非使いこなしたいですが。