お世話になっております。
UStaticMesh::BuildFromMeshDescription で生成されたメッシュについて
UVChannels が必ず 8 になるという症状が発生しています。
原因としては LODResources.VertexBuffers.StaticMeshVertexBuffer.Init() で渡された
VertexInstanceUVs.GetNumChannels() が使用されておらず、
MakeConstMeshBuildVertexView() で MAX_STATIC_TEXCOORDS 分の UVChannel が必ず生成されている点かと
思うのですが、こちらは不具合になりますでしょうか?
また、この関数を用いて生成した StaticMesh をファイルとして保存し、その StaticMesh アセットを編集しようとした際、
UVChannel が 8 の表示の表示にも関わらず UV メニューから Remove Selected で UVChannel 削除ができなくなります。
こちらについては UV Channels の表示は StaticMeshVertexBuffer.GetNumTexCoords() = 8 で行っているのに対し、
FStaticMeshEditor::CanRemoveUVChannel では GetNumUVChannels() = 1 となって
削除できないという不整合が発生しているのではと考えています。
最終的には UStaticMesh::BuildFromMeshDescription で生成したメッシュの不要な UVChannels を
削除したい(もしくは生成しない)のですが、ワークアラウンドはございますでしょうか?
お手数ですが、宜しくお願い致します。
[Attachment Removed]
あけましておめでとうございます。
今年もよろしくお願いします。
また、オフィスがクローズしていたため、返事がおくれました。もうしわけありません。
UE5lは最大8個のUVチャンネルをサポートしており、StaticMeshのレンダリング処理では、実際に使っていなくても8チャンネル分の領域を確保することがあります。
そのため、メッシュとしてはUVを1つしか使っていない場合でも、エディタ上ではUVチャンネルが8個あるように見えることがあります。
一方で、他の処理では論理的なUV数を見ているため、この食い違いが原因で、UIからUVを削除できないといった挙動になるかと思います。
回避方法としては、UStaticMesh::BuildFromMeshDescriptionを呼ぶ前に、FMeshDescriptionから不要なUVチャンネルを削除しておくことかと思います。
あらかじめMeshDescriptionを整理しておけば、内部のバッファが8チャンネル分確保されていたとしても、論理的なUV情報は正しくなり、エディタやツールが混乱しなくなります。
すでにStaticMeshアセットが作成されている場合は、エディタ専用のStaticMeshEditorSubsystemを使ってUVチャンネルを削除することもできます。その際、GetNumUVChannels()の値をそのまま信用すると、エディタ表示と合わない場合があるので注意が必要です。どのUVを残して、どれを削除したいのかを明確にしたうえで処理するのが無難です。
レンダリング用の頂点バッファ自体を8チャンネル未満にするのは、エンジンのソースを変更しない限り現実的ではありませんし、あまり推奨できないと思います。そのため、実用的には論理的なUVチャンネルをきれいな状態に保つことを意識するのが一番の解決策になります。
もしそれでもまだ問題になっていたら、遠慮せず教えてください。
お手数ですが、よろしくお願いします。
[Attachment Removed]
ご回答ありがとうございます。
本年もどうぞ宜しくお願い致します。
> 回避方法としては、UStaticMesh::BuildFromMeshDescriptionを呼ぶ前に、FMeshDescriptionから不要なUVチャンネルを削除
こちら、詳細をお伺いしたいのですが FMeshDescription の UVs になりますでしょうか?
そちらについては既に 1 になっていますが、最終的に UStaticMesh::BuildFromMeshDescription からコールされる
void FStaticMeshVertexBuffer::Init(const TArray<FStaticMeshBuildVertex>& InVertices, uint32 InNumTexCoords, const FStaticMeshVertexBufferFlags & InInitFlags)
にて、この数は使用されていないという認識となります。
> エディタ専用のStaticMeshEditorSubsystemを使ってUVチャンネルを削除
RemoveUVChannel になるかと思いますが、こちらは GetNumUVChannels が用いられている関係で 8 ではなく 1 が返却されるため、エラーチェックではじかれてしまうようでした。
問題が発生しているアセットについてですが、Text3D Plugin にある void FText3DGlyph::Build(UStaticMesh* StaticMesh, UMaterial* DefaultMaterial)
にてコールされる UStaticMesh::BuildFromMeshDescriptions を通して作成したものになりますが、
無駄な UV チャンネルでアセットサイズが大きくなっているようでしたので削除したいという意図となります。
お手数ですが、宜しくお願い致します。
[Attachment Removed]
void FStaticMeshVertexBuffer::Init(const TArray<FStaticMeshBuildVertex>& InVertices, uint32 InNumTexCoords, const FStaticMeshVertexBufferFlags & InInitFlags)
{
FConstMeshBuildVertexView VertexView = MakeConstMeshBuildVertexView(InVertices);
VertexView.UVs.SetNum(InNumTexCoords, true); // InNumTexCoords 分に制限
Init(VertexView, InInitFlags);
}
エンジン側の改造が必要なため、検証ができておらず恐縮ですが送られてきた InNumTexCoords に制限をかけてしまう必要があるのではないかと考えております。
[Attachment Removed]
VertexView.UVs.SetNum(InNumTexCoords, true); // InNumTexCoords 分に制限一度 MakeConstMeshBuildVertexView 内で MAX_STATIC_TEXCOORDS 分確保されたものを削除する形になっているため、少し処理的に無駄な部分があるかとは思いますが、
試しに入れて検証してみたところ、UVChannel が正しい状態の StaticMesh が生成できるようになったことを確認致しました。
宜しくお願い致します。
[Attachment Removed]
お世話になっております。
フォローアップと詳細な検証、ありがとうございます。
ご確認いただいた内容について整理しますと、今回お試しいただいた対応は、ご提案した回避策そのものではなく、ご自身で特定された箇所に対する修正になりますね。調べたら言っしゃる通りでSetNumで回避ができるかと思います。
MakeConstMeshBuildVertexViewの後でVertexView.UVs.SetNum(InNumTexCoords, true) によりUVチャンネル数を明示的に制限することで、期待どおりのUVチャンネル数を持つStaticMeshが生成できることを確認されたという理解です。
この結果から、現在の挙動は意図されたものではない可能性が高いと考えています。
そのため、本件はバグである可能性が高いと判断しています。こちらで開発チームに確認を行い、何か分かり次第、改めてご連絡します。
それまでの間は、ワークアラウンドとして今回の修正をそのままご使用いただいて問題ありません。もし想定外の挙動や追加の問題に気付かれた場合は、遠慮なく再度ご連絡ください。
詳細な調査と検証を行っていただき、ありがとうございました。
[Attachment Removed]
ご確認ありがとうございます。
> MakeConstMeshBuildVertexViewの後でVertexView.UVs.SetNum(InNumTexCoords, true) によりUVチャンネル数を明示的に制限することで、
> 期待どおりのUVチャンネル数を持つStaticMeshが生成できることを確認
はい、上記内容となります。
> 本件はバグである可能性が高いと判断しています。こちらで開発チームに確認を行い、何か分かり次第、改めてご連絡
FStaticMeshVertexBuffer::Init の引数である InNumTexCoords が無視されてしまっている点がありますので、弊社側でも不具合ではないかと考えております。
お手数ですが、進展ありましたらご共有お願い致します。
[Attachment Removed]
お世話になっております。
一旦本件をクローズさせていただきます。
担当者から話の進行があったら改めて知らせていただきます。
引き続きよろしくお願いします。
[Attachment Removed]