UE5.5 - 逐材质Stencil
启动项设置
注意事项,启动项选择 
逐材质Stencil
Stencil对应就是这里,UE默认是逐Mesh的Stencil,很不方便,会影响模型拆分。这里进行源码修改 
交互层
MaterialInterface.h
找到这个类,它是所以有材质的基类
声明Stencil成员变量,丢在LightmassSetting后面就行
找到重写的函数类进行声明一个获取函数来获取刚才声明的受保护成员变量 
MaterialInterface.cpp
cpp文件内对声明的获取函数进行实现 
Material.h
Material是MaterialInterface的子类,Material继承了MaterialInterface中声明的成员变量MaterialStencilValue所以不用再次声明,但是获取函数是虚函数所以需要重写,这里进行声明 
Material.cpp
重写函数,但内容其实是一样的,就是获取MaterialStencilValue值 
MaterialInstance.h
材质实例继承基类MaterialInterface,所以需要进行和Material同样操作,进行重写虚函数。
这里需要提一点,MaterialInstance并不是继承Material而是继承基类MaterialInterface,材质和材质实例是同级的 声明获取函数 
MaterialInstance.cpp
函数实现 
MaterialInstanceBasePropertyOverrides.h
声明需要重写的值,是否重写的Bool,不太清楚为什么使用int类型不直接用Bool,可能还有其他用途或者防止内容溢出之类的 顺带一提这个文件是没有Cpp文件的,仅做声明变量使用,里面的变量实际上是做为材质和材质实例之间的成员比对类来使用,意思是比较材质和实例都包含这个类成员,所以直接比对材质和材质实例中这个类就行
既然是中转变量,所以自然需要再声明一个变量,跟其他变量写法差不多,直接用和之前在材质接口中声明的MaterialStencilValue同名就行,愿意加个Temp前缀也行,源码没加我就没加
FMaterialInstanceBasePropertyOverrides这里是材质实例中的引用参数,MaterialInstance.h中可以看到材质参数更新就靠这里,传入参数是FMaterialInstanceBasePropertyOverrides。 
MaterialInstance.cpp
是否需要更新参数取决于材质实例文件中怎么实现,这里有更新判断函数做判断,判断材质实例参数面板的值是否和父类,因为材质和材质实例都是继承同一父类,这里也可以理解成判断材质实例和材质的参数是否相等,得到的Bool值用于后续更新判断 
MaterialShared.cpp
MaterialShared负责底层渲染数据的传递处理,材质实例和父类的比对在这里进行 这里对MaterialInstanceBasePropertyOverrides中的所有参数进行初始化,这里使用的是初始化列表写法,就是在类后面加冒号”:”,然后进行赋值,末尾函数体实际是空的
重写等等判断符,进行比较,对根材质和中间重写的值进行比较 
MaterialInstance.cpp
进行判断,如果父类不为空,则先初始化材质实例的所有值,如果有重写的值就直接读取重写的值,反之读取父类的值 
PreviewMaterial.cpp
这里进行判断,如果没有发现重写,就读取材质实例的值给重写的值 
MaterialEditorInstanceDetailCustomization.h
这里进行声明UI函数 
MaterialEditorInstanceDetailCustomization.cpp
找到创建UI的函数
这里进行生创建UI
简单来说生成就是材质实例面板
创建UI还需要有赋值操作,使用宏来实现,这里直接参考裁剪值来写就行
函数实现就是这个宏,将新值传给材质实例编辑类 
渲染层
交互层改完后现在进行渲染层的修改,材质渲染这里,FMaterial做的工作就是实时查询UMaterial和UMaterialInstance的参数并进行进行处理,然后继承给FMaterialResource进行渲染
MaterialShared.h
找到FMaterial类,前面说过,FMaterial做的工作就是实时查询UMaterial和UMaterialInstance的参数并进行进行处理,所以自然需要读取我们创建的MaterialStencil,那么就需要创获取函数来读取
声明获取函数,注意这里不能完全参照下面的GetOpacityMaskClipValue来写了,不能设为纯虚函数,因为还有其他文件继承它,所以这里给一个默认实现返回0
找到FMaterialResource类,它继承FMaterial类
声明继承过来的需要重写的虚函数 
MaterialShared.cpp
对虚函数进行实现,作比对看是返回UMaterial还是UMaterialInstance的值去渲染 
CustomDepthRendering.cpp
修改自定义深度渲染,因为自定义深度和自定义Stencil在UE中是绑定在一起的,默认就可以获取到CustomDepthStencilValue,所以只需要把我们创建的材质中的MaterialStencilValue传给它就行。有这里找到位置将注释地方更换掉,如果MaterialStencilValue大于0就直接输出给CustomDepthStencilValue 
Stencil的项目设置
如果需要使用和查看Stencil,必须更改项目设置
预览参数选择
在预览之前需要在材质中设置自定义深度写入,否则是不会生效的 
当前效果
这里是使用的一个有两个材质的模型,两个材质分别设置Stencil值
现在预览可以看到逐材质Stencil生效了 
References
Enjoy Reading This Article?
Here are some more articles you might like to read next: