Override Engine Shaders in Local Project or Plugin

So, I’ve been looking for an answer to this kind of question for a while. I actually found a solution that works, but I’d like to find a better one. Here’s how I did it on my end.

In my case I wanted to test by overriding the MobileFog.usf file from the engine’s Shaders/Private folder. So, I tricked the engine by virtually mapping the private subfolder like so.

void FCustomShadersModule::StartupModule()
{
  FString BaseDir = FPaths::Combine(FPaths::GameSourceDir(), TEXT("CustomShadersModule));
  FString ModuleShaderDir = FPaths::Combine(BaseDir, TEXT("Shaders"));
  AddShaderSourceDirectoryMapping(TEXT("/Engine/Private"), ModuleShaderDir);
};

void FCustomShadersModule::ShutdownModule()
{
  ResetAllShaderSourceDirectoryMappings();
};

After doing this the engine couldn’t find any other files in the directory, so I ended up having to copy the entire private folder into my module / plugin and not just the single file.

the module also needs to be set to PostConfigInit.

{
		"Name": "CustomShadersModule",
		"Type": "Runtime",
		"LoadingPhase": "PostConfigInit",
		"AdditionalDependencies": [
			"Engine"
		]
}

Everything else is common sense build.cs and includes.


It would be great to find a way to get the file system to override a single file locally.
I feel like I might find answers by digging into this macro.

IMPLEMENT_SHADER_TYPE(, FCombineShaderPS, TEXT("/Engine/Private/MyShaders.usf"), TEXT("CombineMainPS"), SF_Pixel);
IMPLEMENT_SHADER_TYPE(, FUVMaskShaderPS, TEXT("/Engine/Private/MyShaders.usf"), TEXT("UVMaskMainPS"), SF_Pixel);

Otherwise, I’ve been digging into FShaderType::GetTypeList()" which returns a linked list you can itterate and which you can call:

 // Create permutation parameters, using android example
     FShaderPermutationParameters Parameters(EShaderPlatform::SP_VULKAN_ES3_1_ANDROID);
     FShaderCompilerEnvironment OutEnvironment;
     ShaderType->ModifyCompilationEnvironment(Parameters, OutEnvironment);
 // Now add your custom modification to the environment
     OutEnvironment.SetDefine(TEXT("CUSTOM_SHADER_PATH"), *CustomShaderFilePath);

I have not figured out the right way to work with this data. It seems most of these are now wrapped with getters and has no settings. GPT suggests static linking a new global shader instead.