Skip to main content

着色器

概念

Shader(着色器)是运行在GPU上的小程序,控制物体渲染时的光照、颜色、纹理等视觉效果。它决定了材质如何与光线交互,生成最终像素颜色。

核心功能

  • 顶点变换(如模型空间→屏幕空间)。
  • 光照计算(漫反射、高光、环境光)。
  • 纹理映射与混合(如法线贴图、透明度处理)。

Shader与材质的关系

  • Shader:是“食谱”,定义渲染规则(如光照模型、混合模式)。
  • 材质:是“菜肴”,绑定Shader并设置具体参数(如颜色、纹理)。
  • 关系链:Shader → 材质 → 网格渲染器(Mesh Renderer)。

面试题

1. Unity中Shader的常见类型及区别?

答案

  • Surface Shader:封装了光照模型(如PBR),适合物理渲染(如金属、塑料)。
  • Unlit Shader:忽略光照,用于UI、特效(如发光粒子)。
  • Vertex/Fragment Shader:完全自定义渲染流程,适合高级效果(如扭曲、溶解)。
  • Shader Graph:节点化编辑,无需代码(如卡通渲染)。

2. 编写一个简单的Unlit Shader

(输出固定颜色,不受光照影响)

Shader "Custom/UnlitColor" {
Properties { _Color ("Color", Color) = (1,1,1,1) }
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
struct appdata { float4 vertex : POSITION; };
struct v2f { float4 pos : SV_POSITION; };
fixed4 _Color;
v2f vert(appdata v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag(v2f i) : SV_Target { return _Color; }
ENDCG
}
}
}

3. 顶点着色器与片元着色器的分工?

  • 顶点着色器:处理几何数据(如顶点位置、法线、UV)。
  • 片元着色器:计算像素颜色(如纹理采样、光照混合)。
  • 示例:顶点着色器可扭曲网格,片元着色器实现渐变透明。

4. 如何优化Shader性能?

方法

  • 减少分支:避免if-else,使用step()或插值替代。
  • 简化计算:用half代替float,预计算常量。
  • 合批优化:相同Shader Variant的材质可合批减少DrawCall。

5. PBR材质的关键属性有哪些?

答案

  • Albedo:基础颜色(反照率)。
  • Metallic:金属度(0-1)。
  • Smoothness:光滑度(影响高光范围)。
  • Normal Map:表面凹凸模拟。

6. ShaderLab中Properties的作用?

答案

  • 定义材质Inspector中可调参数(如颜色、纹理)。
  • 示例:_MainTex ("Texture", 2D) = "white" {}声明一张默认白色纹理。

7. 如何实现溶解效果?

  • Shader方案

  • 使用噪声图控制透明度阈值:

clip(noise.r - _Threshold); // 裁剪低于阈值的像素
  • 动态调整_Threshold实现溶解动画。

8. Unity内置渲染管线与SRP的区别?

  • 内置管线:固定流程,支持Surface Shader。
  • SRP(如URP/HDRP):可编程管线,支持Shader Graph,优化移动端(URP)或高端图形(HDRP)。

9. 什么是Shader Variant?如何管理?

答案

  • 同一Shader的不同编译版本(如不同光照、关键字组合)。
  • 管理:通过#pragma multi_compile定义变体,避免冗余变体增加包体。

10. 动态修改材质颜色的最佳实践?

方案

  • MaterialPropertyBlock:修改属性不创建新材质实例:

(避免内存碎片)

MaterialPropertyBlock props = new MaterialPropertyBlock();
props.SetColor("_Color", Color.red);
GetComponent<Renderer>().SetPropertyBlock(props);

11. 法线贴图与视差贴图的原理差异?

  • 法线贴图:通过RGB编码法线方向,模拟凹凸(不改变几何)。
  • 视差贴图:根据高度偏移UV,产生深度错觉(性能开销更高)。

12. 几何着色器(Geometry Shader)的应用场景?

  • 答案:动态生成几何体(如毛发、草地),但移动端支持有限。

13. Shader中如何实现卡通渲染(Cel Shading)?

  • 关键步骤

  • 离散化光照(floor(dot(N,L) * 3) / 3)。

  • 边缘检测(法线与视角夹角描边)。