163 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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<FString>& OutError) { return true; }
// 取得RayTracingPayloadType
static ERayTracingPayloadType GetRayTracingPayloadType(const int32 PermutationId) { return static_cast<ERayTracingPayloadType>(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<typename UniformBufferStructType>
FORCEINLINE_DEBUGGABLE const TShaderUniformBufferParameter<UniformBufferStructType>& GetUniformBufferParameter() const
{
const FShaderUniformBufferParameter& FoundParameter = GetUniformBufferParameter(UniformBufferStructType::FTypeInfo::GetStructMetadata());
return static_cast<const TShaderUniformBufferParameter<UniformBufferStructType>&>(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<const FHashedName> 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<FString, FParameterAllocation>& ParameterMap);
public:
// 着色器参数绑定.
LAYOUT_FIELD(FShaderParameterBindings, Bindings);
// 着色器参数绑定的映射信息.
LAYOUT_FIELD(FShaderParameterMapInfo, ParameterMapInfo);
protected:
LAYOUT_FIELD(TMemoryImageArray<FHashedName>, UniformBufferParameterStructs);
LAYOUT_FIELD(TMemoryImageArray<FShaderUniformBufferParameter>, UniformBufferParameters);
// 下面3个是编辑器参数.
// 着色器的编译输出和结果参数映射的哈希值, 用于查找匹配的资源.
LAYOUT_FIELD_EDITORONLY(FSHAHash, OutputHash);
// 顶点工厂资源哈希值
LAYOUT_FIELD_EDITORONLY(FSHAHash, VFSourceHash);
// Shader资源哈希值.
LAYOUT_FIELD_EDITORONLY(FSHAHash, SourceHash);
private:
// 着色器类型.
LAYOUT_FIELD(TIndexedPtr<FShaderType>, Type);
// 顶点工厂类型.
LAYOUT_FIELD(TIndexedPtr<FVertexFactoryType>, 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);
};
```