Overview
I am currently trying to create a vertex shader in Unreal Engine. The project does build, however the Editor crashes while attempting to retrieve my shader file. I acquire the error message in the log Couldn't find source file of virtual shader path '/Engine/Shaders/Private/DemoShader.usf'
. Despite constant research, I have yet to fix this issue.
Shader Module
In order to include shaders in my project, I have created a game module named ShadersModule
, which is implemented in my ShadersModule CPP file. All code shown, with exception to the DemoShader USF file, is contained within ShadersModule
. This module includes RenderCore
as a public dependency. Additionally, the primary game module includes ShadersModule
as a public dependency. Due to when shaders need to be loaded, ShadersModule
’s loading phase is set to PostConfigInit
in my uproject file.
Shader Registration (Face Value Problem)
So far, I think it is likely that my implementation of the IMPLEMENT_SHADER_TYPE
macro is failing to register my vertex shader. This is due to the crash log stating Couldn't find source file of virtual shader path '/Engine/Shaders/Private/DemoShader.usf'
. Various references I have found use different virtual paths to my own, however none of them appear to have worked for me so far. I have been led to believe that the intended virtual path has changed across Unreal Engine versions, which might be my issue. Most references I have found use various Unreal Engine 4 versions. I am using Unreal Engine v5.1.1 with a C++ project. I attempt to register the shader in my DemoShaderVS CPP file with the following line:
IMPLEMENT_SHADER_TYPE(, FDemoShaderVS, TEXT("/Engine/Shaders/Private/DemoShader.usf"), TEXT("MainVS"), SF_Vertex);
Shader Directory Mapping
Project Shader Path
I have created a directory to locate my shader file within my project at /Shaders
. Within this, I have created two subdirectories, Private
& Public
. I have been made aware these distinctions are necessary, however I feel unsure as to whether this is strictly the case. Regardless, my shader is in the Private
folder.
Virtual Shader Path
Setup
I have mapped my project’s shader directory to Unreal Engine’s virtual shader directory in my ShadersModule header file. This was done by creating a subclass of IModuleInterface
, which in my case is named FShaderModule
. I have overriden the StartupModule()
function & I execute AddShaderSourceDirectoryMapping()
in order to map my path.
Errors
My previous mappings used to throw errors when I started the Editor, however I believe this has ceased with the use of the /Engine/Shaders/Private
path. When this used to present an error, the crash log suggested I use the aforementioned path. However, I have found this to be particularly confusing. Despite requiring a virtual path, the aforementioned path is a real path within my Engine directory. I am also wondering if the paths are correct, but if they are not being mapped prior to the Engine attempting to retrieve my shader. If this is the case, I don’t know why this would be. Regardless, I currently map the directories as follows:
FString shaderDirectory = FPaths::Combine(FPaths::ProjectDir(), TEXT("Shaders/Private"));
AddShaderSourceDirectoryMapping("/Engine/Shaders/Private", shaderDirectory);
Conclusion
The rest of my code that I felt is worth sharing is below. I have also included more of the crash log. Any help would be extremely appreciated.^^
Crash Log
[2024.04.01-15.52.08:239][ 0]LogShaderCompilers: Guid format shader working directory is -23 characters bigger than the processId version (…/…/…/…/…/…/Work/UEShadersLecture/Unreal-Engine-Shader-Tutorial/Intermediate/Shaders/WorkingDirectory/5872/).
[2024.04.01-15.52.08:239][ 0]LogShaderCompilers: Cleaned the shader compiler working directory ‘C:/Users/sebas/AppData/Local/Temp/UnrealShaderWorkingDir/D99A674B446DB527F664749B032B2CE2/’.
[2024.04.01-15.52.08:241][ 0]LogXGEController: Cannot use XGE Controller as Incredibuild is not installed on this machine.
[2024.04.01-15.52.08:241][ 0]LogShaderCompilers: Display: Using Local Shader Compiler with 9 workers.
[2024.04.01-15.52.08:251][ 0]LogShaders: InitializeShaderTypes() begin
[2024.04.01-15.52.08:253][ 0]LogShaders: Shader directory mapping /Engine → …/…/…/Engine/Shaders
[2024.04.01-15.52.08:253][ 0]LogShaders: Shader directory mapping /ShaderAutogen → D:/Work/UEShadersLecture/Unreal-Engine-Shader-Tutorial/Intermediate/ShaderAutogen
[2024.04.01-15.52.08:253][ 0]LogShaders: Shader directory mapping /Plugin/GLTFExporter → …/…/…/Engine/Plugins/Enterprise/GLTFExporter/Shaders
[2024.04.01-15.52.08:253][ 0]LogShaders: Shader directory mapping /Plugin/FX/Niagara → …/…/…/Engine/Plugins/FX/Niagara/Shaders
[2024.04.01-15.52.08:253][ 0]LogShaders: Shader directory mapping /Plugin/ExrReaderShaders → …/…/…/Engine/Plugins/Media/ImgMedia/Shaders
[2024.04.01-15.52.08:254][ 0]LogShaders: Shader directory mapping /Plugin/WmfMedia → …/…/…/Engine/Plugins/Media/WmfMedia/Shaders
The thread ‘FIOSDeviceHelper.QueryTask_1’ (31408) has exited with code 0 (0x0).
[2024.04.01-15.52.10:641][ 0]LogTurnkeySupport: Completed SDK detection: ExitCode = 0
The thread ‘FMonitoredProcess 0’ (26900) has exited with code 0 (0x0).
Fatal error: [File:D:\build++UE5\Sync\Engine\Source\Runtime\RenderCore\Private\ShaderCore.cpp] [Line: 999]
Couldn’t find source file of virtual shader path ‘/Engine/Shaders/Private/DemoShader.usf’
A breakpoint instruction (__debugbreak() statement or a similar call) was executed in UnrealEditor.exe.
A breakpoint instruction (__debugbreak() statement or a similar call) was executed in UnrealEditor.exe.
[2024.04.01-15.52.17:712][ 0]LogWindows: Error: appError called: Fatal error: [File:D:\build++UE5\Sync\Engine\Source\Runtime\RenderCore\Private\ShaderCore.cpp] [Line: 999]
Couldn’t find source file of virtual shader path ‘/Engine/Shaders/Private/DemoShader.usf’
[2024.04.01-15.52.17:712][ 0]LogWindows: Windows GetLastError: The operation completed successfully. (0)
[2024.04.01-15.52.17:712][ 0]LogWindows: Error: === Critical error: ===
[2024.04.01-15.52.17:712][ 0]LogWindows: Error:
[2024.04.01-15.52.17:712][ 0]LogWindows: Error: Fatal error: [File:D:\build++UE5\Sync\Engine\Source\Runtime\RenderCore\Private\ShaderCore.cpp] [Line: 999]
[2024.04.01-15.52.17:712][ 0]LogWindows: Error: Couldn’t find source file of virtual shader path ‘/Engine/Shaders/Private/DemoShader.usf’
ShadersModule Header
#pragma once
#include "CoreMinimal.h"
#include "Modules/ModuleInterface.h"
#include "Modules/ModuleManager.h"
class SHADERSMODULE_API FShaderModule : public IModuleInterface {
public:
static inline FShaderModule& Get()
{
return FModuleManager::LoadModuleChecked<FShaderModule>("ShadersModule");
}
static inline bool IsAvailable()
{
return FModuleManager::Get().IsModuleLoaded("ShadersModule");
}
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};
ShadersModule CPP
// Copyright Epic Games, Inc. All Rights Reserved.
#include "ShadersModule.h"
#include "Modules/ModuleManager.h"
IMPLEMENT_GAME_MODULE(FDefaultGameModuleImpl, ShadersModule);
void FShaderModule::StartupModule()
{
FString shaderDirectory = FPaths::Combine(FPaths::ProjectDir(), TEXT("Shaders/Private"));
AddShaderSourceDirectoryMapping("/Engine/Shaders/Private", shaderDirectory);
}
void FShaderModule::ShutdownModule()
{
ResetAllShaderSourceDirectoryMappings();
}
DemoShaderVS Header
#pragma once
#include "GlobalShader.h"
class FDemoShaderVS : public FGlobalShader
{
DECLARE_EXPORTED_SHADER_TYPE(FDemoShaderVS, Global, SHADERSMODULE_API);
FDemoShaderVS() { }
FDemoShaderVS(const ShaderMetaType::CompiledShaderInitializerType& Initializer)
: FGlobalShader(Initializer)
{
}
static bool ShouldCache(EShaderPlatform Platform)
{
return true;
}
};
DemoShaderVS CPP
#include "DemoShaderVS.h"
IMPLEMENT_SHADER_TYPE(, FDemoShaderVS, TEXT("/Engine/Shaders/Private/DemoShader.usf"), TEXT("MainVS"), SF_Vertex);
DemoShader USF
void MainVS(
in float4 InPosition : ATTRIBUTE0,
out float4 Output : SV_POSITION
)
{
Output = InPosition;
}
// Simple solid color pixel shader
float4 MyColor;
float4 MainPS() : SV_Target0
{
return MyColor;
}