前言
之前B站上看到的材质搬运课程在收藏夹里放了有段时间了
Ben虚幻4材质课合集
刚好在博客上看到了一位博主整理的系列文章(博主的其他系列文章也都整理得很好)。
UE4 Material 101学习笔记——01-07 介绍/PBR基础/UV扭曲/数据类型/翻页动画/材质混合/性能优化
本着向大佬学习的精神,想抽空过一些这个系列课程。
课程里对应的贴图等资源,可在油管上作者原视频的评论区里下载到。
油管上作者的主页
Lec 02 默认输出材质PBR
UE4的材质编辑器中,默认会带有PBR效果的节点
Lec04 UV扭曲
本节尝试扭曲Texture的效果。
首先可以将一张StarterContent中的Texture作为输入
借助噪声,给Texture的uv输入添加不规则的扰动
可通过改变参数, 调整Texture的不规则程度
代码版本:
#iChannel0 "file://Resources/Distortion.png"
#iChannel1 "file://Resources/T_Checker_Noise_M.png"
const float noiseSpeed = 0.1;
const float noiseLevel = 0.2;
void main() {
vec2 uv = gl_FragCoord.xy / iResolution.xy;
vec2 st = uv + noiseSpeed * iTime;
vec4 texture0 = texture2D(iChannel0, st);
st = uv;
vec2 noise = texture0.rg;
st += noise * noiseLevel;
vec4 texture1 = texture2D(iChannel1, st);
gl_FragColor = texture1;
}
Lec05 序列帧动画
对于一些较为复杂的效果,通常可以先由美术设计师输出序列帧,然后再渲染到纹理上。
UE中自带FlipBook节点,可以支持解析播放下面这种形式的序列帧贴图。
理解下FlipBook节点的原理,可以自己实现一下。
翻译成glsl代码,大致是这样。
#iChannel0 "file://Resources/Explosion.png"
const float m_row = 6.0; // 序列帧贴图行数
const float m_col = 6.0; // 序列帧贴图列数
const float framePerSecond = 32.0; // 每秒多少帧
void main() {
float time = mod(iTime * framePerSecond, m_row * m_col);
float row_id = 5.0 - floor(time / m_row);
float col_id = floor(mod(time, m_col));
vec2 offset = vec2(1.0 / m_col, 1.0 / m_row);
offset *= vec2(col_id, row_id);
vec2 uv = gl_FragCoord.xy / iResolution.xy;
uv /= m_row;
uv += offset;
vec4 color = texture2D(iChannel0, uv);
gl_FragColor = color;
}
Lec06 环境混合
借助法线贴图,让不同材质的混合显得更自然一些。
#iChannel0 "file://Resources/T_Rock_Basalt_D.png"
#iChannel1 "file://Resources/T_Rock_Basalt_N.png"
#iChannel2 "file://Resources/T_Ground_Grass_D.png"
#iChannel3 "file://Resources/T_Ground_Grass_N.png"
void main() {
vec2 uv = gl_FragCoord.xy / iResolution.xy;
vec2 st = uv * 2.0 - 1.0;
vec4 T_Rock_Basalt_D = texture2D(iChannel0, st);
vec4 T_Rock_Basalt_N = texture2D(iChannel1, st);
vec4 T_Ground_Grass_D = texture2D(iChannel2, st);
vec4 T_Ground_Grass_N = texture2D(iChannel3, st);
float pct = T_Rock_Basalt_N.b + 0.02; // 获取岩石表面的法线
pct = pow(pct, 100.0); //
pct = clamp(pct, 0.0, 1.0);
vec4 color = mix(T_Rock_Basalt_D, T_Ground_Grass_D, pct * (1.0 - dot(st,st)));
gl_FragColor = color;
}