BlueRoseNote/03-UnrealEngine/Rendering/Material/自定义材质输出节点.md
2023-06-29 11:55:02 +08:00

48 lines
2.1 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: 自定义材质输出节点
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
}
```