It’s the nanitebasepass. I stripped the level down all the way, put on a simple color material, removed the PCG scattered nanite rocks so that it’s just a barren landscape, removed the water as well. I deleted all my lighting/clouds/etc, opened the environmental light mixer, click click click for directional light, sky atmosphere and skylight. Turned the sun intensity down and angled it.
Here are the results for the stat gpu with scalability set to epic:
VK: 0.26
DX12: 6.87
26x longer on the nanite base pass with DX12 for some reason.
Another thing I noticed while experimenting was that my original material for my landscape seemed to bog DX12 down a lot more than it did Vulkan. The material wasn’t terribly complex, but it was three layers of albedo+normal+ORD(not using displacement), along with some noise textures(built in ones) for variation and two channels for the landscape coordinate scaled splatmaps(only two channels).
Base pass shader: 463 instructions
Stats: Resources Used: 15
Resource Limit: 64
Samplers Used: 12
Sampler Limit: 32
I should also mention that for testing, I manually ported all of this to a fresh new project created with 5.5 because I was worried that something was bugging out or maybe some cvar was set differently in the console that I forgot about, when upgrading a project from 5.4 to 5.5, and that 5.5 was using some different settings or something.
EDIT:
I rebuilt the game(shipping) again, but this time with two versions of the map and a key to switch between them. Map A has the landscape set to use nanite, map B is set to use the regular landscape. After building the game, I’m now finding that DX12 is performing 5-10% better than Vulkan. Maybe there was some broken shader or something that sponaneously fixed itself? I have absolutely no clue how or why it’s working now, after having spent a ton of time reliably reproducing the performance degredation with DX12.
EDIT2:
Now I’m having another issue on a second launch with DX12:
LowLevelFatalError [File:D:\build\++UE5\Sync\Engine\Source\Runtime\D3D12RHI\Private\D3D12Util.cpp] [Line: 998]
RayTracingDevice->CreateStateObject(&Desc, IID_PPV_ARGS(Result.GetInitReference())) failed
at D:\build\++UE5\Sync\Engine\Source\Runtime\D3D12RHI\Private\D3D12RayTracing.cpp:663
with error E_INVALIDARG
I have to go into my appdata local directory for the game’s saved information and delete the *.upipelinecache
in order to fix it. Again, if I delete that file, launch the game with DX12, it will work fine. I then close the game, and try to launch it a second time, it will crash with an error like this every time until I delete that file again.
I should also note that this is directly tied to running r.Lumen.HardwareRayTracing 1
during runtime(I have a keybind to enable/disable it). It’s disabled in the project settings, but can be turned on/off at runtime. If I don’t enable this, I won’t get the crash when reopening the game again. If I enable it or enable->disable it during runtime, it will crash with this D3D12RayTracing.cpp related error every time when trying to reopen the game. My guess is that since the game has it disabled by default, when it launches, it checks that upipelinecache for what it needs and in that cache and the data is still tied to having lumenHWRT enabled, instead of disabled; causing the crash, since it’s a mismatch. I just rebuilt again, this time with lumen HWRT enabled in the project settings (on begin play, I disable it with the above command). Still causes the crash on subsequent relaunches on DX12 until that cache file is deleted.