--- title: 剖析虚幻渲染体系(08)- Shader体系 date: 2024-02-04 21:44:10 excerpt: tags: rating: ⭐ --- # 前言 原文地址:https://www.cnblogs.com/timlly/p/15092257.html # FShader ```c++ class FShader { public: // 在编译触发之前修改编译环境参数, 可由子类覆盖. static void ModifyCompilationEnvironment(const FShaderPermutationParameters&, FShaderCompilerEnvironment&) {} // 是否需要编译指定的排列, 可由子类覆盖. static bool ShouldCompilePermutation(const FShaderPermutationParameters&) { return true; } // 检测编译结果是否有效, 可由子类覆盖. static bool ValidateCompiledResult(EShaderPlatform InPlatform, const FShaderParameterMap& InParameterMap, TArray& OutError) { return true; } // 取得RayTracingPayloadType static ERayTracingPayloadType GetRayTracingPayloadType(const int32 PermutationId) { return static_cast(0); } // 获取各类数据的Hash的接口. RENDERCORE_API const FSHAHash& GetHash() const; RENDERCORE_API const FSHAHash& GetVertexFactoryHash() const; RENDERCORE_API const FSHAHash& GetOutputHash() const; /** Returns an identifier suitable for deterministic sorting of shaders between sessions. */ uint32 GetSortKey() const { return SortKey; } // 保存并检测shader代码的编译结果. RENDERCORE_API void Finalize(const FShaderMapResourceCode* Code); // 数据获取接口. inline FShaderType* GetType(const FShaderMapPointerTable& InPointerTable) const { return Type.Get(InPointerTable.ShaderTypes); } inline FShaderType* GetType(const FPointerTableBase* InPointerTable) const { return Type.Get(InPointerTable); } inline FVertexFactoryType* GetVertexFactoryType(const FShaderMapPointerTable& InPointerTable) const { return VFType.Get(InPointerTable.VFTypes); } inline FVertexFactoryType* GetVertexFactoryType(const FPointerTableBase* InPointerTable) const { return VFType.Get(InPointerTable); } inline FShaderType* GetTypeUnfrozen() const { return Type.GetUnfrozen(); } inline int32 GetResourceIndex() const { checkSlow(ResourceIndex != INDEX_NONE); return ResourceIndex; } inline EShaderPlatform GetShaderPlatform() const { return Target.GetPlatform(); } inline EShaderFrequency GetFrequency() const { return Target.GetFrequency(); } inline const FShaderTarget GetTarget() const { return Target; } inline bool IsFrozen() const { return Type.IsFrozen(); } inline uint32 GetNumInstructions() const { return NumInstructions; } #if WITH_EDITORONLY_DATA inline uint32 GetNumTextureSamplers() const { return NumTextureSamplers; } inline uint32 GetCodeSize() const { return CodeSize; } inline void SetNumInstructions(uint32 Value) { NumInstructions = Value; } #else inline uint32 GetNumTextureSamplers() const { return 0u; } inline uint32 GetCodeSize() const { return 0u; } #endif // 尝试返回匹配指定类型的自动绑定的Uniform Buffer, 如果不存在则返回未绑定的. template FORCEINLINE_DEBUGGABLE const TShaderUniformBufferParameter& GetUniformBufferParameter() const { const FShaderUniformBufferParameter& FoundParameter = GetUniformBufferParameter(UniformBufferStructType::FTypeInfo::GetStructMetadata()); return static_cast&>(FoundParameter); } FORCEINLINE_DEBUGGABLE const FShaderUniformBufferParameter& GetUniformBufferParameter(const FShaderParametersMetadata* SearchStruct) const { const FHashedName SearchName = SearchStruct->GetShaderVariableHashedName(); return GetUniformBufferParameter(SearchName); } FORCEINLINE_DEBUGGABLE const FShaderUniformBufferParameter& GetUniformBufferParameter(const FHashedName SearchName) const { int32 FoundIndex = INDEX_NONE; TArrayView UniformBufferParameterStructsView(UniformBufferParameterStructs); for (int32 StructIndex = 0, Count = UniformBufferParameterStructsView.Num(); StructIndex < Count; StructIndex++) { if (UniformBufferParameterStructsView[StructIndex] == SearchName) { FoundIndex = StructIndex; break; } } if (FoundIndex != INDEX_NONE) { const FShaderUniformBufferParameter& FoundParameter = UniformBufferParameters[FoundIndex]; return FoundParameter; } else { // This can happen if the uniform buffer was not bound // There's no good way to distinguish not being bound due to temporary debugging / compiler optimizations or an actual code bug, // Hence failing silently instead of an error message static FShaderUniformBufferParameter UnboundParameter; return UnboundParameter; } } RENDERCORE_API const FShaderParametersMetadata* FindAutomaticallyBoundUniformBufferStruct(int32 BaseIndex) const; RENDERCORE_API void DumpDebugInfo(const FShaderMapPointerTable& InPtrTable); #if WITH_EDITOR RENDERCORE_API void SaveShaderStableKeys(const FShaderMapPointerTable& InPtrTable, EShaderPlatform TargetShaderPlatform, int32 PermutationId, const struct FStableShaderKeyAndValue& SaveKeyVal); #endif // WITH_EDITOR /** Returns the meta data for the root shader parameter struct. */ static inline const FShaderParametersMetadata* GetRootParametersMetadata() { return nullptr; } private: RENDERCORE_API void BuildParameterMapInfo(const TMap& ParameterMap); public: // 着色器参数绑定. LAYOUT_FIELD(FShaderParameterBindings, Bindings); // 着色器参数绑定的映射信息. LAYOUT_FIELD(FShaderParameterMapInfo, ParameterMapInfo); protected: LAYOUT_FIELD(TMemoryImageArray, UniformBufferParameterStructs); LAYOUT_FIELD(TMemoryImageArray, UniformBufferParameters); // 下面3个是编辑器参数. // 着色器的编译输出和结果参数映射的哈希值, 用于查找匹配的资源. LAYOUT_FIELD_EDITORONLY(FSHAHash, OutputHash); // 顶点工厂资源哈希值 LAYOUT_FIELD_EDITORONLY(FSHAHash, VFSourceHash); // Shader资源哈希值. LAYOUT_FIELD_EDITORONLY(FSHAHash, SourceHash); private: // 着色器类型. LAYOUT_FIELD(TIndexedPtr, Type); // 顶点工厂类型. LAYOUT_FIELD(TIndexedPtr, VFType); /** Target platform and frequency. */ LAYOUT_FIELD(FShaderTarget, Target); /** Index of this shader within the FShaderMapResource */ LAYOUT_FIELD(int32, ResourceIndex); /** The number of instructions the shader takes to execute. */ LAYOUT_FIELD(uint32, NumInstructions); /** Truncated version of OutputHash, intended for sorting. Not suitable for unique shader identification. */ LAYOUT_FIELD(uint32, SortKey); /** Number of texture samplers the shader uses. */ LAYOUT_FIELD_EDITORONLY(uint32, NumTextureSamplers); /** Size of shader's compiled code */ LAYOUT_FIELD_EDITORONLY(uint32, CodeSize); }; ```