【转载】UE4 移动 shader 修改:MobileBasePassPixelShader.usf 初探

504 阅读3分钟

原文链接:Ue4移动shader修改:MobileBasePassPixelShader.usf初探 | 熊掌(熊鑫)

因为对于 UE4 延迟渲染管线不熟(太菜),添加一个新的 ShaderModel 稍显复杂(不会),而 Mobile Pixel Shader 简单明了易于修改,对移动 Shader 进行简单的修改可以满足手游开发中的一些特殊 Shader 需求。希望可以帮助到一些使用 UE4 开发手游的朋友。

文中使用 Custom 节点是从 UOD2019 中学得,视频地址:2019 虚幻引擎技术开放日 Epic Games 技术演讲影片合集

1. MobileBasePassPixelShader 修改

MobileBasePassPixelShader.usf 位于 Engine\Shaders\Private 中,或者直接在 Shaders 文件夹中搜索 Mobile 就可以找到。

MobileShader 的解析可以阅读 @more never 大佬写的文章

这里直接打开 usf 进行修改,搜索 NoL 可见图形学中最常见的几个函数:

float NoL = max(0, dot(float3(MaterialParameters.WorldNormal), float3(MobileDirectionalLight.DirectionalLightDirectionAndShadowTransition.xyz)));

float RoL = max(0, dot(float3(MaterialParameters.ReflectionVector), float3(MobileDirectionalLight.DirectionalLightDirectionAndShadowTransition.xyz)));

float3 H = normalize(float3(MaterialParameters.CameraVector) + float3(MobileDirectionalLight.DirectionalLightDirectionAndShadowTransition.xyz));

float NoH = max(0,dot(MaterialParameters.WorldNormal, H));

例如对 NoL进行修改,在 NoL 后添加

NoL = ceil(NoL*2)/2;

回到编辑器,切换到移动端,对一个材质进行任意的修改或者使用Ctrl+Shift+. (编译全部材质) 重新编译 Shader,完成后就可以看到如下的效果

这样就完成了对 Shader 的修改,一般并不想全部材质都使用自定义的 “光照模型”,这个时候就需要使用到 Custom 节点。可以把原本的

NoL = ceil(NoL*2)/2;

修改为

#ifdef myparameter
NoL = ceil(NoL*2)/2;
#endif

使用 #ifdef 之后,就可以使用 Custom 开启这行代码,材质编辑器中使用 Custom 节点,代码如下:

#define myparameter // 定义开启的参数

1 // Custom 的返回值

在 Custom 中定义了 mymarameter 就可以开启 usf 中 #ifdef myparameter 分支,效果如下:

有几点需要注意

Custom 节点必须最终连入任意一个节点,例如上图 Custom 返回值为1, Multiply BaseColor 后没有产生任何影响,但是只有这样 Custom 中的代码才会进入编译;

不知道什么原因,把 #define 写在第一行会报错。

最终效果如下:

2. Unreal Open Day 2019 中 Preintegrated BSSRDF 的实现

Pre-integrated 次表面实现原理很简单,可以参阅 @flashyiyi文章

文章开头的官方视频 6 分 30 秒 开始讲解了移动皮肤材质实现,视频中思路如下:

image.png

使用材质编辑器中使用 dot(lightdir,pixelnormal)*0.5+0.5 和曲率图对 Lut 图进行采样,最后连入 EmissiveColor ,然后在 usf 中添加 shadow*EmissiveColor 把阴影中的次表面颜色剔除。

这里使用 Custom 节点控制 sss 的开关,usf 中搜索 Emissive 找到

Color += Emissive;

修改为

#ifndef mysss
Color += Emissive;
#else
Color += Emissive*Shadow;
#endif

Custom 节点中代码

#define mysss

1

最终效果如下

注意 Lut 贴图的 Tile 方式使用 Clamp,注意压缩压缩格式,压缩太多会变糊。

分享一下最近的想法,抛砖引玉,还请轻拍。

最后学一下群主:

Enjoy it!