UE4 后期处理
https://zhuanlan.zhihu.com/p/81310476
https://www.dingshukai.com/blog/ue4-material-scenetexelsize.html
SceneTexture(场景纹理)节点:通过这个节点,输入UV值,你可以获取到这个UV对应的像素点的各个属性,比如SceneColor(场景颜色),SceneDepth(场景深度),CustomDepth(自定义深度),Opacity(不透明度)等等。
如果不输入UV,则默认为对所有像素点都做一样的处理。
SceneDepth(场景深度):当前画面上的像素点和摄像机之间的距离,也就是从你看得到的地方开始算,比如镜头正对着一面墙,墙后有块石头,那么UV(0.5,0.5)获取到的场景深度就是墙中间的部分与摄像机之间的距离,跟石头无关了。
CustomDepth(自定义深度):想获得被遮挡的物体离相机的距离,就要开启物体上的自定义深度了。如果在UV对应的像素点方向上有物体开启了自定义深度,即使被遮挡也可以获取到它的场景深度。如果该位置没有物体开启自定义深度,那么访问到的值则是无穷大。
所以我们就可以根据自定义深度和场景深度的差来判断是否有东西被挡住,如果被挡住显示什么颜色等等了。
并且经过测试,有两个开启了自定义深度的物体在一条线上的话,获取到的CustomDepth是离得最近的那个。
ScreenPosition(屏幕位置):ViewportUV输出的就是每个像素点在屏幕上的UV值,等于是每个像素点的UV都获取一次,然后进行处理。
SceneTexture:PostProcessInput0节点:这个节点其实就是SceneColor,也就是场景本来的颜色。SceneColor只能用于MaterialDomain为Surface(表面)的材质。刚开始一直理解不了为什么选了深度,输出的值那里仍然是Color。其实这里的Color并不代表颜色,只是代表一个Vector参数,有RGBA四个值。
当使用自定义深度时,我们要的只是一个值,就是用Mask节点取到第一个值也就是深度了。同理,PostProcessInput0节点那里,我们只取前三个值,因为后处理材质只有一个属性EmissiveColor(自发光颜色),这是个float3的属性,只需要三个值控制颜色,不需要透明度。这里的逻辑其实很简单,用两个if节点,判断CustomDepth-SceneDepth的结果。
当结果<=0时,也就是物体开启了自定义深度,但是没有被挡住,那么用本来的颜色,不做处理,也就是PostProcessInput0的Color值。
当0<结果<9999999999时(用一个很大的值来区分是否正无穷),说明物体开启了自定义深度并且被挡住了,这时候需要做处理了,新建一个VectorParameter,调自己想要的颜色就行了。
当结果>9999999999时,也就是为正无穷,说明没有物体开启自定义深度,同样不做处理,用本来的颜色。
SceneTexelSize(场景纹素大小):这是一个float2的值,对应着UV,(u,v),uv均为正数。
这里u就代表着要在横向偏移一个像素单位,uv值中的u需要增加或者减少多少,v也同理。
比如你的屏幕是1920*1080的,那么你屏幕的横向上就有1920个像素,U的值区间是0~1,
那么横向上每个像素就占1/1920≈0.000521,同理纵向上每个像素占1/1080≈0.000926,那么SceneTexelSize的值就为(0.000521,0.000926)。
比如现在有个像素点uv为(0.3,0.5),那么这个像素上方的像素点则为
(0.3,0.5-0.000926),下方则为(0.3,0.5+0.000926),左右同理。
(因为UE4中uv坐标系原点在左上角,所以这里向上为减,向下为加)
TexCoord【0】 全屏uv值
SceneTexture:Ambient Occlusion 场景的SSAO图
SceneTexture:WorldNormal GBuffer的normal图
SceneTexture:CustomDepth 物体单独渲染的深度图
SceneTexture:SceneDepth 场景的深度图
SphereMask的参数
SphereMask有四个输入参数。
A:待检查的位置。
B:圆心的位置。
Radius:半径。
Hardness:硬度,0是完整过渡,100是没有过渡。
输出的是一个0~1之间的数。当A在B之外时,输出0,当A在B的位置时,输出1。A在园内时,输出0~1,具体取决于是否有硬度以及位置。
注意,A和B可以1~4维的vector。
SphereMask的应用
应用应该是很广泛的。当你想以某个东西为中心做个什么事儿的时候。。用这个就方便了。
找到个SphereMask的实现,只不过是unity的
void Unity_SphereMask_float4(float4 Coords, float4 Center, float Radius, float Hardness, out float4 Out) { Out = 1 - saturate((distance(Coords, Center) - Radius) / (1 - Hardness)); }
Desaturation 向灰度渐变
ScreenResolution 屏幕分辨率
Fmod取余数