はかせのラボ

私の頭の中を書いていく雑記ブログです

DirectX12 Lat式ミクさんを正常に描画出来た話

あいさつ

どうも、はかせです。
前回表示したモデルにテクスチャを貼り付けてみました。

概ね正常にできていたのですが、
顔の部分だけおかしくなっていました。

今日はそれを直した話です。

前回のやつ

まずは前回表示したものの確認です。
f:id:hakase0274:20191016171804p:plain

顎と鼻の部分が黒くなっています。
あと少しわかりづらいですが、
目の周り以外が白のダミーテクスチャになっています。

黒くなっている原因

Twitterで教えてもらったのですが、
何やら今回私が使っているLat式のモデルは
一部のサーフェイスが反転しているそうです。

サーフェイスが反転しているため裏面が見えていたというわけですね。
(私は今回特別な処理をしてなかったので裏面は黒)

なのでこれに対処していきます。

対処法

理屈としては黒い裏面が見えているのが問題なので
裏面を描画しなければいいだけです。

DirectX12的に言えば
RasterizerStateのCullModeを変えるだけです。

D3D12_GRAPHICS_PIPELINE_STATE_DESC pipelineStateDesc{};
//pipelineStateDesc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;←NONEでは両面描画されてしまう
pipelineStateDesc.RasterizerState.CullMode = D3D12_CULL_MODE_BACK;//←BACKだと裏面は描画されない

これで裏面の黒い部分は無くなりました。
ただこれでは何も描画されてない面が見えるだけ=不十分です。

何も描画されていないということは透明ということなので
透過処理をすることで裏になっている
本来表であるべき面が見えるようになります。

透過処理はDirectX11の時に何回も吐く思いをしながらやったので
ササっとやります。
気になる人はこの辺をご覧ください
hakase0274.hatenablog.com
hakase0274.hatenablog.com
hakase0274.hatenablog.com
hakase0274.hatenablog.com

では実際にやっていきます。
といってもさっきと同じく
今度はBlendStateの設定を弄るだけです。

//ブレンドステートの設定
pipelineStateDesc.BlendState.AlphaToCoverageEnable = TRUE;
pipelineStateDesc.BlendState.IndependentBlendEnable = FALSE;
for (int i = 0; i < _countof(pipelineStateDesc.BlendState.RenderTarget); ++i)
{
	//見やすくするため変数化
	auto rt= pipelineStateDesc.BlendState.RenderTarget[i];
	rt.BlendEnable = TRUE;
	rt.LogicOpEnable = FALSE;
	rt.SrcBlend = D3D12_BLEND_SRC_ALPHA;
	rt.DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
	rt.BlendOp = D3D12_BLEND_OP_ADD;
	rt.SrcBlendAlpha = D3D12_BLEND_SRC_ALPHA;
	rt.DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA;
	rt.BlendOpAlpha = D3D12_BLEND_OP_ADD;
	rt.LogicOp = D3D12_LOGIC_OP_NOOP;
	rt.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
}

さてこれで黒かった面は消え去り
きれいなミクさんのご尊顔を拝めるはず。
f:id:hakase0274:20191017170142p:plain

ミクさんの顔が血まみれになったぁぁぁ・・・
(赤いのは見やすくするためダミーテクスチャの色を変えたからです)

ただこれできっと黒い問題は解決したはず。
(ダミーを赤にしても黒かったのがなくなったから)

血まみれ問題原因

これは冒頭でも言ったダミーテクスチャが顔についてる問題ですね。
ぐだぐだ言ってもしょうがないんで結論から言うと、
顔の上にもう一個マテリアルが引っ付いてた
ってことでした。

どういうことかって言うと
PMDにしろPMXにしろMMDってのは
トゥーンレンダリングが前提になっています。
(トゥーンレンダリングはまた後日)

なので顔の部分に顔の影用のマテリアルが存在していました。
もちろんその影はトゥーンテクスチャを用いて
描画されるため普通のテクスチャは存在していません。

ですが今回私が作ったやつでは
テクスチャが割り当たっていないマテリアルには
ダミーテクスチャを当てるようにしています。

つまり今回の顔血まみれ事件は原因は
本来割り当てる必要が無かったマテリアルにまで
テクスチャを割り当ててしまったから

です。

なので顔のマテリアルにダミーを当てなきゃいいだけの話です。
ただ私がまだ初心者すぎるせいかうまいやり方が思いつきませんでした。
というかどのマテリアルが顔に当たってるかとかよくわかりません。
(mayaとかblenderなら見れるんだけどね)

なので今回は脳筋戦法で
ダミーを透明テクスチャにしましたw

成果

さて長々と語ってきましたが、
これで今度こそ準備完了です。

ミクさんのご尊顔を拝みましょう。
f:id:hakase0274:20191017172008p:plain

Lat式のミクさんはかわいいですね。
苦労したかいがあります。

あとがき

今回は前回のおかしかった描画を直した話でした。

正直サーフェイスが反転しているなんて
教えてもらわなきゃ気づけなかったかもしれません。

本当に教えていただきありがとうございました。
(名前は許可とってないのでここでは書きません)

今回の記事良ければスターやコメント等よろしくお願いします。
それでは今回はこの辺でノシ

ちなみに

蛇足ですが、
顔の前になんかマテリアルがあるってことを調べたやり方です。
何か特別変わったことをしたわけではなく
CullModeをFRONT(表面を描画しない)にしただけです。

CullModeをFRONTにした時の結果です。
f:id:hakase0274:20191017171612p:plain

黒問題はCullModeが違うので出てますが、
赤い部分は消え去っています。

つまり表面にダミーテクスチャが描画されている
マテリアルがあるということが見えました。