虚幻4 材质的编译。
2016-04-28 00:57
776 查看
\Engine\Source\Runtime\Engine\Private\Materials\MaterialShader.cpp
这个文件中的
然后调用到这里:
Engine\Source\Runtime\Engine\Private\ShaderCompiler\ShaderCompiler.cpp
吧编译一个shader的任务加入队列。
下面的函数没有被调用,不知道为什么,总觉得最后应该调用到他了。但是可以看到这个函数最后调用了 编译函数。
我找到了这个
\Engine\Source\Programs\ShaderCompileWorker\Private\ShaderCompileWorker.cpp
目前猜测材质的渲染都是通过这个CPP里面的workerloop完成的。
\Engine\Source\Runtime\Engine\Private\Materials\MaterialShader.cpp
这个文件中的
/** * Compiles the shaders for a material and caches them in this shader map. * @param Material - The material to compile shaders for. * @param InShaderMapId - the set of static parameters to compile for * @param Platform - The platform to compile to */ void FMaterialShaderMap::Compile( FMaterial* Material, const FMaterialShaderMapId& InShaderMapId, TRefCountPtr<FShaderCompilerEnvironment> MaterialEnvironment, const FMaterialCompilationOutput& InMaterialCompilationOutput, EShaderPlatform InPlatform, bool bSynchronousCompile, bool bApplyCompletedShaderMapForRendering) { if (FPlatformProperties::RequiresCookedData()) { UE_LOG(LogMaterial, Fatal, TEXT("Trying to compile %s at run-time, which is not supported on consoles!"), *Material->GetFriendlyName() ); } else {
然后调用到这里:
Engine\Source\Runtime\Engine\Private\ShaderCompiler\ShaderCompiler.cpp
/** Enqueues a shader compile job with GShaderCompilingManager. */ void GlobalBeginCompileShader( const FString& DebugGroupName, FVertexFactoryType* VFType, FShaderType* ShaderType, const FShaderPipelineType* ShaderPipelineType, const TCHAR* SourceFilename, const TCHAR* FunctionName, FShaderTarget Target, FShaderCompileJob* NewJob, TArray<FShaderCommonCompileJob*>& NewJobs, bool bAllowDevelopmentShaderCompile ) {
吧编译一个shader的任务加入队列。
下面的函数没有被调用,不知道为什么,总觉得最后应该调用到他了。但是可以看到这个函数最后调用了 编译函数。
void FShaderCompileThreadRunnable::CompileDirectlyThroughDll() { for (int32 WorkerIndex = 0; WorkerIndex < WorkerInfos.Num(); WorkerIndex++) { FShaderCompileWorkerInfo& CurrentWorkerInfo = *WorkerInfos[WorkerIndex]; if (CurrentWorkerInfo.QueuedJobs.Num() > 0) { for (int32 JobIndex = 0; JobIndex < CurrentWorkerInfo.QueuedJobs.Num(); JobIndex++) { FShaderCommonCompileJob& CurrentJob = *CurrentWorkerInfo.QueuedJobs[JobIndex]; check(!CurrentJob.bFinalized); CurrentJob.bFinalized = true; static ITargetPlatformManagerModule& TPM = GetTargetPlatformManagerRef(); auto* SingleJob = CurrentJob.GetSingleShaderJob(); if (SingleJob) { const FName Format = LegacyShaderPlatformToShaderFormat(EShaderPlatform(SingleJob->Input.Target.Platform)); const IShaderFormat* Compiler = TPM.FindShaderFormat(Format); if (!Compiler) { UE_LOG(LogShaderCompilers, Fatal, TEXT("Can't compile shaders for format %s, couldn't load compiler dll"), *Format.ToString()); } CA_ASSUME(Compiler != NULL); if (IsValidRef(SingleJob->Input.SharedEnvironment)) { // Merge the shared environment into the per-shader environment before calling into the compile function // Normally this happens in the worker SingleJob->Input.Environment.Merge(*SingleJob->Input.SharedEnvironment); } // Compile the shader directly through the platform dll (directly from the shader dir as the working directory) Compiler->CompileShader(Format, SingleJob->Input, SingleJob->Output, FString(FPlatformProcess::ShaderDir())); SingleJob->bSucceeded = SingleJob->Output.bSucceeded; if (SingleJob->Output.bSucceeded) { // Generate a hash of the output and cache it // The shader processing this output will use it to search for existing FShaderResources SingleJob->Output.GenerateOutputHash(); } } else { auto* PipelineJob = CurrentJob.GetShaderPipelineJob(); check(PipelineJob); EShaderPlatform Platform = (EShaderPlatform)PipelineJob->StageJobs[0]->GetSingleShaderJob()->Input.Target.Platform; const FName Format = LegacyShaderPlatformToShaderFormat(Platform); const IShaderFormat* Compiler = TPM.FindShaderFormat(Format); if (!Compiler) { UE_LOG(LogShaderCompilers, Fatal, TEXT("Can't compile shaders for format %s, couldn't load compiler dll"), *Format.ToString()); } CA_ASSUME(Compiler != NULL); // Verify same platform on all stages for (int32 Index = 1; Index < PipelineJob->StageJobs.Num(); ++Index) { auto* SingleStage = PipelineJob->StageJobs[Index]->GetSingleShaderJob(); if (!SingleStage) { UE_LOG(LogShaderCompilers, Fatal, TEXT("Can't nest Shader Pipelines inside Shader Pipeline '%s'!"), PipelineJob->ShaderPipeline->GetName()); } if (Platform != SingleStage->Input.Target.Platform) { UE_LOG(LogShaderCompilers, Fatal, TEXT("Mismatched Target Platform %s while compiling Shader Pipeline '%s'."), *Format.GetPlainNameString(), PipelineJob->ShaderPipeline->GetName()); } } CompileShaderPipeline(Compiler, Format, PipelineJob, FString(FPlatformProcess::ShaderDir())); } } CurrentWorkerInfo.bComplete = true; } } }
我找到了这个
\Engine\Source\Programs\ShaderCompileWorker\Private\ShaderCompileWorker.cpp
目前猜测材质的渲染都是通过这个CPP里面的workerloop完成的。
class FWorkLoop { public: FWorkLoop(const TCHAR* ParentProcessIdText,const TCHAR* InWorkingDirectory,const TCHAR* InInputFilename,const TCHAR* InOutputFilename, TMap<FString, uint16>& InFormatVersionMap) : ParentProcessId(FCString::Atoi(ParentProcessIdText)) , WorkingDirectory(InWorkingDirectory) , InputFilename(InInputFilename) , OutputFilename(InOutputFilename) , InputFilePath(FString(InWorkingDirectory) + InInputFilename) , OutputFilePath(FString(InWorkingDirectory) + InOutputFilename) , FormatVersionMap(InFormatVersionMap) { } void Loop() { UE_LOG(LogShaders, Log, TEXT("Entering job loop")); while(true) { TArray<FJobResult> SingleJobResults; TArray<FPipelineJobResult> PipelineJobResults; // Read & Process Input { FArchive* InputFilePtr = OpenInputFile(); if(!InputFilePtr) { break; } UE_LOG(LogShaders, Log, TEXT("Processing shader")); ProcessInputFromArchive(InputFilePtr, SingleJobResults, PipelineJobResults); LastCompileTime = FPlatformTime::Seconds(); // Close the input file. delete InputFilePtr; } // Prepare for output FArchive* OutputFilePtr = CreateOutputArchive(); check(OutputFilePtr); WriteToOutputArchive(OutputFilePtr, SingleJobResults, PipelineJobResults); // Close the output file. delete OutputFilePtr; // Change the output file name to requested one IFileManager::Get().Move(*OutputFilePath, *TempFilePath); if (GShaderCompileUseXGE) { // To signal compilation completion, create a zero length file in the working directory. WriteXGESuccessFile(*WorkingDirectory); // We only do one pass per process when using XGE. break; } } UE_LOG(LogShaders, Log, TEXT("Exiting job loop")); }
相关文章推荐
- phpStorm 2016.1 最新版激活方法
- 解读(四):分析主界面顶部Tab的实现
- Python Cookbook - 1 - 数据结构和算法
- RDD执行延迟执行原理
- RTSPClient工具EasyRTSPClient支持H.265,支持海思等各种芯片平台
- RTSPClient工具EasyRTSPClient支持H.265,支持海思等各种芯片平台
- 机器学习笔记04:逻辑回归(Logistic regression)、分类(Classification)
- react -- 计时器
- sql执行顺序
- Spring 框架使用QQ邮箱发送邮件
- 硬盘存储原理
- CF初体验--Round #348,D
- Office2016 转换零售版为VOL版
- Java动态类加载与重载
- Lable文字自适应宽高
- Openstack小试牛刀之Keystone
- 使用Cydia Substrate 从Native Hook Android Java世界
- 基于C语言的面向对象编程
- 动态语言和静态语言的比较
- Android高效ImageLoader的实现