- 用户指南
- Components
- 寻路
- 动画组件
- 资源组件
- 音频组件(AudioComponent)
- 音频侦听器(AudioListener)
- 音频源(AudioSource)
- 音频过滤器(AudioFilter)(仅限专业版)
- 混响区域(ReverbZone)
- 麦克风(Microphone)
- 物理组件(PhysicsComponent)
- 箱体碰撞体(BoxCollider)
- 胶囊碰撞体(CapsuleCollider)
- 角色控制器(CharacterController)
- 角色关节(CharacterJoint)
- 可配置关节(ConfigurableJoint)
- 恒定力(ConstantForce)
- 固定关节(FixedJoint)
- 铰链关节(HingeJoint)
- 网格碰撞体(MeshCollider)
- 物理材质(PhysicsMaterial)
- 刚体(Rigidbody)
- (SphereCollider)
- 弹簧关节(SpringJoint)
- 交互布(InteractiveCloth)
- 蒙皮布(SkinnedCloth)
- 车轮碰撞体(WheelCollider)
- 游戏对象(GameObject)
- 图像效果(ImageEffectScripts)
- 高光溢出和镜头光晕(BloomandLensFlare)
- 模糊(Blur)
- 相机运动模糊(MotionBlur)
- 颜色修正曲线(ColorCorrectionCurve)
- 颜色修正(ColorCorrection)
- 颜色修正查找纹理(ColorCorrectionLookupTexture)
- 对比度增强(ContrastEnhance)
- 对比度拉伸(ContrastStretch)
- 起皱(Crease)
- 视野深度(DepthofField)3.4
- 视野深度(DepthofField)
- 边缘检测(EdgeDetection)
- 鱼眼(Fisheye)
- 全局雾(GlobalFog)
- 发光(Glow)
- 灰度(Grayscale)
- 运动模糊(MotionBlur)
- 噪波和颗粒(NoiseAndGrain)
- 噪波(Noise)
- 屏幕叠加(ScreenOverlay)
- 棕褐色调(SepiaTone)
- 边缘检测效应
- 阳光照射(SunShaft)
- 屏幕空间环境光遮蔽(SSAO)(ScreenSpaceAmbientOcclusion(SSAO))
- 倾斜位移(TiltShift)
- 色调映射(Tonemapping)
- 旋转(Twirl)
- 渐晕(Vignetting)(和色差(ChromaticAberration))
- 状态同步详细信息
- 旋涡
- 设置管理器(SettingsManager)
- 网格组件(MeshComponents)
- 网络组
- 效果
- 渲染组件
- 变换组件(TransformComponent)
- UnityGUI组
- 向导
- 地形引擎指南(TerrainEngineGuide)
- 树木创建器指南
- 动画视图指南
- GUI脚本指南
- 网络参考指南
- 移动设备上的网络连接
- 高级网络概念
- Unity中的网络元素
- RPC详细信息
- NetworkLevelLoading
- 主服务器
- 最小化网络带宽
- 社交API
- 内置着色器指南
- Unity的后台渲染
- 着色器参考
- ShaderLab语法:Shader
- ShaderLab语法:Properties
- ShaderLab语法:子着色器(SubShader)
- ShaderLab语法:Pass
- ShaderLabsyntax:Color,Material,Lighting
- ShaderLab语法:剔除和深度测试(Culling&DepthTesting)
- ShaderLab语法:纹理组合器(TextureCombiners)
- ShaderLab语法:雾(Fog)
- ShaderLab语法:Alpha测试(Alphatesting)
- ShaderLab语法:混合(Blending)
- ShaderLab语法:通道标记(PassTags)
- ShaderLab语法:名称(Name)
- ShaderLab语法:绑定通道(BindChannels)
- ShaderLab语法:使用通道(UsePass)
- ShaderLab语法:GrabPass
- ShaderLab语法:子着色器标记(SubShaderTags)
- ShaderLab语法:回退(Fallback)
- ShaderLab语法:自定义编辑器(CustomEditor)
- ShaderLab语法:其他命令
- ShaderLab语法:Pass
- 高级ShaderLab主题
- ShaderLab内置值
- 其他
- 网络视图
- 导航网格 (Navmesh) 和寻路 (Pathfinding)(仅限专业版 (Pro))
- Mecanim 动画系统
- 动画状态机
- 混合树 (Blend Tree)
- 在 Mecanim 中使用动画曲线 (Animation Curves)(仅限专业版 (Pro))
- 循环动画片段
- Animation State Machine Preview (solo and mute)
- 动画参数
- 旧动画系统
- 使用类人动画
- 动画层
- 资源导入与创建
- 音轨模块
- 减少文件大小
- 光照贴图 UV
- 资源准备和导入
- 如何安装或升级标准资源 (Standard Assets)?
- FBX 导出指南
- 从 Maya 中导入对象
- 从 Cinema 4D 中导入对象
- 从 3D Studio Max 中导入对象
- 从 Cheetah3D 中导入对象
- 从 Modo 中导入对象
- 从 Lightwave 中导入对象
- 从 Blender 中导入对象
- 为优化性能建模角色
- 如何使用法线贴图 (NormalMaps)?
- 如何修正已导入模型的旋转?
- 程序材质
- 如何使用水?
- 分析器(仅限专业版)
- 绘制调用批处理
- 遮挡剔除(仅限专业版)
- Unity 中的高动态范围 (High Dynamic Range) 渲染
- 在 Unity 4 中使用 DirectX 11
- 文本场景文件格式(仅限专业版)
- 使用网络播放器模版
- 平台依赖编译
- 日志文件
- 首选项
- 粒子系统曲线编辑器
- 渐变编辑器
- 怎样制作网格粒子发射器?(旧粒子系统)
- 深入了解光照贴图
- 光照贴图快速入门
- 着色器
- 动画脚本(旧版)
- 自定义
- 布局模式
- 扩展编辑器
- 网络实例化
- 材质和着色器
- 如何使用细节纹理?
- 着色器:顶点和片段程序
- Unity 中的阴影
编写表面着色器
编写与光照交互的着色器是十分复杂的事情。有不同的光照类型、不同的阴影选项和不同的渲染路径(正向和延时渲染),着色器应以某种方法处理此种程度的复杂性。
Unity 的表面着色器 (Surface Shader) 是一种代码生成方法,用它来编写光照着色器比用低级的顶点/像素着色器程序容易得多。请注意,表面着色器 (Surface Shader) 中不包含自定义语言、魔法或忍者;它只会生成本应手写的所有重复代码。您仍要用 Cg/HLSL 语言来编写着色器代码。
相关的一些示例,请参阅表面着色器示例 和 表面着色器自定义光照示例。
工作原理
定义一个“表面函数”,此函数将您需要的任意 UV 或数据作为输入信息并填入输出结构 SurfaceOutput
。SurfaceOutput 大体上描述了表面的属性(它的反射率颜色、法线、发射量、高光等)。您要用 Cg/HLSL 语言来编写此代码。
然后,表面着色器 (Surface Shader) 编译器会计算出需要什么输入信息以及填入了什么输出信息等,并生成实际的顶点和像素着色器以及渲染通道 (rendering pass) 来处理正向和延时渲染。
标准的表面着色器输出结构如下:
struct SurfaceOutput { half3 Albedo; half3 Normal; half3 Emission; half Specular; half Gloss; half Alpha; };
样例
请参阅表面着色器示例、表面着色器自定义光照示例和表面着色器密铺页面。
表面着色器编译指令
表面着色器与其他任何着色器一样放置于 CGPROGRAM..ENDCG
块中。区别是:
#pragma surface
指令是:
#pragma surface surfaceFunction lightModel [optionalparams]
所需参数:
- surfaceFunction - 表明哪个 Cg 函数有表面着色器代码。该函数格式应为
void surf (Input IN, inout SurfaceOutput o)
,其中“Input”是您定义的结构。Input 结构应包含表面函数所需的任何纹理坐标和额外自动变量。 - lightModel - 要使用的光照模型。内置的光照模型是
Lambert
(漫反射)和BlinnPhong
(高光)。有关如何编写自己的光照模型,请参阅自定义光照模型页面。
Optional parameters:
alpha
- Alpha 混合模式。将该参数用于半透明着色器。alphatest:VariableName
- Alpha 测试模式。将该参数用于透明镂空着色器。镂空值在有变量名 (VariableName) 的浮点型变量中。vertex:VertexFunction
- 自定义顶点修改函数。具体示例可见树皮着色器 (Tree Bark Shader)。finalcolor:ColorFunction
- 自定义最终颜色修改函数。请参阅表面着色器示例。exclude_path:prepass
或exclude_path:forward
- 请勿为给定的渲染路径生成通道。addshadow
- 添加阴影投射器 (shadow caster) 和集合通道 (collector pass)。通常与自定义顶点修改函数一起使用,使得阴影投射也可获得所有程序性顶点动画效果。dualforward
- 将双光照贴图用于正向渲染路径中。fullforwardshadows
- 支持正向渲染路径中的所有阴影类型。decal:add
- 附加的印花着色器(例如,地形 AddPass)。decal:blend
- 半透明印花着色器。softvegetation
- 使表面着色器仅在“软植被”(Soft Vegetation) 开启时被渲染。noambient
- 请勿应用任何环境光照或球面调和光照 (spherical harmonics light)。novertexlights
- 请勿在正向渲染 (Forward Rendering) 中应用任何球面调和光照 (spherical harmonic light) 或逐顶点光照 (per-vertex light)。nolightmap
- 在该着色器中禁用光照贴图支持(使着色器变小)。nodirlightmap
- 在该着色器中禁用方向性光照贴图支持(使着色器变小)。noforwardadd
- 禁用正向渲染附加通道。这会使着色器支持一个全方向灯,而其他所有光照则逐顶点/SH 被计算。也会使着色器变小。approxview
- 对于有需要的着色器,逐顶点而不是逐像素计算规范化视线方向。这种方法更快速,但当相机靠近表面时,视线方向不会完全正确。halfasview
- 将半方向向量(而非视线方向向量)传递到光照函数中。半方向向量将会被逐顶点计算和规范化。这种方法更快速,但不会完全正确。tessellate:TessFunction
- 使用 DX11 GPU 密铺 (tessellation);函数计算密铺 (tessellation) 系数。有关详细信息,请参阅表面着色器密铺。
此外,您还可以在 CGPROGRAM 块中编写 #pragma debug
,然后表面编译器 (surface compiler) 将产生大量生成代码的注释。您可以在着色器检视器中使用开放的编译着色器 (Open Compiled Shader) 进行查看。
表面着色器输入结构
输入结构 Input
通常具有着色器所需的所有纹理坐标。纹理坐标必须被命名为纹理名称前加“uv
”(或以“uv2
”开头以使用第二纹理坐标集)。
其他能放入 Input 结构中的值:
float3 viewDir
- 将包含视线方向,用于计算视差 (Parallax) 效果、边缘光照等。- 带
颜色 (COLOR)
语义的float4
- 将包含插值逐顶点颜色。 float4 screenPos
- 将包含反射效果的屏幕空间位置。例如,在 Dark Unity 中由 WetStreet 着色器 (WetStreet Shader) 使用。float3 worldPos
- 将包含世界坐标空间位置。float3 worldRefl
- 将包含世界坐标反射向量,条件是表面着色器不写入 o.Normal。具体示例可见反射 - 漫反射着色器 (Reflect-Diffuse Shader)。float3 worldNormal
- 将包含世界坐标法线向量,条件是表面着色器不写入 o.Normal。float3 worldRefl; INTERNAL_DATA
- 将包含世界坐标反射向量,条件是表面着色器写入 o.Normal。要基于逐像素法线贴图获得反射向量,请使用WorldReflectionVector (IN, o.Normal)
。具体示例可见反射 - 凹凸着色器 (Reflect-Bumped Shader)。float3 worldNormal; INTERNAL_DATA
- 将包含世界坐标法线向量,条件是表面着色器写入 o.Normal。要基于逐像素法线贴图获得法线向量,请使用WorldNormalVector (IN, o.Normal)
。
表面着色器和 DirectX 11
目前表面着色器编译管线 (compilation pipeline) 的一些部分不理解 DirectX 11 HLSL 语法,因此如果是诸如 StructuredBuffers、 RWTextures 和其他非 DX9 语法等的 HLSL 功能,则您必须将它纳入仅特定于 DX11 的预处理器宏:有关详细信息,请参阅特定于平台的差异页面。
更多文档
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论