お世話になっております。
オープンワールド等における広大なマップでのWaterZoneの管理手法について質問させてください。
1つのWaterZoneで広大なマップを管理しようとすると、領域に対する解像度が不足してしまい現実的な消費メモリ内では正しく描画することができなくなります。
対策として以下のどちらかを考えております。
1.WaterZoneを分割して管理
・適切なサイズに分割したWaterZoneを複数配置する
・海のような大きな水源を適切に管理できるかが分からない
・水源同士のTransitionをZoneを跨いで行えない
2.WaterZoneをプレイヤーやカメラに追従させる
・プレイヤーに追従させることで必要な範囲のメッシュだけ都度生成させる
・再生成の負荷が高く毎フレームは行えないため一定距離を移動毎に再生成
・ランタイムで移動させることを想定した作りになっているのか分からない
分割方式の場合は配置状況より機械的なセル分割が難しくなるため、追従方式が可能であればその方が良さそうに感じています。
これらのうち、またはそれ以外で推奨される管理手法がございましたらご教授いただきたいです。
[Attachment Removed]
お世話になっております。
広大なマップにおける WaterZone の管理についてですが、弊社では以下の構成を推奨しており、社内プロジェクトでも同様の構成を採用しております。
- WaterZone は広域をカバーするサイズで定義
- Water Body は World Partition によりストリーミング管理
- 「Local Tessellation」機能を有効化
Local Tessellation を有効にした場合、WaterZone 自体は大きく定義されていても、Water Info Texture および Water Mesh のクアッドツリーは常にカメラ周辺の比較的小さな領域のみを高解像度で処理する方式で動作します。
この機能を使用すれば、WaterZone を物理的に分割せず、WaterZone を自前でプレイヤーに追従させなくとも、広域マップにおける低解像度問題を回避できると考えております。
まずは Local Tessellation を有効化した構成にて、現在懸念されている解像度・メモリ使用状況が改善できそうかご確認いただけますと幸いです。
■補足
Water Zoneそのものとは関係ありませんが、広域Waterがらみで補足事項がございます。
Waterプラグインの「BP Brush」を使用すると、このブラシが関与する Landscape Actor 全体が編集時に強制ロードされてしまい(部分読み込みが効かなくなります)、エディタのパフォーマンスやメモリを圧迫することが確認されています。
社内では経験則上、単一 Landscape が 8km × 8km 規模になると Out of Memory が発生しやすくなるとされており、 4km × 4km 程度のLandscapeをタイル状に並べることで回避しています。
なお、本件については Landscape を部分ロードしたままブラシ効果を適用できる新しい仕組みが現在開発中であり、現時点の計画では UE 5.8 から段階的に導入される予定となっております(時期や使用については変更の可能性があります)。
以上、よろしくお願いいたします。
[Attachment Removed]
ご回答ありがとうございます。
「Local Tessellation」の有効化で解像度とメモリの問題が解決できそうであることを確認できました。
ただ、こちらを有効化するとShallowWaterSubSystemの「WriteImpactToNDC」でリクエストを出している水紋が正しく出せないことがあるようです。
(水紋が出ない、不自然な表示になるなど)
現状は水紋を出すために上記の関数を直接呼び出しているのですが、Local Tessellation有効な環境で任意の位置に水紋を出すために必要な対応はございますでしょうか?
補足についてもありがとうございます。
こちら症状は把握しており、「Landscapeに影響」を使用しないことを前提としてWaterBrushManagerを自動的に配置しないようにEngineに変更を加えております。
ご提案いただいた回避策の場合、細かく分割することでBrushの影響がないLandscapeは強制ロードを免れることで症状を抑えている形でしょうか?
その効果を狙っての分割は検討しましたが、水源が多く点在するデザインだと効果が薄く根本解決にはならないことから見送っておりました。
今後のアップデートで改善が入りましたらまた確認させていただきます。
以上、よろしくお願いいたします。
[Attachment Removed]
水紋に関して、まず現状ですがプロジェクト内ではキャラクターのメッシュにコリジョンを含めておらず、そのためか標準的な水紋が確認できない状態でした。
そのためWriteImpactToNDCを用いて直接指定位置に水紋を出す形を利用したいと考えておりました。
しかし、Local Tessellationを有効化すると正しく水紋が出せないことが確認できた、という状態です。
こちらについて、UE5.7.0の環境で新規作成したThirdPersonゲームプロジェクトに対しても症状が確認できました。
プレイヤーが水面に接触した際などの標準的な水紋での発生で、以下の流れで確認しております。
- 新規でThirdPersonゲームプロジェクトを作成
- Water及びWaterAdvancedプラグインを有効化
- プロジェクト設定より「デフォルトの浅瀬サブシステムを使用」を有効化
- オープンワールドの新規レベルを作成し、Lakeを配置
- WaterZoneのLocal Tessellationの有効無効で挙動を確認
症状としては座標によって水紋が出たり出なかったりするようです。
また、水紋が出ているLakeでも静止時も不自然な形状の水紋が出続けるなど正しい挙動ではなさそうでした。
配置例としては以下になります。
- WaterZone(0.0, 0.0, 0.0)
- Lake1(15280.0, 11340.0, 240.0):水紋が出ない
- Lake2(-25830.0, 2920.0, 0.0):水紋が出ない
- Lake3(7850.0, -48830.0, 40.0):水紋が出る
以上、よろしくお願いいたします。
[Attachment Removed]
ご確認ありがとうございます。
問題の症状について協議いただけるとのこと、承知いたしました。
引き続きよろしくお願い致します。
[Attachment Removed]
UE5.8環境で修正されているとのこと、承知いたしました。
現状、プロジェクトとしてはUE5.8へのアップグレード予定はございません。
ただし、他の機能面含め導入することのメリットが見えてきた段階でまた検討を行う想定です。
修正CLの特定については調査いただけているとのことなので、判明しましたらUE5.7環境への修正について共有いただけますと助かります。
以上、よろしくお願いいたします。
[Attachment Removed]
修正方法のご共有ありがとうございます。
いただきました差分を適用することで水紋が正常に発生することを確認できました。
度々申し訳ございません、もう1点Local Tessellationを有効化した際に発生する症状を確認致しました。
以下の条件を満たすSceneCaptureComponent2Dを保有しているアクターがレベルに存在する際、Local Tessellationが有効なWaterZoneに属する水が表示されなくなります。
- 任意のTextureTargetを指定している
- Capture Every Frameが有効
こちらも以前共有させていただいたThirdPersonゲームプロジェクトの設定で再現を確認致しました。
何かしら回避方法などございましたらご教授いただけますと助かります。
以上、よろしくお願いいたします。
[Attachment Removed]
迅速なパッチのご提供ありがとうございます。
適用することで正しく描画されることを確認できました。
現状他に問題はなく、Local Tessellationを有効としたWaterZoneで運用できそうです。
度々ご対応のほどありがとうございました。
以上、よろしくお願いいたします。
[Attachment Removed]
お世話になっております。
回答のご確認ありがとうございます。
> ただ、こちらを有効化するとShallowWaterSubSystemの「WriteImpactToNDC」でリクエストを出している水紋が正しく出せないことがあるようです。
> (水紋が出ない、不自然な表示になるなど)
この症状について確認させてください。Local Tessellation 有効時において、
・プレイヤーが水面に接触した際などの標準的な水紋は正常に発生しておりますでしょうか?
・不具合が生じているのは、WriteImpactToNDC()によって発生させた水紋のみでしょうか?
・現在はNDCベースの水紋のみをご使用でしょうか?
> こちら症状は把握しており、「Landscapeに影響」を使用しないことを前提としてWaterBrushManagerを自動的に配置しないようにEngineに変更を加えております。
> ご提案いただいた回避策の場合、細かく分割することでBrushの影響がないLandscapeは強制ロードを免れることで症状を抑えている形でしょうか?
Engineに変更を加えて問題を回避しているとのこと、承知いたしました。
当方が提案した回避策(内製プロジェクトが採用しているもの)は、ご指摘の通り「細かく分割することでBrushの影響がないLandscapeの強制ロードを免れる」ことを目的にしているものです。
ご迷惑をおかけしますが、本件に関しましては今後のアップデートで中長期的に解決できればと思います。
以上、よろしくお願いいたします。
[Attachment Removed]
お世話になっております。
情報共有およびUE5.7での再現情報をご提供いただき、ありがとうございます。
当方で再現プロジェクトを作成し、開発チームに共有いたしました。
私のほうでは当初 Ocean で動作確認を取っていたのですが、ご指摘のような Lake の配置を採用しますと、確かに Local Tessellation で動作がおかしくなることが確認できます。
開発側と協議のうえ、改めてご返信申し上げますので、少々お時間を頂戴できますと幸いです。
引き続き、よろしくお願いいたします。
※念のため、当方で作成した再現プロジェクトを添付・共有します。
[Attachment Removed]
お世話になっております。
問題の症状ですが、現在の//UE5/Main、すなわちUE5.8相当のコードでは修正されていることが確認されました。
当方で、先日の再現プロジェクトを利用して動作確認をとった動画を添付しましたので、ご参照ください。
ただし、開発チームの視点では、UE5.7段階でのLakeでの水紋の不具合を把握しておらず、最新版で再現しようとしたらすでに直っていた・・・という展開であったため、修正CLがハッキリ分からない状況となっております。特定できないか調査いたしますが、場合によっては複合的なCLの積み重ねにより修正されたもので、洗い出しが困難な可能性もあります。
念のためお聞かせ願いたいのですが、御社のプロジェクトにおかれましては、UE5.8へのアップグレードのご予定などございますでしょうか?
以上、よろしくお願いいたします。
[Attachment Removed]
お世話になっております。
大変お待たせいたしました。
//UE5/Main CL50934094 で修正されたことが確認できましたが、UE5.7に対して不要な変更も入っているため、以下の形で部分的に変更を適用いただければと思います。
Engine/Plugins/Experimental/Water/Source/Runtime/Private/WaterZoneActor.cpp:833-848
bool AWaterZone::GetDynamicWaterInfoCenter(int32 PlayerIndex, FVector& OutCenter) const
{
bool bHasValidZoneLocation = false;
- FVector Center = GetActorLocation();
+ OutCenter = GetActorLocation();
if (const FWaterViewExtension* WaterViewExtension = UWaterSubsystem::GetWaterViewExtension(World))
{
- bHasValidZoneLocation = WaterViewExtension->GetZoneLocation(this, PlayerIndex, Center);
+ bHasValidZoneLocation = WaterViewExtension->GetZoneLocation(this, PlayerIndex, OutCenter);
}
return bHasValidZoneLocation;
}
こちらをUE5.7に適用することで当方では先日お渡しした LocalTessellationIssueInUE58 のビデオと同じ動作結果を得ることができました。
一度ご確認いただけますと幸いです。
以上、よろしくお願いいたします。
[Attachment Removed]
お世話になっております。
差分のご確認ありがとうございました。
また、SceneCaptureComponent2Dがある場合、Local Tessellationが機能しない件、当方でも確認が取れました。
大変申し訳ないことながら、従来把握されていなかった不具合となるため、現在すぐご案内できる回避方法がございません。
調査を進めてまいりますので、少々お時間を頂戴できればと思います。
取り急ぎ、不具合確認した旨、ご返信申し上げます。
[Attachment Removed]
お世話になっております。
五月雨で申し訳ありません。
暫定回避策として、WaterViewExtension.cpp 765行目付近のFWaterViewExtension::BeginRenderViewFamily()末尾部分を以下のようにパッチしていただけますでしょうか。
+ for (const FSceneView* View : InViewFamily.Views)
+ {
+ if (ShouldHaveWaterZoneViewData(*View))
+ {
+ bAnyQuadTreeUpdateRequired = false;
+ break;
+ }
+ }
- bAnyQuadTreeUpdateRequired = false;
}
一旦、これで描画が戻るかと思います。
以上、よろしくお願いいたします。
(4/1 12:35 暫定パッチを簡略化)
[Attachment Removed]
パッチのご確認ありがとうございました。
正式な修正が//UE5/Main CL52379205で入りました(処理内容的には暫定パッチと同じものになります)ので、お時間のある際にお手元のコードを差し替えていただけますと幸いです。
それでは本件は対応済みとしてCloseさせていただきます。
また何か問題が生じた場合は遠慮なくお問い合わせください。
以上、よろしくおh願いいたします。
[Attachment Removed]