Files

172 lines
5.3 KiB
C++
Raw Permalink Normal View History

// Copyright Epic Games, Inc. All Rights Reserved.
#include "NaniteVisualizationMenuCommands.h"
#include "Delegates/Delegate.h"
#include "EditorViewportClient.h"
#include "Framework/Commands/InputChord.h"
#include "Framework/Commands/UIAction.h"
#include "Framework/Commands/UICommandInfo.h"
#include "Framework/Commands/UICommandList.h"
#include "Framework/MultiBox/MultiBoxBuilder.h"
#include "HAL/IConsoleManager.h"
#include "Internationalization/Internationalization.h"
#include "Internationalization/Text.h"
#include "Misc/AssertionMacros.h"
#include "NaniteVisualizationData.h"
#include "Styling/AppStyle.h"
#include "UObject/UnrealNames.h"
Implemented a Nanite visualization overview, with a data-driven tile layout. This is similar to the gbuffer overview, except using a custom global shader instead of the post process material shader approach. Additionally, I managed to do this with just a single Nanite cull/raster pass. We already had a rasterizer permutation for retail vs. any visualization enabled, but it was a single ordinal mode. The rasterizer would do a 64b max and a 32b add. Was worried I needed arrays, multi-pass, strided output buffer, etc.. but then realized max is only used by raster mode, and add is only used by overdraw mode. I changed it all to a bitmask, run the rasterizer with that, and then multi-pass all the modes in screen space off the buffer. Renamed Material Depth -> Material ID, and Hit Proxy Depth -> Hit Proxy ID Moved Material ID into the Standard commands grouping, as it can be useful for content creators. Made the editor hide all the Advanced commands by default, can make them available in the UX with r.Nanite.Visualize.Advanced now. Command line has full access to all of them, regardless of this setting. Renamed r.Nanite.DebugSceneComposite to r.Nanite.Visualize.Composite, and changed the behavior for -1=default, 0=off, 1=on Renamed r.Nanite.DebugSobelFilter to r.Nanite.Visualize.EdgeDetect and defaulted it on for content creator benefit. Removed int4 VisualizeConfig member from Rasterizer UB, and added 32bit visualization mode mask instead. Removed 32bit RasterStateReverseCull member from Rasterizer UB, and folded it into pre-existing 32bit RenderFlags Renamed Nanite::FDebugVisualizeCS -> Nanite::FNaniteVisualizeCS Renamed DebugVisualize.usf -> Visualize.usf Made all visualizations composite against scene depth by default, except the overdraw mode. Changed overdraw view mode to use ColorMapInferno from ColorMap.ush #rb brian.karis #fyi michal.valient, rune.stubbe [CL 15828833 by graham wihlidal in ue5-main branch]
2021-03-25 15:02:12 -04:00
int32 GNaniteVisualizeAdvanced = 0;
static FAutoConsoleVariableRef CVarNaniteVisualizeAdvanced(
TEXT("r.Nanite.Visualize.Advanced"),
GNaniteVisualizeAdvanced,
TEXT("")
);
#define LOCTEXT_NAMESPACE "NaniteVisualizationMenuCommands"
FNaniteVisualizationMenuCommands::FNaniteVisualizationMenuCommands()
: TCommands<FNaniteVisualizationMenuCommands>
(
TEXT("NaniteVisualizationMenu"), // Context name for fast lookup
NSLOCTEXT("Contexts", "NaniteVisualizationMenu", "Nanite Visualization"), // Localized context name for displaying
NAME_None, // Parent context name.
FAppStyle::GetAppStyleSetName() // Icon Style Set
),
CommandMap()
{
}
void FNaniteVisualizationMenuCommands::BuildCommandMap()
{
const FNaniteVisualizationData& VisualizationData = GetNaniteVisualizationData();
const FNaniteVisualizationData::TModeMap& ModeMap = VisualizationData.GetModeMap();
CommandMap.Empty();
for (FNaniteVisualizationData::TModeMap::TConstIterator It = ModeMap.CreateConstIterator(); It; ++It)
{
const FNaniteVisualizationData::FModeRecord& Entry = It.Value();
FNaniteVisualizationRecord& Record = CommandMap.Add(Entry.ModeName, FNaniteVisualizationRecord());
Record.Name = Entry.ModeName;
Record.Command = FUICommandInfoDecl(
this->AsShared(),
Entry.ModeName,
Entry.ModeText,
Implemented a Nanite visualization overview, with a data-driven tile layout. This is similar to the gbuffer overview, except using a custom global shader instead of the post process material shader approach. Additionally, I managed to do this with just a single Nanite cull/raster pass. We already had a rasterizer permutation for retail vs. any visualization enabled, but it was a single ordinal mode. The rasterizer would do a 64b max and a 32b add. Was worried I needed arrays, multi-pass, strided output buffer, etc.. but then realized max is only used by raster mode, and add is only used by overdraw mode. I changed it all to a bitmask, run the rasterizer with that, and then multi-pass all the modes in screen space off the buffer. Renamed Material Depth -> Material ID, and Hit Proxy Depth -> Hit Proxy ID Moved Material ID into the Standard commands grouping, as it can be useful for content creators. Made the editor hide all the Advanced commands by default, can make them available in the UX with r.Nanite.Visualize.Advanced now. Command line has full access to all of them, regardless of this setting. Renamed r.Nanite.DebugSceneComposite to r.Nanite.Visualize.Composite, and changed the behavior for -1=default, 0=off, 1=on Renamed r.Nanite.DebugSobelFilter to r.Nanite.Visualize.EdgeDetect and defaulted it on for content creator benefit. Removed int4 VisualizeConfig member from Rasterizer UB, and added 32bit visualization mode mask instead. Removed 32bit RasterStateReverseCull member from Rasterizer UB, and folded it into pre-existing 32bit RenderFlags Renamed Nanite::FDebugVisualizeCS -> Nanite::FNaniteVisualizeCS Renamed DebugVisualize.usf -> Visualize.usf Made all visualizations composite against scene depth by default, except the overdraw mode. Changed overdraw view mode to use ColorMapInferno from ColorMap.ush #rb brian.karis #fyi michal.valient, rune.stubbe [CL 15828833 by graham wihlidal in ue5-main branch]
2021-03-25 15:02:12 -04:00
Entry.ModeDesc)
.UserInterfaceType(EUserInterfaceActionType::RadioButton)
.DefaultChord(FInputChord()
);
switch (Entry.ModeType)
{
default:
case FNaniteVisualizationData::FModeType::Overview:
Record.Type = FNaniteVisualizationType::Overview;
break;
case FNaniteVisualizationData::FModeType::Standard:
Record.Type = FNaniteVisualizationType::Standard;
break;
case FNaniteVisualizationData::FModeType::Advanced:
Record.Type = FNaniteVisualizationType::Advanced;
break;
}
}
}
void FNaniteVisualizationMenuCommands::BuildVisualisationSubMenu(FMenuBuilder& Menu)
{
Implemented a Nanite visualization overview, with a data-driven tile layout. This is similar to the gbuffer overview, except using a custom global shader instead of the post process material shader approach. Additionally, I managed to do this with just a single Nanite cull/raster pass. We already had a rasterizer permutation for retail vs. any visualization enabled, but it was a single ordinal mode. The rasterizer would do a 64b max and a 32b add. Was worried I needed arrays, multi-pass, strided output buffer, etc.. but then realized max is only used by raster mode, and add is only used by overdraw mode. I changed it all to a bitmask, run the rasterizer with that, and then multi-pass all the modes in screen space off the buffer. Renamed Material Depth -> Material ID, and Hit Proxy Depth -> Hit Proxy ID Moved Material ID into the Standard commands grouping, as it can be useful for content creators. Made the editor hide all the Advanced commands by default, can make them available in the UX with r.Nanite.Visualize.Advanced now. Command line has full access to all of them, regardless of this setting. Renamed r.Nanite.DebugSceneComposite to r.Nanite.Visualize.Composite, and changed the behavior for -1=default, 0=off, 1=on Renamed r.Nanite.DebugSobelFilter to r.Nanite.Visualize.EdgeDetect and defaulted it on for content creator benefit. Removed int4 VisualizeConfig member from Rasterizer UB, and added 32bit visualization mode mask instead. Removed 32bit RasterStateReverseCull member from Rasterizer UB, and folded it into pre-existing 32bit RenderFlags Renamed Nanite::FDebugVisualizeCS -> Nanite::FNaniteVisualizeCS Renamed DebugVisualize.usf -> Visualize.usf Made all visualizations composite against scene depth by default, except the overdraw mode. Changed overdraw view mode to use ColorMapInferno from ColorMap.ush #rb brian.karis #fyi michal.valient, rune.stubbe [CL 15828833 by graham wihlidal in ue5-main branch]
2021-03-25 15:02:12 -04:00
const bool bShowAdvanced = GNaniteVisualizeAdvanced != 0;
const FNaniteVisualizationMenuCommands& Commands = FNaniteVisualizationMenuCommands::Get();
if (Commands.IsPopulated())
{
Menu.BeginSection("LevelViewportNaniteVisualizationMode", LOCTEXT("NaniteVisualizationHeader", "Nanite Visualization Mode"));
if (Commands.AddCommandTypeToMenu(Menu, FNaniteVisualizationType::Overview))
{
Menu.AddMenuSeparator();
}
if (Commands.AddCommandTypeToMenu(Menu, FNaniteVisualizationType::Standard))
{
Implemented a Nanite visualization overview, with a data-driven tile layout. This is similar to the gbuffer overview, except using a custom global shader instead of the post process material shader approach. Additionally, I managed to do this with just a single Nanite cull/raster pass. We already had a rasterizer permutation for retail vs. any visualization enabled, but it was a single ordinal mode. The rasterizer would do a 64b max and a 32b add. Was worried I needed arrays, multi-pass, strided output buffer, etc.. but then realized max is only used by raster mode, and add is only used by overdraw mode. I changed it all to a bitmask, run the rasterizer with that, and then multi-pass all the modes in screen space off the buffer. Renamed Material Depth -> Material ID, and Hit Proxy Depth -> Hit Proxy ID Moved Material ID into the Standard commands grouping, as it can be useful for content creators. Made the editor hide all the Advanced commands by default, can make them available in the UX with r.Nanite.Visualize.Advanced now. Command line has full access to all of them, regardless of this setting. Renamed r.Nanite.DebugSceneComposite to r.Nanite.Visualize.Composite, and changed the behavior for -1=default, 0=off, 1=on Renamed r.Nanite.DebugSobelFilter to r.Nanite.Visualize.EdgeDetect and defaulted it on for content creator benefit. Removed int4 VisualizeConfig member from Rasterizer UB, and added 32bit visualization mode mask instead. Removed 32bit RasterStateReverseCull member from Rasterizer UB, and folded it into pre-existing 32bit RenderFlags Renamed Nanite::FDebugVisualizeCS -> Nanite::FNaniteVisualizeCS Renamed DebugVisualize.usf -> Visualize.usf Made all visualizations composite against scene depth by default, except the overdraw mode. Changed overdraw view mode to use ColorMapInferno from ColorMap.ush #rb brian.karis #fyi michal.valient, rune.stubbe [CL 15828833 by graham wihlidal in ue5-main branch]
2021-03-25 15:02:12 -04:00
if (bShowAdvanced)
{
Menu.AddMenuSeparator();
}
}
Implemented a Nanite visualization overview, with a data-driven tile layout. This is similar to the gbuffer overview, except using a custom global shader instead of the post process material shader approach. Additionally, I managed to do this with just a single Nanite cull/raster pass. We already had a rasterizer permutation for retail vs. any visualization enabled, but it was a single ordinal mode. The rasterizer would do a 64b max and a 32b add. Was worried I needed arrays, multi-pass, strided output buffer, etc.. but then realized max is only used by raster mode, and add is only used by overdraw mode. I changed it all to a bitmask, run the rasterizer with that, and then multi-pass all the modes in screen space off the buffer. Renamed Material Depth -> Material ID, and Hit Proxy Depth -> Hit Proxy ID Moved Material ID into the Standard commands grouping, as it can be useful for content creators. Made the editor hide all the Advanced commands by default, can make them available in the UX with r.Nanite.Visualize.Advanced now. Command line has full access to all of them, regardless of this setting. Renamed r.Nanite.DebugSceneComposite to r.Nanite.Visualize.Composite, and changed the behavior for -1=default, 0=off, 1=on Renamed r.Nanite.DebugSobelFilter to r.Nanite.Visualize.EdgeDetect and defaulted it on for content creator benefit. Removed int4 VisualizeConfig member from Rasterizer UB, and added 32bit visualization mode mask instead. Removed 32bit RasterStateReverseCull member from Rasterizer UB, and folded it into pre-existing 32bit RenderFlags Renamed Nanite::FDebugVisualizeCS -> Nanite::FNaniteVisualizeCS Renamed DebugVisualize.usf -> Visualize.usf Made all visualizations composite against scene depth by default, except the overdraw mode. Changed overdraw view mode to use ColorMapInferno from ColorMap.ush #rb brian.karis #fyi michal.valient, rune.stubbe [CL 15828833 by graham wihlidal in ue5-main branch]
2021-03-25 15:02:12 -04:00
if (bShowAdvanced)
{
Commands.AddCommandTypeToMenu(Menu, FNaniteVisualizationType::Advanced);
}
Menu.EndSection();
}
}
bool FNaniteVisualizationMenuCommands::AddCommandTypeToMenu(FMenuBuilder& Menu, const FNaniteVisualizationType Type) const
{
bool bAddedCommands = false;
const TNaniteVisualizationModeCommandMap& Commands = CommandMap;
for (TCommandConstIterator It = CreateCommandConstIterator(); It; ++It)
{
const FNaniteVisualizationRecord& Record = It.Value();
if (Record.Type == Type)
{
Menu.AddMenuEntry(Record.Command, NAME_None, Record.Command->GetLabel());
bAddedCommands = true;
}
}
return bAddedCommands;
}
FNaniteVisualizationMenuCommands::TCommandConstIterator FNaniteVisualizationMenuCommands::CreateCommandConstIterator() const
{
return CommandMap.CreateConstIterator();
}
void FNaniteVisualizationMenuCommands::RegisterCommands()
{
BuildCommandMap();
}
void FNaniteVisualizationMenuCommands::BindCommands(FUICommandList& CommandList, const TSharedPtr<FEditorViewportClient>& Client) const
{
// Map Nanite visualization mode actions
for (FNaniteVisualizationMenuCommands::TCommandConstIterator It = FNaniteVisualizationMenuCommands::Get().CreateCommandConstIterator(); It; ++It)
{
const FNaniteVisualizationMenuCommands::FNaniteVisualizationRecord& Record = It.Value();
CommandList.MapAction(
Record.Command,
FExecuteAction::CreateStatic(&FNaniteVisualizationMenuCommands::ChangeNaniteVisualizationMode, Client.ToWeakPtr(), Record.Name),
FCanExecuteAction(),
FIsActionChecked::CreateStatic(&FNaniteVisualizationMenuCommands::IsNaniteVisualizationModeSelected, Client.ToWeakPtr(), Record.Name)
);
}
}
void FNaniteVisualizationMenuCommands::ChangeNaniteVisualizationMode(TWeakPtr<FEditorViewportClient> WeakClient, FName InName)
{
if (TSharedPtr<FEditorViewportClient> Client = WeakClient.Pin())
{
Client->ChangeNaniteVisualizationMode(InName);
}
}
bool FNaniteVisualizationMenuCommands::IsNaniteVisualizationModeSelected(TWeakPtr<FEditorViewportClient> WeakClient, FName InName)
{
if (TSharedPtr<FEditorViewportClient> Client = WeakClient.Pin())
{
return Client->IsNaniteVisualizationModeSelected(InName);
}
return false;
}
#undef LOCTEXT_NAMESPACE