公司动态

Substance Designer与Unity Shader实现丝绸PBR材质全流程解析

📅 2026/8/7 6:06:07
Substance Designer与Unity Shader实现丝绸PBR材质全流程解析
1. 项目概述与核心思路拆解看到“用Substance Designer制作丝绸PBR贴图”这个标题很多朋友的第一反应可能是这不就是一个材质制作教程吗但如果你仔细琢磨“从A站大神作品反推”这个前缀就会发现它的价值远不止于此。这实际上是一种非常高效的学习方法——通过逆向工程顶尖艺术家的成品来拆解其背后的技术逻辑和审美构成。丝绸材质尤其是带有各向异性光照特性的高级丝绸一直是实时渲染中的一个经典挑战。它不像金属或石材那样有固定的粗糙度和法线表现丝绸的光泽会随着观察方向和纤维编织方向的变化而产生流动般的高光这种视觉特性对贴图制作和Shader编写都提出了更高的要求。这个项目的核心目标是复现出那种在A站ArtStation上常见的、质感高级的丝绸材质。它不仅仅是做出几张看起来像丝绸的贴图而是要制作一套完整的、基于物理的渲染PBR贴图并最终在Unity引擎中通过自定义Shader将这些贴图正确地“驱动”起来还原出丝绸特有的柔软光泽和各向异性高光。整个过程涉及两个核心工具链Substance Designer用于无程序化地生成所有必需的纹理Albedo, Roughness, Metallic, Normal, Height, 以及关键的Anisotropy贴图Unity则用于搭建最终的渲染环境与Shader逻辑。对于技术美术TA、材质艺术家甚至是有志于提升画面表现力的开发者来说掌握这套流程意味着你拥有了从零开始构建复杂表面质感并精准控制其渲染表现的能力。2. 丝绸材质特性分析与贴图需求定义在动手之前我们必须先搞清楚我们要模拟的对象——丝绸——到底有什么独特的物理和视觉特征。盲目地开始生成噪点或绘制图案最后得到的可能只是一团看起来“光滑”的东西而非丝绸。2.1 丝绸的视觉特征解析丝绸之所以看起来高级源于其复杂的微观结构和光线相互作用。首先丝绸由极细的、表面光滑的蛋白质纤维蚕丝编织而成。这使得它的表面在宏观上非常光滑反射率高但并非像镜子一样的完美镜面反射。其次也是最关键的一点丝绸的编织结构如斜纹、缎纹导致了其表面的微观几何具有方向性。当光线照射时沿着编织方向经线或纬线的高光会特别明亮、集中且狭长而垂直于编织方向的高光则较弱甚至消失。这种随着方向变化的高光特性就是“各向异性”Anisotropy。在日常观察中你可以把它想象成CD光盘的表面或者拉丝金属。当你转动它们时高光会像一道明亮的“光带”一样滑动。丝绸的高光更柔和、更扩散但滑动和流动的感觉是类似的。此外丝绸的Albedo反照率/基础色通常饱和度较低带有一种柔和、内敛的色泽并且由于纤维的透光性在边缘或薄层处可能呈现出轻微的次表面散射SSS效果不过在我们的PBR流程中这一步通常用更简单的方式模拟。2.2 PBR贴图清单与功能映射基于以上分析我们需要在Substance Designer中制作以下一套贴图每一张都承载着描述丝绸某一项物理属性的信息Albedo (RGB)基础颜色贴图。决定丝绸的固有色。对于丝绸这通常不是单一纯色而是带有非常微妙的颜色变化、纹理或图案例如细微的云纹、色织条纹等。颜色明度Value不宜过高饱和度Saturation应保持中等偏低以体现其柔和感。Roughness (Grayscale)粗糙度贴图。控制表面微观不平整度决定高光的锐利或模糊程度。丝绸的整体粗糙度值很低例如0.1-0.3表示表面光滑。但关键点在于我们需要让粗糙度也呈现出各向异性即沿着编织方向更光滑粗糙度更低垂直方向略粗糙。这通常不会单独用一张图而是通过后续的Shader处理但可以在基础粗糙度图上制作一些方向性的微纹理作为基底。Metallic (Grayscale)金属度贴图。丝绸是非金属所以这张图理论上可以全黑0。但在实际工作流中有时会轻微地提高某些高光区域的数值如0.1-0.2来模拟那种极其光滑的非金属表面带来的强烈菲涅尔反射效果但这需要谨慎操作最好在Shader中用更物理的方式控制。Normal (RGB)法线贴图。模拟表面的微观凹凸细节。对于丝绸法线贴图的核心是表现编织纹理的走向。这些纹理不是强烈的凹凸而是非常细腻的、有方向性的条纹或波纹。法线的方向直接影响了各向异性高光的走向。Height (Grayscale)高度贴图。用于视差或曲面细分提供深度信息。在丝绸材质中它可以用来强化编织纹理的立体感但通常不是必须项除非需要极近距离的细节。Anisotropy (Grayscale) Anisotropy Direction (Grayscale)这是丝绸材质的灵魂所在。各向异性强度贴图Anisotropy控制表面各向异性效应的强弱0为无1为最强。各向异性方向贴图Anisotropy Direction则编码了表面微观沟槽的方向信息通常用0-1的灰度值对应0-360度的方向。在Substance Designer中我们可以通过处理法线或高度图来衍生出这两张图。注意并非所有渲染管线或Shader都直接支持Anisotropy贴图。在Unity的标准URP/HDRP或自定义Shader中我们通常用一张贴图来存储方向信息如法线贴图的某个通道而强度则可能作为一个常数或由粗糙度图调制。3. Substance Designer核心节点图构建Substance Designer的核心魅力在于其节点化的程序化生成逻辑。我们不是“画”出贴图而是“搭建”一个生成贴图的流水线。下面我将拆解构建丝绸材质节点图的关键步骤。3.1 基础编织纹理的生成丝绸的视觉基础是它的编织结构。我们可以从模拟基础的织物纹理开始。创建Tile Generator平铺生成器这是起点。我会选择一个Shape: Parquet或Custom Map来生成基础的网格或条纹图案。关键参数是Pattern Width/Height和Random Offset用于控制编织单元的密度和随机性避免过于机械的重复。添加Directional Warp方向扭曲单纯的网格看起来像麻布不像丝绸。丝绸的纤维有轻微的弯曲和流动感。使用Directional Warp节点用一个低频率的Perlin Noise作为扭曲图对Tile Generator进行轻微扭曲。Intensity强度要设得很低如0.1目的是打破僵直的线条营造出柔软、有机的走向。生成法线与高度信息将上一步得到的灰度图代表高度连接到Normal节点生成初步的法线贴图。同时它本身也可以作为高度图的基底。此时法线图已经具备了方向性这是我们后续提取各向异性方向的基础。实操心得在这个阶段不要追求过高的对比度或强烈的凹凸。丝绸是细腻的所以Normal节点里的Intensity参数建议设置在0.5-1.5之间进行微调。可以多用Blur模糊节点来柔化边缘模拟纤维的柔和感。3.2 各向异性信息的提取与强化这是将普通织物纹理转化为丝绸质感的关键一步。从法线图提取流向使用Gradient Vector节点。将上一步生成的法线贴图输入这个节点会计算图像中每个像素的梯度变化最快方向并输出一张矢量图两个通道代表方向。这个方向信息本质上就是微观沟槽的走向。创建各向异性方向图Gradient Vector节点的输出不能直接用作贴图。我们需要使用Vector Morph节点将其转换为灰度方向图。通常我们会取其中一个通道例如G通道或者使用Direction to Grayscale之类的自定义节点将0-360度的方向信息线性映射到0-1的灰度值。这张灰度图就是我们的Anisotropy Direction Map。生成各向异性强度图强度图定义了哪里各向异性效应更强。一个简单有效的方法是使用Histogram Scan节点作用于基础高度图或法线图的强度。设定一个范围提取出那些“脊线”或“沟槽”区域——这些微观结构显著的地方各向异性效应就应该更强。然后通过Levels节点调整对比度得到一张黑白分明的强度遮罩。细化强度图直接得到的强度遮罩可能边缘太硬。用Blur进行高斯模糊然后用Levels再次调整得到一个带有柔和过渡的强度图。这很重要它能让各向异性高光的出现和消失更加自然而不是生硬的开关。踩过的坑早期我尝试直接用高度图作为强度图结果导致高光在平坦区域也出现显得很假。必须记住各向异性强度与表面的方向性微观结构的显著性相关而不是单纯的整体高度或粗糙度。3.3 颜色Albedo、粗糙度与细节融合有了结构信息接下来需要赋予它颜色和表面光学属性。Albedo制作使用Uniform Color节点作为基色例如一种淡紫色或香槟色。然后使用之前生成的Direction Map或Tile Generator图作为遮罩通过Blend节点混合第二种略有差异的颜色例如更浅或稍暗的同色系颜色模拟色织效果。混合模式可以选用Overlay,Soft Light或Multiply不透明度设置得很低5%-15%目标是产生极其微妙的变化而非明显的图案。粗糙度图制作新建一个Grayscale节点赋予一个基础值比如0.15表示很光滑。然后将Anisotropy Intensity Map反相因为沟槽深处可能更粗糙一点通过Blend节点以Multiply模式混合到基础粗糙度上强度控制在10%左右。这样在各向异性强的区域粗糙度会有细微变化增加视觉复杂度。还可以添加一个非常微弱的Grunge Map污渍贴图用极低的强度混合模拟丝绸表面的自然使用痕迹。细节法线添加基础法线图描述的是编织结构。我们还需要更微观的细节比如纤维本身的细微不平。添加一个Perlin Noise节点设置非常高的Frequency如500然后连接到另一个Normal节点Intensity设为0.2左右。最后通过Normal Blend节点将微观法线混合到基础法线上。这能有效打破表面在近距离观察时的“塑料感”让材质更加真实。工具选型解析为什么全程用程序化节点而不是手绘因为程序化意味着无限可控性和非破坏性编辑。你可以随时返回调整Tile Generator的密度、Noise的强度所有下游贴图都会自动更新。这对于迭代和适配不同分辨率的纹理需求至关重要。4. Unity Shader连接与各向异性光照实现贴图制作完毕导出为PNG或TGA格式建议使用线性空间的.exr格式以保留更大动态范围。接下来就是在Unity中让这些贴图“活”起来。我们将创建一个自定义Shader实现基于物理的各向异性光照模型。4.1 Shader基础框架与属性定义在Unity中创建Unlit Shader然后修改为基于物理的光照模型。这里以Unity URP通用渲染管线为例因为其更现代且易于定制。Shader Custom/SilkAnisotropicPBR { Properties { // 基础贴图 _BaseMap (Albedo (RGB), 2D) white {} _BaseColor (Base Color, Color) (1,1,1,1) // 表面属性贴图 _MetallicGlossMap(Metallic (R) Roughness (A), 2D) white {} _Metallic (Metallic, Range(0,1)) 0.0 _Roughness (Roughness, Range(0,1)) 0.5 // 法线与高度 _BumpMap (Normal Map, 2D) bump {} _BumpScale (Normal Scale, Float) 1.0 _ParallaxMap (Height Map, 2D) gray {} _Parallax (Height Scale, Range(0, 0.1)) 0.01 // **核心各向异性属性** _AnisoMap (Anisotropy Direction (RG) Intensity (B), 2D) gray {} _Anisotropy (Anisotropy Strength, Range(-1,1)) 0.5 _AnisoRoughness (Anisotropic Roughness Bias, Range(-0.5,0.5)) 0.0 } SubShader { ... } }参数详解_AnisoMap这是一张打包贴图。R和G通道存储了从Substance Designer导出的方向信息通常是经过编码的向量B通道存储强度信息。这样只需采样一次性能更优。_Anisotropy控制各向异性高光的整体强度。正值和负值会影响高光延展的方向可以用于匹配不同的编织方向视觉习惯。_AnisoRoughness一个微调参数用于在各向异性方向上对基础粗糙度进行偏移模拟沿纤维方向和垂直方向不同的光滑度。4.2 各向异性高光计算的核心函数在片元着色器Fragment Shader中我们需要替换标准PBR模型中的高光项。常用的各向异性高光模型有Ward、Ashikhmin-Shirley等。这里以一种在游戏行业较流行的、基于GGX分布的修改版为例它更易于理解和实现。关键步骤是计算各向异性粗糙度roughnessT和roughnessB以及切线向量tangentT和tangentB。// 从贴图中解码各向异性方向 float2 anisoDir tex2D(_AnisoMap, uv).rg * 2.0 - 1.0; // 从[0,1]映射到[-1,1] float anisoStrength tex2D(_AnisoMap, uv).b * _Anisotropy; // 构建各向异性切线空间 float3 worldNormal normalize(WorldNormal); float3 worldTangent normalize(WorldTangent); float3 worldBitangent normalize(cross(worldNormal, worldTangent)); // 根据方向图旋转切线 float3 anisoTangent normalize(anisoDir.x * worldTangent anisoDir.y * worldBitangent); float3 anisoBitangent normalize(cross(worldNormal, anisoTangent)); // 计算各向异性粗糙度 float baseRoughness tex2D(_MetallicGlossMap, uv).a * _Roughness; float roughnessT clamp(baseRoughness _AnisoRoughness, 0.001, 1.0); float roughnessB clamp(baseRoughness - _AnisoRoughness, 0.001, 1.0); // 用强度参数插值回各向同性便于控制 roughnessT lerp(baseRoughness, roughnessT, abs(anisoStrength)); roughnessB lerp(baseRoughness, roughnessB, abs(anisoStrength)); // 然后在计算高光时使用roughnessT和roughnessB分别代替原来的单一粗糙度 // 并让高光形状沿着anisoTangent方向拉伸。 // 此处省略具体的BRDF计算代码它涉及较复杂的数学但核心思想是修改法线分布函数NDF为什么这么计算传统的各向同性高光认为表面在所有方向上的粗糙度相同。而我们通过roughnessT和roughnessB定义了沿着切线方向anisoTangent和副切线方向anisoBitangent两个不同的粗糙度。当这两个值差异越大时高光就会在更光滑的方向上被拉长形成狭长的光带这正是丝绸高光的特征。anisoStrength参数则让我们可以动态调整这种各向异性效果的强弱甚至完全关闭它。4.3 在Unity材质检视器中调试将编写好的Shader赋给一个材质球并将从Substance Designer导出的贴图分别拖入对应的纹理槽。基础效果验证首先关闭各向异性强度检查Albedo、Normal和Roughness贴图是否正确模型是否有基础的光照反应。开启各向异性逐步调高_Anisotropy参数。你应该能看到高光从圆点状逐渐变成沿着丝绸纹理方向延伸的条状。旋转视角或旋转光源这条状高光应该会平滑地滑动。微调调整_AnisoRoughness观察高光条带的宽度和锐利度变化。配合_Roughness整体参数找到最适合你心目中丝绸质感的那一组数值。方向校正如果发现高光延展的方向与纹理走向垂直或不对检查两个地方一是Substance Designer中生成方向图时向量的编码方式是切线空间还是世界空间是否需要旋转90度二是Unity中模型的切线空间是否一致。可能需要在对anisoDir进行采样后增加一个旋转操作例如float2 rotatedDir float2(-anisoDir.y, anisoDir.x);。实操心得调试各向异性Shader时使用一个简单的、UV展开平整的平面Plane或圆柱体Cylinder作为测试对象非常有效。复杂的模型可能会因为切线空间变形而干扰判断。确保在_AnisoMap的导入设置中取消勾选sRGB (Color Texture)因为它存储的是方向数据而非颜色。5. 常见问题、性能优化与效果提升在实际应用这套流程时你肯定会遇到一些挑战。下面是我总结的一些典型问题及其解决方案。5.1 贴图制作与连接问题问题1从Substance Designer导出的方向图在Unity里看起来是纯色或奇怪图案没有方向变化。排查首先在Substance Designer的2D View中检查Anisotropy Direction贴图的预览。确保它不是一个常数。通常方向图看起来是灰蒙蒙的、有平滑渐变的。解决检查导出设置。方向图必须是灰度图且确保在导出时没有错误地应用了色彩空间转换如sRGB。在Unity中导入该贴图时Texture Type选择Default并确保sRGB (Color Texture)是取消勾选的因为方向信息是线性数据。问题2丝绸的高光看起来“闪烁”或“断断续续”不连续。排查这通常是各向异性方向图存在不连续点或接缝导致的尤其是在模型UV接缝处。解决在Substance Designer中确保用于生成方向图的源纹理如法线或高度本身是tilable可无缝平铺的。使用Tile Sampler节点并开启Random Offset和Blending可以帮助减少明显的重复图案。在烘焙或生成最终方向图后使用Histogram Scan节点检查值域是否覆盖了0-1全范围并用Gradient Map进行重新映射确保方向变化平滑。在Unity中对于有UV接缝的模型考虑在Shader中使用世界空间或模型空间的方向计算但这会更复杂。一个折中方案是确保模型的UV展开尽可能减少接缝或者将接缝藏在不易察觉的地方。问题3材质在特定角度下看起来异常黑或没有高光。排查检查法线贴图是否正确应用。在Unity材质中将Bump Scale暂时设为0如果问题依旧则可能不是法线问题。更可能是各向异性计算中切线或副切线向量计算错误导致在某些视角下高光计算失效。解决在Shader中输出anisoTangent或anisoBitangent作为颜色到屏幕用于调试检查它们是否是单位向量且方向正确。确保cross(worldNormal, anisoTangent)的计算顺序正确叉乘顺序影响副切线方向。5.2 Shader性能与优化建议自定义各向异性Shader会比标准Shader消耗更多性能因为它有更复杂的计算。贴图采样优化我们使用了多张贴图。考虑将Metallic和Roughness合并到一张贴图的R和A通道。将Anisotropy Direction (RG)和Intensity (B)也合并到一张贴图。这样可以将采样次数减少1-2次对性能提升显著。计算简化各向异性BRDF计算比各向同性复杂。如果项目对性能极其敏感可以考虑使用一种简化的“假”各向异性模型。例如仍然使用标准的GGX高光但根据视角和切线方向动态地修改高光形状的UV偏移或强度来模拟各向异性效果。虽然物理上不准确但在移动端或大量使用的场合能取得不错的视觉效果与性能平衡。LOD支持为你的Shader编写细节层次LOD版本。在远距离可以完全关闭各向异性计算回退到标准的PBR着色甚至使用更简单的光照模型。SRP Batcher兼容如果你使用URP/HDRP确保Shader的属性和变量声明符合SRP Batcher的要求这样可以实现更高效的合批渲染。5.3 效果提升技巧次表面散射SSS模拟真正的丝绸有轻微的透光性。我们可以在Shader的边缘光Rim Light或自定义光照模型中加入基于厚度图Thickness Map或简单NdotV的散射模拟。用一个柔和的颜色如淡黄色在边缘处进行加法混合能立刻增加材质的柔软感和真实感。环境反射优化丝绸的高光清晰对环境反射非常敏感。使用高质量的天空盒Skybox或反射探头Reflection Probe至关重要。可以考虑使用屏幕空间反射SSR来增加动态物体的反射细节。动态效果通过Shader Graph或脚本让_Anisotropy强度或方向随着时间、风力或角色运动轻微变化可以模拟丝绸随风飘动时光泽流动的生动效果。这需要将参数与时间或顶点动画数据相关联。最后再分享一个小技巧在Substance Designer中完成基础材质后不要急于导出所有贴图。先通过Substance Player插件或导出sbsar文件到Unity的Substance Plugin中在Unity内进行实时参数调整和预览。这样你就能在最终的游戏光照环境下直接微调颜色、粗糙度和各向异性强度确保材质在目标场景中看起来是最佳的实现从创作工具到游戏引擎的无缝迭代。这套从逆向分析到正向实现再到引擎内精调的工作流才是高效产出高质量游戏美术资源的关键。