208 lines
9.8 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.

# 参考文章
- UE4https://zhuanlan.zhihu.com/p/446587397
- UE5.2 https://zhuanlan.zhihu.com/p/658700282
- UE5.1 https://zhuanlan.zhihu.com/p/565837897
# 备注
添加的定义:
- MATERIAL_SHADINGMODEL_TOONSTANDARD
- SHADINGMODELID_TOONSTANDARD
- PIXEL_INSPECTOR_SHADINGMODELID_TOONSTANDARD
添加的功能:
- Material
- 材质编辑器引脚
- 相关引脚控制
- ShaderModel
- ViewMode - BufferVisualization
- ShaderModel可视化
- ToonBuffer可视化
- PixelInspector
# c++部分
## 添加ShaderModel
- EngineTypes.h 在EMaterialShadingModel中添加ShaderModel枚举
## 材质宏添加数值
ShaderMaterial.h给材质宏`MATERIAL_SHADINGMODEL_TOONSTANDARD`添加数值。
```c++
uint8 MATERIAL_SHADINGMODEL_TOONSTANDARD : 1;
```
之后再ShaderGenerationUtil.cpp的ApplyFetchEnvironment()与DetermineUsedMaterialSlots()添加对应代码。
## 添加材质编辑器引脚
- SceneTypes.h 在EMaterialProperty中添加2个引脚属性名称枚举。
- Material.h 在UMaterial类中添加FScalarMaterialInput类型变量CustomData2与CustomData3。
### MaterialExpressions.cpp
- 给MakeMaterialAttributes节点增加对应引脚
- 添加CustomData2与CustomData3声明。位于MaterialExpressionMakeMaterialAttributes.h
- 修改UMaterialExpressionMakeMaterialAttributes::Compile()增加CustomData2与CustomData3的对应列。
- 给BreakMaterialAttributes节点增加对应引脚
- 修改UMaterialExpressionBreakMaterialAttributes::UMaterialExpressionBreakMaterialAttributes()增加CustomData2与CustomData3的对应列。
- 修改UMaterialExpressionBreakMaterialAttributes::Serialize(),增加两列`Outputs[OutputIndex].SetMask(1, 1, 0, 0, 0); ++OutputIndex;`
- 修改BuildPropertyToIOIndexMap()增加CustomData2与CustomData3的对应列并且将最后一行的index改成合适的数值。
- 修改断言条件`static_assert(MP_MAX == 32`=>`static_assert(MP_MAX == 34`
### MaterialShared.cpp
- 修改FMaterialAttributeDefinitionMap::InitializeAttributeMap(),给CustomData2与CustomData3添加对应码只需与之前的不重复即可。
- 修改FMaterialAttributeDefinitionMap::GetAttributeOverrideForMaterial(),修改新添加的ShaderModel的引脚在材质编辑器中的显示名称。
### MaterialShader.cpp
- 修改GetShadingModelString()给新增加的ShaderModel添加返回字符串。
- 修改UpdateMaterialShaderCompilingStats(),给性能统计添加新增加的ShaderModel条件判断,`else if (ShadingModels.HasAnyShadingModel({ MSM_DefaultLit, MSM_Subsurface, MSM_PreintegratedSkin, MSM_ClearCoat, MSM_Cloth, MSM_SubsurfaceProfile, MSM_TwoSidedFoliage, MSM_SingleLayerWater, MSM_ThinTranslucent ,MSM_NPRShading}))`
### Material.cpp
- 修改UMaterial::PostLoad(),给新增加的引脚添加对应的两行代码,来对材质属性进行重新排序,`DoMaterialAttributeReorder(&CustomData2, UE4Ver, RenderObjVer);`
- 修改UMaterial::GetExpressionInputForProperty(),给新增加的引脚添加对应的两行代码。
- 修改UMaterial::CompilePropertyEx(),给新增加的引脚添加对应的两行代码。编译材质属性。
- 修改static bool IsPropertyActive_Internal()控制材质编辑器中引脚是否开启。给CustomData添加对应的代码。
### HLSLMaterialTranslator.cpp
控制材质节点编译拼接成完整的ShaderCode。
- 修改FHLSLMaterialTranslator::FHLSLMaterialTranslator()给SharedPixelProperties数组中引脚对应index赋值为true。
- 修改FHLSLMaterialTranslator::GetMaterialEnvironment()给新增加的ShaderModel添加宏。
- 修改FHLSLMaterialTranslator::GetMaterialShaderCode()。给新增加的引脚添加对应的两行`LazyPrintf.PushParam(*GenerateFunctionCode(MP_CustomData1));`。该函数会读取`/Engine/Private/MaterialTemplate.ush`并对替换字符格式化。
- 修改FHLSLMaterialTranslator::Translate(),为新增加的两个引脚增加两行:
```c#
Chunk[MP_CustomData2] = Material->CompilePropertyAndSetMaterialProperty(MP_CustomData2 ,this);//NPR Shading
Chunk[MP_CustomData3] = Material->CompilePropertyAndSetMaterialProperty(MP_CustomData3 ,this);
```
### MaterialGraph.cpp
材质界面代码。修改UMaterialGraph::RebuildGraph(),用来显示新添加的两个引脚:
```c#
MaterialInputs.Add( FMaterialInputInfo(FMaterialAttributeDefinitionMap::GetDisplayNameForMaterial(MP_CustomData2, Material), MP_CustomData2, FMaterialAttributeDefinitionMap::GetDisplayNameForMaterial(MP_CustomData2, Material)));
MaterialInputs.Add( FMaterialInputInfo(FMaterialAttributeDefinitionMap::GetDisplayNameForMaterial(MP_CustomData3, Material), MP_CustomData3, FMaterialAttributeDefinitionMap::GetDisplayNameForMaterial(MP_CustomData3, Material)));
```
### 解决添加引脚后
添加引脚后会出现`PropertyConnectedBitmask cannot contain entire EMaterialProperty enumeration.`的编译错误。需要将
```c#
uint32 PropertyConnectedBitmask;
```
=》
```c#
uint64 PropertyConnectedBitmask;
```
再将函数中的转换类型改成uint64即可。
```c#
ENGINE_API bool IsConnected(EMaterialProperty Property) { return ((PropertyConnectedBitmask >> (uint64)Property) & 0x1) != 0; }
ENGINE_API void SetConnectedProperty(EMaterialProperty Property, bool bIsConnected)
{
PropertyConnectedBitmask = bIsConnected ? PropertyConnectedBitmask | (1i64 << (uint64)Property) : PropertyConnectedBitmask & ~(1i64 << (uint64)Property);
}
```
## 控制引脚
### Material.cpp控制引脚开启
在IsPropertyActive_Internal()中修改:
```c++
case MP_CustomData0:
Active = ShadingModels.HasAnyShadingModel({ MSM_ClearCoat, MSM_Hair, MSM_Cloth, MSM_Eye, MSM_SubsurfaceProfile, MSM_ToonStandard, MSM_PreintegratedSkin });
break;
case MP_CustomData1:
Active = ShadingModels.HasAnyShadingModel({ MSM_ClearCoat, MSM_Eye, MSM_ToonStandard, MSM_PreintegratedSkin });
break;
```
### MaterialShared.cpp(修改引脚显示名称)
在MaterialShared.cpp的GetAttributeOverrideForMaterial()中修改:
```c++
case MP_CustomData0:
CustomPinNames.Add({ MSM_ClearCoat, "Clear Coat" });
CustomPinNames.Add({ MSM_Hair, "Backlit" });
CustomPinNames.Add({ MSM_Cloth, "Cloth" });
CustomPinNames.Add({ MSM_Eye, "Iris Mask" });
CustomPinNames.Add({ MSM_SubsurfaceProfile, "Curvature" });
CustomPinNames.Add({ MSM_ToonStandard, "ToonDataA" });
CustomPinNames.Add({ MSM_PreintegratedSkin, "ToonDataA" });
return FText::FromString(GetPinNameFromShadingModelField(Material->GetShadingModels(), CustomPinNames, "Custom Data 0"));
case MP_CustomData1:
CustomPinNames.Add({ MSM_ClearCoat, "Clear Coat Roughness" });
CustomPinNames.Add({ MSM_Eye, "Iris Distance" });
CustomPinNames.Add({ MSM_ToonStandard, "ToonDataB" });
CustomPinNames.Add({ MSM_PreintegratedSkin, "ToonDataB" });
return FText::FromString(GetPinNameFromShadingModelField(Material->GetShadingModels(), CustomPinNames, "Custom Data 1"));
```
### ShaderMaterialDerivedHelpers.cpp(CustomData数据传递)
在CalculateDerivedMaterialParameters()中修改代码让CustomData渲染到GBuffer上
```c++
// Only some shader models actually need custom data.
Dst.WRITES_CUSTOMDATA_TO_GBUFFER = (Dst.USES_GBUFFER && (Mat.MATERIAL_SHADINGMODEL_SUBSURFACE || Mat.MATERIAL_SHADINGMODEL_PREINTEGRATED_SKIN || Mat.MATERIAL_SHADINGMODEL_SUBSURFACE_PROFILE || Mat.MATERIAL_SHADINGMODEL_CLEAR_COAT || Mat.MATERIAL_SHADINGMODEL_TWOSIDED_FOLIAGE || Mat.MATERIAL_SHADINGMODEL_HAIR || Mat.MATERIAL_SHADINGMODEL_CLOTH || Mat.MATERIAL_SHADINGMODEL_EYE));
```
## PixelInspectorResult
在PixelInspectorResult.h中添加`PIXEL_INSPECTOR_SHADINGMODELID_TOONSTANDARD`宏定义。
之后在PixelInspectorResult.cpp的DecodeShadingModel()函数中添加定义。
### PixelInspectorDetailsCustomization修改菜单显示屏蔽属性用
# Shader部分
## MaterialTemplate.ush
给新增加的引脚增加对应的格式化代码:
```c#
half GetMaterialCustomData2(FMaterialPixelParameters Parameters)
{
%s;
}
half GetMaterialCustomData3(FMaterialPixelParameters Parameters)
{
%s;
}
```
## ShadingCommon.ush
- 新增加的ShaderModel添加ID宏`#define SHADINGMODELID_NPRSHADING 12`
- 修改float3 GetShadingModelColor(uint ShadingModelID)给添加的ShaderModel设置一个显示颜色。
## Definitions.ush定义材质宏
位于`Engine\Shaders\Private\Definitions.ush`。
## BasePassCommon.ush
- ~~修改#define WRITES_CUSTOMDATA_TO_GBUFFER宏在最后的条件判断中添加新增加的ShaderModel~~。**UE5.1将该逻辑转移到C++中**
## DeferredShadingCommon.ush
- 修改bool HasCustomGBufferData(int ShadingModelID)在条件判断中添加新增加的ShaderModel。
## ShadingModelsMaterial.ush
- 修改void SetGBufferForShadingModel()该函数用于设置输出的GBuffer给新增加的ShaderModel添加对应的代码段
```c#
#ifdef MATERIAL_SHADINGMODEL_NPRSHADING
else if(ShadingModel == SHADINGMODELID_NPRSHADING)
{
GBuffer.CustomData.x=saturate(GetMaterialCustomData0(MaterialParameters));
GBuffer.CustomData.y=saturate(GetMaterialCustomData1(MaterialParameters));
GBuffer.CustomData.z=saturate(GetMaterialCustomData2(MaterialParameters));
GBuffer.CustomData.w=saturate(GetMaterialCustomData3(MaterialParameters));
}
#endif
```
## 光照实现
- ShadingModel.ushBxDF实现。
- DeferredLightingCommon.ush延迟光照实现。
# 相关文件
- UMaterialInterface、UMaterial、UMaterialInstance、FMaterial、FMaterialResource、FMateialRenderProxy、FMaterialInstanceResource、FDefaultMaterialInstance
- MaterialShader.cpp
- HLSLMaterialTranslator.cpp
- MaterialHLSLEmitter:塞入ShaderModel宏
- Material.cpp:开启引脚
- MaterialAttributeDefinitionMap.cpp
- ShaderMaterialDerivedHelpers.cpp
- ShaderGenerationUtil.cpp
- ShadingCommon.ush
# Material编辑器相关代码
- FMaterialInstanceBasePropertyOverrides
- FMaterialInstanceParameterDetails
https://zhuanlan.zhihu.com/p/565776677
https://www.cnblogs.com/timlly/p/15109132.html