BlueRoseNote/03-UnrealEngine/Rendering/Material/自定义材质输出节点.md

48 lines
2.1 KiB
Markdown
Raw Normal View History

2023-06-29 11:55:02 +08:00
---
title: 自定义材质输出节点
date: 2022-09-02 11:30:37
excerpt:
tags:
rating: ⭐
---
## 前言
参考文章https://zhuanlan.zhihu.com/p/163121357
## 自定义材质输出节点
继承`UMaterialExpressionCustomOutput`类并实现对应函数即可。
具体可以参考`BentNormal`材质输出节点。Shader代码位于BasePassPixelShader.usf的ApplyBentNormal()CPP代码位于UMaterialExpressionBentNormalCustomOutput类中UE4.27)。这种节点会生成`NUM_MATERIAL_OUTPUTS_节点名`的宏。
之后就可以在BasePassPixelShader.usf中通过宏与函数获取到对应的节点计算结果。比如
```c++
void ApplyBentNormal( in FMaterialPixelParameters MaterialParameters, in float Roughness, inout float3 BentNormal, inout float DiffOcclusion, inout float SpecOcclusion )
{
#if NUM_MATERIAL_OUTPUTS_GETBENTNORMAL > 0
#if MATERIAL_TANGENTSPACENORMAL
BentNormal = normalize( TransformTangentVectorToWorld( MaterialParameters.TangentToWorld, GetBentNormal0(MaterialParameters) ) );
#else
BentNormal = GetBentNormal0(MaterialParameters);
#endif
FSphericalGaussian HemisphereSG = Hemisphere_ToSphericalGaussian( MaterialParameters.WorldNormal );
FSphericalGaussian NormalSG = ClampedCosine_ToSphericalGaussian( MaterialParameters.WorldNormal );
FSphericalGaussian VisibleSG = BentNormalAO_ToSphericalGaussian( BentNormal, DiffOcclusion );
FSphericalGaussian DiffuseSG = Mul( NormalSG, VisibleSG );
float VisibleCosAngle = sqrt( 1 - DiffOcclusion );
#if 1 // Mix full resolution normal with low res bent normal
BentNormal = DiffuseSG.Axis;
//DiffOcclusion = saturate( Integral( DiffuseSG ) / Dot( NormalSG, HemisphereSG ) );
DiffOcclusion = saturate( Integral( DiffuseSG ) * 0.42276995 );
#endif
float3 N = MaterialParameters.WorldNormal;
float3 V = MaterialParameters.CameraVector;
SpecOcclusion = DotSpecularSG( Roughness, N, V, VisibleSG );
SpecOcclusion /= DotSpecularSG( Roughness, N, V, HemisphereSG );
SpecOcclusion = saturate( SpecOcclusion );
#endif
}
```