30 lines
1.4 KiB
Plaintext
30 lines
1.4 KiB
Plaintext
shader_type spatial;
|
||
// 面部 = 两层贴图的合成:底图(预设脸)+ 笔画层(玩家自绘),后者带 alpha 盖在前面。
|
||
// 两层都用「面部孤岛重映射后的 UV」采样,所以一张方形小图就能正好铺满整张脸。
|
||
//
|
||
// 为什么不是直接把贴图换掉:画布只装笔画、不装底图,橡皮擦掉笔画后露出来的是预设脸,
|
||
// 而不是把脸擦成黑洞。这也是它能一边切预设一边保留手绘笔画的原因。
|
||
|
||
// 面部 UV 孤岛(实测自 mouse.glb 的 body_mesh surface 1 "face"):
|
||
// u 0.142~0.356,v 0.038~0.238。v 往下外扩到 0.031 是为了取成正方形,避免拉伸。
|
||
uniform vec2 face_uv_min = vec2(0.142, 0.031);
|
||
uniform float face_uv_size : hint_range(0.01, 1.0) = 0.214;
|
||
|
||
// 预设脸。没接上时给张白图,至少不会一片黑
|
||
uniform sampler2D base_tex : source_color, filter_linear, repeat_disable,
|
||
hint_default_white;
|
||
// 玩家笔画层(一个透明底的 SubViewport)。没接上时给张全透明图,等于没画
|
||
uniform sampler2D paint_tex : source_color, filter_linear, repeat_disable,
|
||
hint_default_transparent;
|
||
|
||
void fragment() {
|
||
vec2 uv = (UV - face_uv_min) / face_uv_size;
|
||
vec4 base = texture(base_tex, uv);
|
||
vec4 paint = texture(paint_tex, uv);
|
||
|
||
ALBEDO = mix(base.rgb, paint.rgb, paint.a);
|
||
// 顶掉 GLB 里 lambert1 那套手感,不然脸会比身体亮一块
|
||
ROUGHNESS = 1.0;
|
||
METALLIC = 0.0;
|
||
}
|