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

2.1 KiB
Raw Blame History

title, date, excerpt, tags, rating
title date excerpt tags rating
自定义材质输出节点 2022-09-02 11:30:37

前言

参考文章:https://zhuanlan.zhihu.com/p/163121357

自定义材质输出节点

继承UMaterialExpressionCustomOutput类并实现对应函数即可。

具体可以参考BentNormal材质输出节点。Shader代码位于BasePassPixelShader.usf的ApplyBentNormal()CPP代码位于UMaterialExpressionBentNormalCustomOutput类中UE4.27)。这种节点会生成NUM_MATERIAL_OUTPUTS_节点名的宏。

之后就可以在BasePassPixelShader.usf中通过宏与函数获取到对应的节点计算结果。比如

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  
}