Loading
S7ARRY_SPACE
0%
INITIALIZING
Album Cover
焚蝶
铁痕电台
0:00
Xiaohongshu
终末地渲染还原记录(一)
DOC_ID // 373fd5ONLINE

终末地渲染还原记录(一)

2026-6-2
UPDATED: 2026-6-10
效果还原
2603 CHARS
#UNITY#角色#卡通渲染
S7ARRY
type
Post
status
Published
date
Jun 2, 2026
slug
zmd1
summary
Cloth
tags
Unity
角色
卡通渲染
category
效果还原
icon
password

0. 前言

学习了一阵子卡通渲染,参考了别的大佬的文章和代码,也终于是做出来一个效果还可以的成品,于是写一篇文章记录一下还原的过程。
代码有点乱还没整理,特殊材质也没加进去,先凑合看。
notion image

1. 贴图分析

1.1 Albedo

_Albedo 是基础色贴图。RGB 提供衣服本身颜色,A 通道参与透明相关计算。
notion image

1.2 Normal Map

_NormalMap 只有RG通道有信息,shader里面需要自己算一下
notion image

1.3 MRO Map

_MROMap 是一张通道打包贴图:
  • R:Metallic
  • G:Specular Scale
  • B:Occlusion
  • A:Smoothness
notion image

1.4 Diffuse Ramp

RGB 和 A 的职责分开:
  • RGB:控制漫反射色带
  • A:控制亮暗权重
notion image

1.5 Specular Ramp

_SpecularRamp 用来重映射高光颜色,Shader 计算 GGX 高光,高光颜色会采样 Specular Ramp。
notion image

1.6 CubeMap

_CharCubeMap 用来计算环境高光

1.7 Emission Map

_EmissionMap 处理衣服上的发光区域

2. Shader 向量准备

2.1 TBN

TBN矩阵,采样NormalMap,处理法向

2.2 ViewDirection

ViewDirection会影响高光、IBL、Rim、BackLight Rim。

2.3 主光方向

主光方向、颜色、亮度

2.4 相机前方向

cameraForward 会参与 Wrap 补光、高光半角向量、Rim 方向和 BackLight Rim 判断。

2.5 水平投影与背光关系

cameraLightDot 描述当前镜头和主光在水平面上的关系。相机接近观察背光面时,这个值会升高。

3. 漫反射

Diffuse主要思路:
  • 虚拟顶光作为环境光
  • Ramp Tinted
  • WrapLight补光
  • BaseColor分层:亮部、暗部、暗暗部
  • 根据ao、rampA、shadow来对明暗进行混合

3.1 环境光:虚拟顶光

这里的环境光使用一盏人为设置的虚拟顶光。
对应参数:
相比于SH的环境光,这样做更有体积感?
参考文章里面也有关于这里的解释,也是通过观察游戏里的效果得出的
_VirtualLightParamsdot(N, virtualLightDir) 做remap:
  • Offset:抬高或压低整体受光。
  • Scale:控制虚拟光的影响范围。
  • Bias:提供最低基础亮度。
然后根据阴影权重混合虚拟光颜色,这里不混合也问题不大

3.2 主光:Ramp 漫反射

主光从 NoL 开始:
接着加入相机相关 Wrap Light:
这段逻辑用于处理背光和侧光下的大面积暗面。cameraLightDot 越高,说明镜头越接近观察背光面;cameraYSmooth 会根据相机俯仰控制补光强度;_RampOffsetWrapBlend 决定 Wrap 参与比例。
之后把修正后的 modNoL 映射到 Ramp UV:
Ramp RGB 控制色带,Ramp A 进入后面的阴影。

3.3 Shadow

先取 Unity 主光阴影和自定义 PerObject 屏幕空间阴影:
接着用 SigmoidSharp 来获得更可控的阴影边界:
最终明暗遮罩:
这里混合了四类信息:
  • occlusion:MROMap B 通道,控制材质 AO。
  • rampA:Diffuse Ramp Alpha,控制 Ramp 明暗权重。
  • shadowScene:Unity Shadow 与 PerObject Shadow 的合成结果。
  • _ShadowStrength:整体阴影强度。

3.4 Diffuse Color:亮部、暗部与深暗部

得到 minShadow 后,先构建三层基础漫反射颜色:
三层颜色分别对应亮部、普通暗部、深暗部。
深暗部会再做一次亮度和饱和度修正:
然后通过视角阴影和 Ramp A 混合暗部层次:
再通过 minShadow 从暗部过渡到亮部:
接着把 Ramp RGB 乘进去:
这里先计算 Ramp 的色度。Ramp 色彩越明显,对漫反射颜色影响越强;Ramp 越接近灰阶,对底色影响越弱。
Ramp 改色后会做亮度补偿:
这一步用原本的 mainDiffuseBRDF 亮度约束 Ramp 后的亮度,避免 Ramp 颜色把整体明度推得过高或压得过低。
最后合并虚拟顶光和主光颜色:
Diffuse
Diffuse

4. 高光

高光部分使用 GGX 生成基础形状,再通过 Specular Ramp 做颜色重映射。
先从 MROMap 得到高光参数:
基础高光颜色根据 metallic 混合:
非金属区域通过 MROMap G 通道控制高光强度,金属区域更多继承 Albedo 颜色。
半角向量加入了相机前方向:
这个处理会让高光位置更偏角色展示。纯物理半角向量在镜头变化时容易让高光位置跳到不理想的位置,加入 cameraForward 后,高光会更稳定地服务于画面。
GGX 计算:
Specular Ramp 采样:
默认模式下,Specular Ramp 主要受高光强度和粗糙度影响。
开启 _USE_IRIDESCENT_MODE 后,U 坐标改用 NoV * NoV,颜色会随视角变化,更适合虹彩、镀膜或特殊涂层。(这里只留了个开关,特殊材质还没做)
最后高光乘上阴影相关权重,压制暗部高光:
Specular
Specular

5. 环境高光

首先是CubeMap
粗糙度越高,采样 mip 越高,反射越模糊。
然后计算近似环境 BRDF(数值拟合):
最终 Cubemap 贡献:
IBL 强度受到 virtualDiffInt 控制(这里其实应该是环境光的整体强度)。
暗部仍然可以有反射,但整体强度会被压在可控范围内。
notion image

6. Rim

Rim 分成普通 Rim 和 BackLight Rim。

6.1 普通 Rim

普通 Rim 基于 Fresnel:
_RimArea 控制 Rim 范围。
还要计算和相机相关的 Rim 方向:
再根据角色中心到当前像素的水平向量,控制 Rim 偏向合适的一侧:
最终普通 Rim:
_RimTint 控制 Rim 受 baseColor 染色的比例。
notion image

6.2 BackLight Rim

BackLight Rim 用来处理逆光边缘。
它主要综合这些因素:
  • 当前镜头和主光是否接近背光关系。
  • 表面是否处于视角边缘。
  • 当前基础色是否偏暗。
  • 法线和主光在水平面上的关系。
最终结果:
notion image

7. Emission

Emission 是最后的独立叠加项。
notion image

8. 合成

这里还有一段亮部去饱和处理:
它可以让高亮区域更干净,减少颜色过饱和。
最终合成大致是:

9. 最后

衣服部分还有一些特殊材质没有实现,最近去研究别的了,后续整理好了再发吧。

参考

 
NAVIGATION // Related Articles
Loading...