零、前言

最近尝试尝试给UE4添加一个用于三渲二的新的光照模型,主要参考了知乎文章和这篇博客教程,以及GDC2015罪恶装备Xrd制作团队的演讲及其PPT内容。

一、获取美术资源

由于是完全照抄罪恶装备Xrd的渲染方法因此首先要获取到相关的美术资源。需要的解包软件有:

  1. psarc——一个可以将PS3加密格式文件进行解密的工具。
  2. umodel——一个用于解包虚幻引擎制作的游戏的工具。
  3. 罪恶装备Xrd的PS3版本游戏文件。

资源获取方法,以win10+罪恶装备Xrd的PS3镜像文件为例:

1、首先打开镜像文件,在此目录下找到DATA00.PSARC文件,并将其拷贝到psarc.exe所在的目录:

2、在psarc.exe所在目录中,按住shift+鼠标右键打开Powershell:

3、接下来输入下图所示内容进行解密:

4、你会得到一个叫做REDGame的文件夹,接下来使用umodel打开这个文件夹(就是把这个文件夹拖到umodel上):

5、一般前三个字母代表角色名称、后面三个时资源类型,比如第一个文件就是AXL的编号为0108的材质文件,选中后点击Export可以获得纹理(模型也是相同的流程,后缀是MSH,解包出来后还需要导入到3DMax中再导出成FBX才能直接导入到UE4引擎中):

二、日式卡通渲染基础

这一章节简单讲讲如何去使用获得的美术资源,详细内容可以去看GDC2015的讲座以及PPT。

1、Vertexcolor(解包得到的模型资源似乎丢失了相关信息)

  • R通道:控制角色的阴影倾向系数,即:在光线与法线夹角相同的情况下,该值越大则该顶点附近的区域越容易处于阴影状态。
  • G通道:轮廓线随着摄像机距离的膨胀系数。
  • B通道:轮廓线的ZOffset值,该值越大描边越不可见。
  • A通道:控制描边的粗细程度。

2、SSS纹理、Base纹理、ILM纹理

  • Base纹理——提供角色的BaseColor信息。
  • SSS纹理——提供次表面散射的颜色信息。
  • ILM纹理——R通道:高光系数(Blinn-Phong光照模型中的镜面反射指数系数);G通道:阴影系数,与VertexColor的R通道共同工作;B通道:高光区域;A通道:内部轮廓线的颜色。

三、给UE4添加新的ShadingModel

1、首先我们要让材质编辑器知道有这么一个新的ShadingModel:

2、通知Shader我们添加了一个新的光照模型(给Shader声明了一个宏):

3、由于我们要传输大量的数据给Shader,而UE4的材质系统只给了我们两个half4的Custom接口以及UE4的延迟渲染的GBuffer只有一个float4允许你自由使用,所以显然并不够用,因此我使用了Metallic、Specular、Roughness、Custom0来传输ILM纹理的RGBA通道数据,使用Subsurface来传输SSS纹理数据:

第一张图的主要作用是设置材质系统认为我们的卡通渲染模型属于次表面渲染模型的一种,否则材质系统翻译材质蓝图的时候不会给Subsurface这个值进行赋值,第二张图是告诉材质系统我们要在材质蓝图中用custom0和SubsurfaceColor这两个接口。

为了方便在材质蓝图中辨认接口,我们可以改编接口的名称:

上面四张图可能有些不太清晰,简单说一下,其实就是找到对应接口名称的XXXPinName函数进行更改,由于Specular、Roughness没有相关的XXXPinName函数,于是我们可以自己声明对应的函数,自定义其名称。

四、在Shader中添加相应的ShadingModel计算逻辑

首先,我们要在Shader单中定义一个ShadingModel与C++中定义的枚举相对应:

然后要让自定义的光照模型允许使用GBufferD,即CustomData:

由于这句代码比较长,在这里给出完整代码:

#define WRITES_CUSTOMDATA_TO_GBUFFER        (USES_GBUFFER && (MATERIAL_SHADINGMODEL_SUBSURFACE || MATERIAL_SHADINGMODEL_PREINTEGRATED_SKIN || MATERIAL_SHADINGMODEL_SUBSURFACE_PROFILE || MATERIAL_SHADINGMODEL_CLEAR_COAT || MATERIAL_SHADINGMODEL_TWOSIDED_FOLIAGE || MATERIAL_SHADINGMODEL_HAIR || MATERIAL_SHADINGMODEL_CLOTH || MATERIAL_SHADINGMODEL_EYE || MATERIAL_SHADINGMODEL_TOON))

既然已经允许往GBuuferD中写入数据,那么接下来就是决定要写什么内容:

(1)、

上图表示,我们首先要将传输到SubsurfaceColor接口的数据赋值给真正的输出变量。完整代码如下:

#if MATERIAL_SHADINGMODEL_SUBSURFACE || MATERIAL_SHADINGMODEL_PREINTEGRATED_SKIN || MATERIAL_SHADINGMODEL_SUBSURFACE_PROFILE || MATERIAL_SHADINGMODEL_TWOSIDED_FOLIAGE || MATERIAL_SHADINGMODEL_CLOTH || MATERIAL_SHADINGMODEL_EYE || MATERIAL_SHADINGMODEL_TOON
{float4 SubsurfaceData = GetMaterialSubsurfaceData(PixelMaterialInputs);#if MATERIAL_SHADINGMODEL_SUBSURFACE || MATERIAL_SHADINGMODEL_PREINTEGRATED_SKIN || MATERIAL_SHADINGMODEL_TWOSIDED_FOLIAGESubsurfaceColor = SubsurfaceData.rgb * View.DiffuseOverrideParameter.w + View.DiffuseOverrideParameter.xyz;#elif MATERIAL_SHADINGMODEL_CLOTH || MATERIAL_SHADINGMODEL_TOONSubsurfaceColor = SubsurfaceData.rgb;#endifSubsurfaceProfile = SubsurfaceData.a;
}
#endif

(2)、

上图表示,将SubsurfaceColor与Custom0合并成一个float4,并赋值到GBufferD代表的CustomData。

接下来由于我们使用了Metallic、Specular、Roughness,所以会参与到间接反射的计算当中,我们要找到对应的代码修改一下:

由于间接反射与光照计算是叠加关系,所以直接输出(0.0,0.0,0.0)即可。

------------------------------------------------------------------------2019.5.17修改-------------------------------------------------------------------------------------------------

还要注意的是,Metallic在编码GBuffer之前参与到了其他渲染逻辑的计算,需要将对应代码进行修改(不修改的话,会发现调整SpecularStrength数值后,角色身上会出现色块),如图:

---------------------------------------------------------------------------------修改结束----------------------------------------------------------------------------------------------

终于到了最后一步,获取我们所需要的数据开始计算表面颜色:

完整代码如下:

BRANCH
if (GBuffer.ShadingModelID == SHADINGMODELID_TOON)
{float3 LightColor = LightData.Color;float3 SSS = float3(GBuffer.CustomData.r, GBuffer.CustomData.g, GBuffer.CustomData.b);float SpecStrength = GBuffer.Metallic;float ShadowThreshold = GBuffer.Specular;float SpecularSize = GBuffer.Roughness;float InnerLine = GBuffer.CustomData.a;// 纹理数据处理float3 BrightColor = GBuffer.BaseColor;float3 ShadowColor = GBuffer.BaseColor * SSS;// 这里我觉得内部描边的颜色不够明显,于是乘上了0.5if (InnerLine < 0.8f){InnerLine *= 0.5f;}float3 InnerLineColor = float3(InnerLine, InnerLine, InnerLine);float NdotL = dot(L, N) * Shadow.SurfaceShadow;float NdotH = dot(normalize(L + V), N);ShadowThreshold = step(ShadowThreshold, NdotL);float3 Diffuse = InnerLineColor * LightColor * lerp(ShadowColor, BrightColor, ShadowThreshold);float3 Specular = LightColor * BrightColor * ShadowThreshold * InnerLineColor * step(0.2f, SpecularSize * pow(NdotH, SpecStrength));LightAccumulator.TotalLight = Diffuse + Specular;
}
else
{//原本的代码......
}

五、外轮廓描边实现

罪恶装备的外部描边是通过模型膨胀法实现的,这种方式在Unity3D中很好实现,只需要在Shader中添加一个pass即可,可是在UE4中,由于顶点在提交给RHI渲染时,已经进行了合并,想要在Renderer中加一个Pass来做描边似乎是不可能的(太菜不知道怎么改),于是我想的办法是在蓝图中,给Character这个类的SkeletalMesh组件附加一个PoseableMesh组件,当作多Pass渲染,如图:

膨胀模型外描边顾名思义,要将模型根据法线方向进行膨胀,然后只绘制背面,其中第一步很好做,第二部由于UE4并不支持只绘制背面,所以我们要稍做修改:

首先,声明一个新的变量,方便我们在材质中直接设置:

第二步,由于UE4的Material相关的类都是继承自MaterialInterface,所以我们需要添加一个接口,方便在绘制逻辑中查询该材质是否只绘制背面:

接下来要做的事情就很简单了,在Material和MaterialInstance中的对应地方重写IsOnlyBackFace这个函数即可(一个很简单的方法,在对应的.h、.cpp文件中查找IsTwoSided,然后在下方添加对应的函数即可,这里为了缩减篇幅,就不给出截图了)。

最后一步,在合并模型之前,设置ReverseCulling这个变量,找到SkeletaMesh.cpp这个文件,在该文件的GetDynamicElementsSection函数中找到Mesh.ReverseCulling进行修改:

六、材质蓝图截图

光照渲染:

外轮廓描边:

七、效果

八、时隔很多个月的小补充(2020.3.6)

有人提出延迟渲染下,点光源、聚光灯有曝光现象,这种现象有个很简单的方法是设置光源的Use Inverse Squared Fallof这个选项,它决定了使用哪个衰减公式,默认勾选是使用距离平方的倒数,不勾选则是使用指数进行衰减。

距离平方的倒数
指数衰减

ue4 如何获取端口号_尝试在UE4.22中实现罪恶装备Xrd的卡通渲染相关推荐

  1. mysql数据库怎么查看端口号_怎么查看数据库端口号(mysql怎么查看端口号)

    怎么查看数据库端口号(mysql怎么查看端口号) 2020-05-08 11:20:02 共9个回答 如何查看自己数据库的端口号 navicat,找到服务器,右键->连接属性,就找到端口号了 如 ...

  2. mongodb 默认端口号_快2020年了,该如何面对BATJM对MongoDB灵魂式的拷问呢?

    关注我,可以获取最新知识.经典面试题以及微服务技术分享 MongoDB是基于分布式文件存储的数据库,由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案,且MongodDB是一个介于关 ...

  3. adroid 如何测试端口号_多进程启动设备和appium实现自动化测试

    前言 测试过程中,难免遇到多机型兼容测试.如果拿很多手机轮流做手工测试,耗费时间长,重复工作量大,占用人工多.网上已有较多手机测试的文章,基本会根据多个手机参数在配置文件中写死.这样的方式不够灵活,本 ...

  4. java获取机器号_(转)JAVA获得机器码的实现

    http://yangshangchuan.iteye.com/blog/2012401 首先,定义了一个统一的接口,以支持不同操作系统不同实现的透明切换: Java代码  收藏代码 /** *生成机 ...

  5. ldap协议端口号_什么是LDAP协议端口号? 比较LDAP端口389和636

    ldap协议端口号 Lightweight Directory Access Protocol or LDAP is used to authenticate and authorize users. ...

  6. rtsp端口号_设置RTSP, RTP和RTCP端口号 | 学步园

    1.设置RTSP端口号 设置RTSP端口号的处理位于ARTSPConnection.cpp文件中,首先从url中获取端口号,如果读取不到,则设置为默认端口554.代码处理如下: ARTSPConnec ...

  7. java 扫描tcp端口号_多线程TCP端口扫描 java实现

    界面部分: import java.awt.Color; import java.awt.Container; import java.awt.FlowLayout; import java.awt. ...

  8. 串口发送tcp数据 源端口号_三分钟基础知识:用动画给面试官解释 TCP 三次握手过程...

    作者 |  小鹿 来源 |  小鹿动画学编程 写在前边 TCP 三次握手过程对于面试是必考的一个,所以不但要掌握 TCP 整个握手的过程,其中有些小细节也更受到面试官的青睐. 对于这部分掌握以及 TC ...

  9. vue脚手架搭建配置试调地址和端口号_全栈的自我修养: 002使用@vue/cli进行vue环境搭建 (使用Vue,SpringBoot,Flask完成前后端分离)...

    全栈的自我修养: 使用@vue/cli进行vue.js环境搭建 Success, real success, is being willing to do the things that other ...

最新文章

  1. Modelsim下进行功能仿真没问题,可是在ISE综合报错,如何解决?
  2. OpenStack虚机网卡的创建过程
  3. 【图像超分辨率】Multi-scale Residual Network for Image Super-Resolution
  4. java的继承和访问_Java 继承和访问控制
  5. jcseg 1.7.2 版发布了
  6. PWM整流器仿真。 在simulink中搭建了PWM整流器,采用电压电流双闭环控制,实现了网侧电压与电流同相位
  7. ASR中常用的语音特征之FBank和MFCC(原理 + Python实现)
  8. 制作一份高质量的APP运营推广方案
  9. 关闭WIN7交互式服务检测提示
  10. Web服务小试——天气预报
  11. 图像sensor的工作原理
  12. MySql错误处理- 错误代码和消息
  13. meso-四(4-N,N,N-三甲基氨基苯基)卟啉(TTMAPP);[5,15-二乙炔基-10,20-二(3,4,5-三(十六烷氧基)苯基)卟啉]锌(DBTCPP-Zn);锌卟啉(TPP-Zn)科研级
  14. 关于分布式事务 两阶段提交 一阶段提交 Best Efforts 1PC模式和事务补偿机制的研究
  15. Swiper4.0:H5手机端滑屏判断当前页Index并且触发动画(slideChangeTransitionEnd与swiper.activeIndex)
  16. 扶桑号战列舰(差分/笛卡尔树)
  17. 伪解决Selenium中调用PhantomJS无法模拟点击(click)操作
  18. C#学习笔记(四)-- .NET Framework与C#简介
  19. 博图追款锁机程序博图v15 v16 v17适用
  20. Python 用3D引擎写一个Pong游戏

热门文章

  1. 2、Qt Project之鼠标事件监控
  2. C#+HtmlAgilityPack+Dapper走一波爬虫
  3. 【游戏开发】Excel表格批量转换成CSV的小工具
  4. VS2005迁移项目工程所带来问题
  5. 报表FineReport部署Tomcat服务器
  6. 《DSP using MATLAB》Problem 6.6
  7. Taotao Picks Apples
  8. 操作系统--进程管理1--单个CPU情况
  9. Windows 7安装Oracle 10g的方法
  10. 做个犀利的码农:如何持续培养/更新自己的开发技能