版权声明
- 本文为“优梦创客”原创文章,您可以自由转载,但必须加入完整的版权声明
- 文章内容不得删减、修改、演绎
- 本文视频版本:见文末
头发渲染与毛发渲染
- 头发渲染与毛发渲染使用不同的技术
- 头发渲染通常使用插片技术
- 插片技术将头发建模为多个四边形面片
- 这些面片用于渲染头发的外观
- 例如,在《神秘海域4》中,主角的头发使用插片技术渲染
- 黑悟空的头发也是基于此技术
插片技术的具体实现
- 在制作头发模型时,首先将其制作成多个四边形面片
- 这些面片构成了头发的整体形态
- 头发的渲染效果是在这些四边形面片上实现的
头发渲染中的各向异性高光
各向异性的概念
- 头发具有各向异性的特性
- 各向异性指的是高光的反射方向不统一
- 举例:球体渲染中的高光与灯光方向和视角方向的夹角有关
- 夹角越小,高光越亮;夹角越大,高光越暗
- 每个物体表面的方向不同,高光集中在一个小区域
- 头发的高光则不具备这种统一的反射方向
头发的各向异性高光
- 头发的高光是锯齿状的
- 高光在不同方向上的反射是不一样的
- 这使得头发具有独特的光照效果
头发渲染中的具体效果展示
- 以“最终幻想”中的爱丽丝角色为例,展示了头发的各向异性高光
- 头发的高光随视角变化而变化
- 头发丝的反光效果不断扰动,表现出各向异性特征
- 头发具有半透明效果,可以看到面部皮肤透过头发
头发的环境响应
- 头发应该响应环境变化,例如不同的光照条件下
- 在夕阳、西下、白天和夜晚等不同光照下,头发的反光效果不同
- 头发在黑色、直长的情况下,反光更加明显
- 不同的光照环境下,头发反光效果差异显著
头发模型的构建与渲染注意事项
头发模型的构建
- 头发模型通常由四边形面片构成
- 每一层头发面片按顺序叠加,从上至下排列
- 美术工作流中,美术同学负责构建头发模型
- 技术美术需要理解美术工作流,确保效果的实现
头发模型的透明与不透明区域
- 头发模型分为两部分:不透明区域和透明区域
- 不透明区域呈灰色,透明区域呈蓝色
- 需要分别处理透明区域和不透明区域
- 透明区域需要贴上头发的透明贴图,以展示丝状效果
透明头发贴图的应用问题
- 透明贴图可能会导致渲染错误
- 错误现象包括不透明头发覆盖透明头发
- 渲染时可能出现锯齿状效果,影响质量
- 这些是头发渲染中常见的问题,需在处理时注意
头发渲染处理方法
头发颜色渲染
- 头发渲染分为两部分:颜色效果和透明度处理
- 头发颜色渲染的构成主要基于多层结构
- 较厚的头发部分会被表层的头发所遮挡
- 需要实现环境遮蔽效果,模拟头发的层次感
漫反射光照与高光
- 头发受到光线漫反射的影响,需实现漫反射光照
- 头发的高光为各向异性高光,而非简单的圆形高光
- 各向异性高光的效果呈现为zigzag(锯齿状)形式
- 这种效果与头发的自然结构相符合,不能简单地用圆形高光代替
各项异性高光的实现
头发高光的物理特点
- 头发的高光由两层构成:主要高光和次要高光
- 主要高光呈现为发白的高光,通常出现在头发的表面
- 次要高光则呈现为深色调,如红色或黄色
- 主要高光的反光方向偏向发梢
- 次要高光的反光方向偏向发根
次要高光的闪光效果
- 次要高光通常带有闪烁的效果,这种效果在特定部分会更加明显
- 闪光效果是为了增加头发的光泽感和动态感
渲染各向异性高光的两种模型
卡吉亚模型
- 卡吉亚模型用于渲染头发的高光效果,但渲染结果较为单薄
- 该模型生成的高光反射较为简单,只有单一的黄色反射
- 这是网上常用的头发渲染方案
马施纳模型
- 马施纳模型比卡吉亚模型更加精细,能够渲染出更真实的高光效果
- 该模型能够产生主要高光的黄色反射以及次要高光的红色反射
- 这种模型可以提供更丰富的光照效果,提升渲染精度
头发的透明排序
半透明渲染的问题
- 头发的半透明渲染可能会遇到遮挡问题
- 不透明的头发可能会遮挡住半透明的表面头发面片
- 透明排序是半透明头发渲染中的关键问题
实现正确的透明排序
- 为了正确处理头发的透明排序,需要将头发分层渲染
- 头发应当从最里层往外渲染,以避免不透明部分遮挡透明部分
- 在模型制作时,确保头发从内到外的渲染顺序
- 这一细节将在后续进一步讲解
从后往前渲染的实现
渲染过程的步骤
- 渲染过程需要分成多个Pass来处理头发的不同层次
- 头发的渲染顺序是从最里层到最外层
渲染的Pass顺序
- 第一个Pass:渲染头发的不透明部分
- 第二个Pass:渲染头发背面的半透明部分
- 第三个Pass:渲染头发的正面半透明部分
具体示例
- 在渲染马尾时,首先渲染马尾的不透明部分
- 接着渲染马尾背面的半透明部分
- 最后渲染马尾的正面半透明部分
- 同样的过程也适用于刘海的渲染
总结
- 不论是马尾还是刘海,都需要分三遍渲染:不透明部分、背面半透明部分、正面半透明部分
- 该原理是为了解决透明排序问题,确保头发层次渲染正确
透明排序在程序层面的实现
注意:本节内容是“头发渲染”的难点,文字表现力较弱,欢迎移步文末,观看本文视频版本
渲染步骤概述
为了确保头发透明部分的正确渲染,需要分为多个Pass,确保每一层头发从里到外正确渲染
第一步:渲染底层的不透明部分
- 开启双面渲染:确保不透明部分的头发正面和背面都被渲染
- 透明度测试:使用透明贴图来区分不透明和透明部分,只有透明度高于某个阈值(例如0.8)时才进行渲染
- 开启深度写入:对于不透明部分,保持深度写入(z-write)开启
第二步:渲染背面的半透明部分
- 剔除正面三角形:通过开启剔除正面三角形的设置,确保只渲染半透明部分的背面
- 关闭深度写入:在渲染背面半透明部分时关闭深度写入,确保正确的颜色混合
第三步:渲染正面的半透明部分
- 剔除背面三角形:在渲染正面半透明部分时剔除背面的三角形,只渲染正面的头发
禁用 Z-Write 的原因
在渲染半透明对象时,如果不禁用 Z-Write,前面的半透明物体会遮挡后面的不透明物体,导致颜色混合错误。禁用 Z-Write 后,GPU会允许前后物体的颜色混合。
具体原因
- 未禁用 Z-Write:当前面的半透明物体遮挡后面的不透明物体时,前物体的颜色会覆盖后物体,导致混合错误。
- 禁用 Z-Write:允许半透明物体的颜色与后面的物体颜色进行混合,确保正确的视觉效果。
渲染顺序
为了正确进行颜色混合,渲染顺序必须从后到前。渲染错误可能导致不一致的效果,尽管偶尔可能渲染正确。
美术层面的注意事项
尽管程序可以确保透明排序的正确性,但仍需美术同学避免头发的三角形面片穿插。穿插可能导致渲染错误,因此美术模型的制作需要确保头发不会发生穿插。
思考题
渲染多个 Pass
- 在前面的方案中,我们需要三个 Pass 来进行头发的渲染。
- 这种方式能够很好地分层渲染头发的各个部分。
URP 管线的限制
- 我们知道,在 URP(Universal Render Pipeline)管线中,正常情况下只能在一个 Pass 内进行头发的渲染。
三个 Pass 的渲染实现
- 那么,在这种情况下,我们如何在 URP 中进行三个 Pass 的渲染?
- 关键问题在于如何跨越 URP 管线的限制,达到多 Pass 渲染的效果。
渲染状态的设置
- 这三个 Pass 中需要设置不同的渲染状态。
- 如何在每个 Pass 中正确设置这些状态呢?
思考和探索
- 小伙伴们可以思考一下,在 URP 管线下,如何实现头发的渲染,解决这些问题。
透明渲染中的性能问题
透明排序问题
头发的正面与背面渲染
- 在头发渲染时,我们通常会将头发的正面和背面都进行渲染
- 然而,头发的背面大部分情况下是被遮挡的,只有一小部分背面能够被眼睛看见
- 被遮挡的部分头发实际上是不可见的,但由于采用了半透明渲染,这些部分并没有被剔除
渲染开销的浪费
- 即使某些头发部分不可见,它们仍然被渲染
- 这种做法浪费了渲染开销,因为靠近摄像机的头发无法遮挡远离摄像机的部分
- 导致了不必要的渲染开销,影响渲染效率
如何避免无效渲染
- 避免这种无效渲染是我们必须考虑的第一个问题
多 Pass 渲染的开销
内置管线的多 Pass 渲染问题
- 在头发渲染过程中,通常包含不透明的 Pass 和半透明的 Pass
- 在内置管线下进行多 Pass 渲染时,会导致合批打断,这是一个严重的性能问题
- 当每个角色都有多层头发时,开销会变得相当大
SRP 管线下的开销
- 在 URP 或 HDRP 等 SRP 管线下,尽管不会有合批打断的问题,但仍然会无形中增加额外的两个 Pass
- 如何解决这一问题是我们需要进一步探讨的
Early Z 优化无法开启
透明测试与 Early Z 的冲突
- 显卡有一种机制可以判断前面的头发是否遮挡住后面的头发,避免不必要的渲染
- 然而,由于开启了透明测试,这一机制无法启用
- 在透明渲染时,透明测试会在 Shader 代码中进行,但这与提前剔除不可见头发的优化互相冲突
提前剔除不可见头发的优化问题
- 由于透明测试的存在,显卡无法提前剔除不可见的头发,因此无法启用 Early Z 优化
- 这种优化通常是显卡自动开启的,但在透明渲染中被禁用了
- 结果是不可见的半透明像素仍然被渲染,导致了额外的渲染开销
渲染优化与技术实现
渲染 Pass 开销优化
优化前
- 在优化前,马尾和刘海的渲染每个都需要三个 Pass
优化后
- 优化后,每个马尾和刘海的渲染只需要两个 Pass,从而减少了渲染开销
Early Z 限制与 Early Z 优化
Early Z 限制
- 关于 Early Z 的限制,我之前已经提到过,因时间关系在此不再赘述
- 但是,优化后我们可以使 Early Z 生效,提升渲染性能
透明排序优化方案
方案选择
- 另一种优化方式是避免透明排序,但由于这种方法需要较高的性能开销,建议优先选择让 Early Z 生效的方案
- Early Z 优化能在减少渲染开销的同时避免透明排序带来的问题
技术实现与建议
避免照搬论文方案
- 在实现中,不建议完全照搬 SigGraph 论文中的方法
- 如果照搬,渲染结果可能会显得杂乱无章,如同左侧图像中的发丝散乱,效果不理想
优化后的效果
- 通过我们项目中的优化方法,右侧图像中的头发效果更为整齐、自然
项目实践中的应用
- 最终的效果需要在具体的项目实践中落实
- 我们会在 TA 全栈项目中学习这些技巧,帮助大家在项目中实现更好的渲染效果
进阶内容
黑悟空头发渲染
- 黑悟空的头发也可以采用我们项目中的方案进行渲染,调整头发颜色、主要和次要高光、发光区域等
数字人渲染进阶
- 更多关于头发、眼睛、皮肤和服装的渲染内容,可以参考我们的 “TA 全栈项目”的数字人专题,具体请参考文末
小结与思考
参考
- 完整视频请点击本链接观看:https://www.bilibili.com/video/BV1BNUSYYEtu
- 技术交流请加本人v:alice17173