01 雪
使用 菲尼尔 给基础颜色增加边缘过渡

闪烁的雪点

通过两层 闪烁的点进行混合
-
使用 ViewSize / 512 ,其中512为贴图的尺寸
-
由于雪点只有在 光照情况下才可以看到,因此使用 SkyAtmosphereLightDirection 和 VertexNormalWs,通过太阳的方向和顶点的法向 通过Dot计算得到遮罩
效果:

ScreenPosition

-
ViewportUV(常用)
- 范围:
(0,0)左上 →(1,1)右下 - 就是屏幕 UV ,和
TexCoord0在全屏后处理里基本一样。
- 范围:
-
PixelPosition
- 范围:
(0,0)→(ViewSize.X, ViewSize.Y) - 等于:
ViewportUV * ViewSize,直接是像素坐标。
PixelPosition = ViewportUV × ViewSize
ViewportUV = PixelPosition ÷ ViewSize
- 范围:
ViewSize
输出当前渲染画面的宽度(X 轴)和高度(Y 轴)像素值
-
主要用途:
- 制作自适应效果,比如根据屏幕分辨率调整 UI、特效的大小
- 实现和屏幕尺寸相关的后处理效果(如径向模糊、边缘检测)
- 让材质在不同分辨率下保持效果一致
ScreenResolution


法线
计算法线的方式
只需要RG的内容
DeriveNormalZ( RG * 2 - 1)
- 多层法线混合增加细节
- 使用 BlendAngleCorrectedNormals

使用 DeriveNormalZ(Normal * 2 -1) 是对 法线 进行增强边缘细节,需要配合正常的法线使用不然就会出现黑色法线,是负数
- 乘2 减1 是 将取值区间由 0,1 转换为 -1,1
DeriveNormalZ
通过 法线的 XY 通道计算法线,注意 不同的 法线 计算方式略有不同,要考虑到平台以及存储时进行了什么设置
- 通常生成的法线贴图 Z 通道 可以不需要,在UE中可以看到B通道是无法关闭的,因为是通过计算得到的
- 因此 在 优化时,便可以只是要两个通道 存储法线,多余的通道可以存放 Roughness 、 AO 等灰度贴图
Normal = (X, Y, Z),且单位向量,满足勾股定理
,那么

使用 HLSL
float2 N_xy = Normal.xy;
float Z = sqrt(1.0 - dot(N_xy, N_xy) );
return float3(N_xy, Z);

dot 计算,相当于两个向量的乘法,二维向量的乘法 是一个常量
- (a,b)(c,d) = ac + bd
BlendAngleCorrectedNormals
专门用来正确混合两张法线贴图的材质函数(Material Function)
-
避免直接
Add/Multiply导致的细节变平、光照错乱问题 -
直接
Add:细节会过强、扭曲 -
直接
Lerp:细节会变平、丢失 -
BlendAngleCorrectedNormals:按角度校正算法重定向细节法线,保留基础形状 + 叠加细节,效果自然

02 岩石
缩放模型会导致 贴图的细节丢失,解决方法
将模型的 缩放与 UV 进行 相乘


多层法线的混合
利用加法进行计算,需要将混合的法线,B 设置为0,只需要将 RG 利用加法进行相加即可
( RG \* (2,2,0) - (1,1,0) )
增加细节使用,三层法线,两层细节法线
- 将 B 使用 1-x 取反后 ,用作粗糙度 并累加
- 如果 有 AO 贴图,可以 将 AO 与 基础纹理 采用 Blend_Overlay 进行混合
效果:

Blend_Overlay
暗部相乘、亮部滤色 ,整体增强对比度、保留底层形状,非常适合叠细节(脏迹、划痕、磨损)
- UE 里 的 Photoshop 叠加(Overlay)图层模式
03 积雪岩石
主要利用 法线在世界空间的 Z方向的朝向,得到遮罩
- 用于材质的 Lerp混合

效果:

04 冰



冰表面

制作折射
- 将顶点法线转换为 屏幕空间,并于 屏幕的 UV进行相加,相当于使用法线对屏幕进行空间的扰乱(类似于特效制作中Distortion),将得到的 UV传入 Scene Color
Scene Color
Scene Color = 当前屏幕已渲染完成的场景最终颜色(帧缓存画面)
- 仅限:后处理材质、屏幕空间材质、UI 材质

Scene Color 与 SceneTexture:SceneColor(新)
-
两种的一致的,只不过 Scene Color是直接调用的,SceneTexture需要设置
Scene Color + ScreenPosition(ViewportUV) + ViewSize = 绝大多数屏幕特效基础
常用方式:
-
给整张画面叠暗角、滤镜、胶片颗粒、划痕、雾效、复古滤镜
-
局部颜色修正、调色
- 色相偏移、饱和度调整、冷暖色调分离
- 配合
ScreenPosition做左右分色、上下渐变调色
-
扭曲 / 扰动画面(水汽、热浪、镜头晃动)
-
结合像素位置做锐化 / 模糊 / 描边
-
ScreenTexelSize+ViewSize取相邻像素,实现:- 全屏模糊、径向模糊
- 画面锐化、边缘描边、卡通轮廓
-
冰内部纹理
采用自定义 反射向量作为 UV进行采样
-
使用 CustomReflectionVector 获取 反射向量
-
使用 RG 作为基础 UV 的 Distortion
-
B取绝对值,用 100 / abs(B) * RG,其中 100 表示可见程度,数值越大,越深
-
使用 1/1024 8 RG 控制平铺,其中 1024纹理的像素

使用两层反射,制作并冰层的遮罩
CustomReflectionVector
用自定义法线 (可和材质主法线不一样)去算反射向量 ,专门用来做细节凹凸反射、镜面划痕、局部扭曲反射

和默认 ReflectionVectorWS 的区别
- ReflectionVectorWS :固定用主法线 + 相机方向算(受材质 Normal 端口影响)
- CustomReflectionVector :用你输入的任意法线 算,和主法线完全独立
反射公式:
R = reflect(-CameraDir, CustomNormalWS)
HLSL 代码:
// HLSL
float3 Nor = normalize(NormalVector);
float3 Cam = CameraVector;
return dot(Nor,Cam)*Nor*2 - Cam;
// 简化
float3 N = normalize(NormalVector);
return 2 * dot(N, CameraVector) * N - CameraVector;
根据平行四边行法则,2*Normal*cos=Ref+Camera
05 金属
利用法线,获取菲尼尔 边缘,作为 UV 采样一条颜色纹理,与金属 的基础颜色 混合


效果:
旗帜
注意:
- 创建的平面坐标轴要在边缘
- 注意平面又有很多的顶点,不然飘动不起来

基础飘动
通过采用本地位置,根据需要飘动的轴 使用 ComponentMask
- 注意 要使用 要先乘以0.001,因为UE的单位是 1m,为何是0.001呢,是因为 频率1m作为基准还是有点大
然后就是使用 时间,控制 摆动速度和方向
使用 Sine 创建 波形,再通过 参数,控制 振幅
最后乘以 位置信息,作为渐变,让开始位置到结束位置 振幅依次增加

- 平面位于XZ,则Y轴是 振幅 的方向
- 平面位于YZ,则X轴是 振幅 的方向,此处 则是采用这种
LocalPosition
UE内置节点,其实就是 WoldPosituion 通过 Transform 进行空间变换得到的


优化
旋转,会导致 偏移失效
仅仅只需要,将偏移的向量 转换空间
- 本地空间 到 世界空间即可
注意:需要修改 Amplitude 为 Z轴
- 原因是 物体在场景中进行了旋转,会导致 世界空间 和本地空间的变换 出现差异
- 注意模型的轴向 与 世界坐标轴的区别

本地轴向:

世界轴向:

法线
查看 法线信息
- 视口 中 Lit 位置,找到 Buffer Visualization 可以查看所有渲染阶段的 输出

可以看到 旗帜的法线是没有变化的,是统一的颜色
- 这很明显不合理,因此需要进行调整

制作思路:
- 采用 sin + 0.5 = 1- Cos 作为法线的振幅,在数学的三角形中可以知道 Sin 和 Cos的关系

通过对比波形

最后得到的节点:

注意法线设置 与 模型轴向 有关

