找回密码
 立即注册
查看: 446|回复: 0

Unreal自定义ShaderModel

[复制链接]
发表于 2020-12-5 20:06 | 显示全部楼层 |阅读模式
前言:
Unreal支持了好几种常用的ShaderModel,几乎满足大部分的需求。根据我的理解来看,一般是不需要添加ShaderModel的,大部分情况现有的 ShaderModel都支持,有特殊光照需求也可以通过自发光自己添加表达式来计算,并且Unreal的蓝图有材质函数和Instance能复用你的这些表达式,也没有工程相关的问题,非常方便。如果你的项目确实需要修改或者添加自己的光照模型,在Unreal中也是非常方便的,鉴于目前网上关于这一块的中文资料比较少,几乎都来源于一篇老外的翻译。那篇原文也是很老的版本,现有版本Unreal对于材质和shader的编译有较大的修改,所以可能大家看那篇文章会有一些费解。
本篇文章截止到目前最新的Unreal版本:4.23release
准备工作:
VS2017
下载Unreal源码,本文为4.23release,注意一定要下载源码来编译,官网直接下载的编辑器是没法自定义ShaderModel的。
Setup.bat   GenerateProjectFiles.bat
编译。。。。


定义ShaderModelType:
打开EngineType.h文件,找到EMaterialShadingModel,这个枚举定义了Unreal所有的类型,注意 插入到MSM_NUM之前。


那声明完,得决定在编辑器上显示成什么,我们打开MaterialShader.cpp,找到GetShadingModelString方法。(这里说法有误,上面决定编辑器上下拉显示,这里是shadermode的描述)
我们就叫MyModel好了。
写完这句话就能在编辑器上看到了,但是最好别写几行,编译一下看看效果,我的小I7编译一次大概半个小时。
如果需要用到SubSurface的话,可以在MaterialShaded.h里编辑:
在选择到我们的ShaderModel时,需要通知到HLSL的翻译器,打开MyModel对应的宏。打开HLSLMaterialTranslator.h,定位到GetMaterialEnvironment方法,添加我们的宏。


ShaderModel输入
选择好ShadModel后,那我们肯定需要自定义输入
Unreal提供这么多输入,我们得决定用到哪些,不用到哪些,还有最重要的CustomData,这个我们可以额外添加自己的数据。打开Material.cpp,IsPropertyActive_Internal方法 。
前面是一些其他跟这个面板无关的属性,直接往下拉
这里就对应上面的面板在自定义ShaderModel,应该打开哪些属性,供用户输入,你可以自己编辑,我们在这把customData0打开,其他的属性采用默认值就好了,大家可以按需选择。这样就是在Material底层提供哪些属性,熟悉Unity的同学,你差不多可以理解为Unity的ShaderLab上的Properties。如果显示为CustomData,美术看了不知道啥意思咋办,我们可以改名,打开MaterialGraph.cpp,这个类相当于Material的Editor接口,材质跟显示相关的可以试着在这里找到,想改名啥的,这里都有,我们现在只改我们的customdata。
这里可以看到有两个Index,分别对应我们上面的MP_CustomData0和MP_CustomData1,代码很好读,就是一个键值对,有的就取键值对的名字,没有的就显示CustomData。我们把CustomData0显示成MyData。


Inspector面板显示及序列化
在Inspector面板上,我们还能隐藏我们不想给其他人看的一些数据。打开PixelInspectorDetailsCustomization.cpp 的FPixelInspectorDetailsCustomization::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder)方法,到 这个方法的最后,可以自定义隐藏一些东西。
序列化在PixelInspectorResult中,我们先得定义我们的ShaderModel保存的数字,在.h文件上面。
然后在cpp中,定义:
Shader编写
上面的操作做完,就可以编译C++代码了,因为剩下的都是Shader代码的编写,改变ShaderModel需要重编所有的 Shader代码,Unreal默认的shader大概有2000多个,所以也需要很长的时间,大概2分钟左右吧,最好也是都写完了,再打开编辑器,不过相对于C++的编译来说,这也还好,修改的代价不是很大。
Unreal的shader文件后缀叫.usf和.ush,ush一般是声明和定义的一些东西,usf一般提供一些方法。
首先,我们打开ShadingCommon.ush,声明和定义ShaderModel标量来表示。




上面我们在切换ShaderModel时打开了材质宏,我们定义的SHADINGMODELID_MYMODEL。
所以,在GetShadingModelID中,我们需要添加下面代码:
为了在编辑器中调试和显示方便,我们还可以定义用我们这种ShaderModel的默认颜色,在GetShadingModelColor中:
PS4Profile不支持Switch语句。
我们刚刚在上面打开了SubSurface,那么就需要获取SubsurfaceData,打开BasePassPixelShader,添加我们的宏和ShaderModel判断。
在延迟渲染Shader中也要表明这个是次表面模型,打开 DeferredShadingCommon.ush。
由于Unreal的新功能,能混合ShaderModel,如果我们需要让我们的ShaderModel支持跟其他Model混合的话,需要打开TiledDeferredLightShaders.usf的ExecuteShadingLoops函数,添加我们的Model混合代码。
打开ClusteredDeferredShadingPixelShader.usf的ClusteredShadingPixelShader函数,循环获取灯光数据。
我们在计算我们自己的ShaderModel前,需要处理一些数据,可以在ShadingModelsMaterial中,
做完那么多shader准备 工作,终于可以开始定义我们的ShadingModel代码了。打开ShadingModels.ush文件,这个文件里存了我们所有的ShaderModel所有模式的代码。
我们可以自定义自己的model代码。
然后,在IntegrateBxDF选择模型的地方,调用我们的方法。


至此,我们就成功地为UE4添加了一个自定义ShaderModel。


由于本人初学UE4,可能存在诸多错误,写这篇博客主要是网上这方面资料太少了,想跟大家交流一下这方面的内容。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-9-20 06:17 , Processed in 0.091495 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表