Unity-TA面试复习大纲

这次岗位是客户端 TA 方向,重点不是单纯背 Shader 语法,而是看你能不能把 Unity URP/HDRP 管线、Shader 效果、性能分析、工具插件、美术工作流 串成一个能落地的技术支持体系。

明天面试前的目标很明确:

  1. 能讲清楚 URP / SRP 的执行结构,以及自定义 Pass / Feature 怎么接入。
  2. 能用自己的项目经历讲 Shader、后处理、GPU Driven、延迟渲染 Feature。
  3. 能从 GPU 瓶颈角度解释优化,而不是只说“少采样、少分支、少 DrawCall”。
  4. 能给美术和程序之间的问题提供定位路径、工具方案和规范建议。
  5. Houdini 程序化如果不是强项,要准备诚实但不空的回答。

岗位要求拆解

截图里的岗位可以拆成五类能力。

1. Unity URP / HDRP Shader 编写

需要准备的关键词:

URP、HDRP、ShaderLab、HLSL、SRP Batcher、RenderFeature、ScriptableRenderPass、RenderGraph、Forward、Deferred、GBuffer、Depth、Normal、MotionVector、ShadowCaster。

你要能回答:

  1. URP 的渲染入口是什么?
  2. 一个自定义后处理或渲染效果如何接进 URP?
  3. Forward 和 Deferred 的差别是什么?
  4. URP 做一个自定义 Feature 时,资源怎么申请、Pass 在哪里执行、如何避免多余 CopyColor / CopyDepth?
  5. Shader 变体为什么会爆炸,怎么剔除?

关联笔记:

Unity-URP架构
Unity-SRP前向渲染管线
Unity-URP延迟渲染Feature
Base-面试问题汇总

2. CG / GLSL / HLSL 基础

面试里不会只问语法,更可能通过问题看你是否理解 Shader 数据流。

必须过一遍:

  1. 顶点阶段到片元阶段的数据传递:Attributes、Varyings、插值器、语义。
  2. 坐标空间:Object、World、View、Clip、NDC、Screen、Tangent。
  3. 法线贴图:TBN、切线空间、法线编码、DX / OpenGL 绿通道差异。
  4. 纹理采样:sRGB / Linear、Mip、LOD、Sampler、Wrap / Filter。
  5. 精度:float / half 的真实收益与风险。
  6. 分支:静态分支、Uniform 动态分支、线程发散。

一句话版本:

Shader 优化不能只看源码里有没有 if 或 half,要看最终编译到目标 GPU 后的寄存器、Occupancy、纹理等待、带宽和线程发散。

关联笔记:

Base-各个坐标空间
Base-法线贴图
Base-Shader分支与线程发散
Base-GPU硬件架构基础

3. 引擎与渲染效果开发

岗位提到“编写插件,提升生产效率”,所以最好把你的经验说成工具链,而不是单个效果。

可以主讲三个案例。

案例 A:URP 延迟渲染 Feature

可讲内容:

  1. 自定义 GBuffer Shader。
  2. HBAO、SSAO、SSGI、SSR、TAA、Contact Shadow 等屏幕空间效果。
  3. Hi-Z Build 的用途:遮挡查询、SSR Ray March 加速、屏幕空间效果快速深度判断。
  4. MotionVector 对 TAA 的作用。
  5. RenderFeature 接入点、RT 生命周期、Debug 视图和性能验证。

可能追问:

  1. SSR 为什么会丢失屏幕外信息?
  2. TAA 为什么会有拖影,怎么处理 History?
  3. HBAO / SSAO 为什么依赖深度和法线?
  4. 延迟渲染为什么不适合所有透明物体?

关联笔记:

Unity-URP延迟渲染Feature
Shader-RayMarch
Shader-屏幕空间
Base-透明渲染

案例 B:GPU Driven 草地渲染

可讲内容:

  1. 离线或加载时根据地形 Mesh 和草地 Mask 生成 GrassInfo。
  2. 上传 StructuredBuffer。
  3. Compute Shader 做视锥剔除。
  4. 输出可见实例列表和 Indirect Args。
  5. DrawMeshInstancedIndirect 绘制。
  6. Pre-Z 降低草地 Overdraw。

回答重点:

这个方案主要解决 CPU 逐对象提交和大量实例剔除的问题。如果瓶颈在透明 Overdraw、阴影或片元采样,DrawIndirect 本身不会自动解决。

可能追问:

  1. Indirect Draw 为什么叫间接?
  2. Compute 写 Buffer 后 Draw 读取需要注意什么?
  3. 草地阴影、LOD、风动、Lightmap / ShadowMask 怎么处理?
  4. Bounds 过大或过小有什么问题?

关联笔记:

Unity-GPUDriven草地渲染
Base-面试问题汇总
Unity-渲染性能优化

案例 C:自定义 SRP / RenderGraph 前向管线

可讲内容:

  1. 基于 RenderGraph 组织基础 Pass。
  2. PCSS 软阴影。
  3. Tiled Based Forward 光照。
  4. 资源声明、Pass Culling、临时 RT 复用。

回答重点:

RenderGraph 不是自动变快的开关,它的价值是显式声明 Pass 依赖和资源生命周期,让引擎有机会做 Pass 裁剪、资源复用和 Native Render Pass 合并。

关联笔记:

Unity-SRP前向渲染管线
Base-面试问题汇总
Base-TBDR架构

高频技术主题

URP 架构

复习顺序:

  1. UniversalRenderPipelineAsset:序列化管线设置。
  2. UniversalRenderPipeline:Render 入口,遍历 Camera。
  3. CameraData、LightData、ShadowData、RenderingData:渲染上下文数据。
  4. ScriptableRenderer:组织 Pass 队列。
  5. ScriptableRenderPass:实际执行渲染逻辑。
  6. ScriptableRenderFeature:序列化配置,并向 Renderer 添加 Pass。
  7. UniversalRenderer:Unity 提供的 Forward / Deferred Renderer 实现。

面试回答模板:

URP 的核心是 Pipeline 负责驱动每个 Camera,Renderer 负责组织一帧里要跑哪些 Pass,RenderFeature 用来把自定义功能挂进 Renderer,RenderPass 则真正记录 CommandBuffer 或执行绘制。

Forward / Deferred

Forward:

  1. 每个物体渲染时直接算光照。
  2. 材质和透明支持自然。
  3. 多光源可能导致重复计算或多 Pass。
  4. MSAA 支持相对直接。

Deferred:

  1. 先写 GBuffer,再统一做 Lighting。
  2. 多光源更容易控制。
  3. GBuffer 占显存和带宽。
  4. 透明物体通常仍需 Forward。
  5. 移动端要特别注意 MRT、带宽和 Tile Store / Load。

可以补一句:

URP 里的 Deferred 不是替代 Forward,而是根据场景光源数量、材质需求、平台带宽和透明比例做取舍。

ShadowMap / CSM / PCF / PCSS

必须会讲:

  1. ShadowMap 是从光源视角渲染深度,再在主相机渲染时比较当前点到光源的深度。
  2. Bias 用来处理 Shadow Acne,但过大导致 Peter Panning。
  3. Normal Bias 沿法线偏移,Depth Bias 改变深度比较。
  4. CSM 把相机视锥按距离分段,提高近处阴影精度。
  5. PCF 通过多次比较平均软化边缘。
  6. PCSS 先估算遮挡物距离,再根据接收面距离扩大 Filter 半径,得到接触硬、远处软的阴影。

可结合你的 SRP 前向管线讲 PCSS 经验。

关联笔记:

Base-阴影ShadowMap
Unity-SRP前向渲染管线

PBR

面试最容易问基础公式。

必须背熟:

1
2
3
BRDF = Diffuse + Specular
Diffuse = BaseColor / π
Specular = D × F × G / (4 × NdotL × NdotV)

核心解释:

  1. PBR 的重点是能量守恒、菲涅尔、微表面。
  2. Diffuse 除以 π 是 Lambert 半球积分归一化。
  3. Specular 不额外整体除以 π,因为 D、G 和分母已经包含微表面分布和投影变换,GGX 的 D 项里本身也有 π。
  4. 非金属 F0 常用 0.04,金属 F0 有颜色。
  5. Metallic 为 1 时,Diffuse 接近 0。

关联笔记:

Base-PBR
Base-法线贴图

TAA

回答结构:

  1. 当前帧加 Jitter,跨帧积累不同采样位置。
  2. 使用 MotionVector 把当前像素重投影到上一帧。
  3. 采样 History Color。
  4. 用当前帧邻域颜色做 Clamp / Clip,避免历史颜色不可信。
  5. 根据运动、遮挡显露、亮度变化决定混合权重。

追问准备:

  1. Ghosting 来源:遮挡显露、透明、粒子、反射、MotionVector 缺失。
  2. 颜色空间转换:YCoCg 或亮度压缩让 History Clamp 更稳定。
  3. 边缘 MotionVector:常取邻域更近深度对应的 MotionVector,避免背景历史拖到前景。

关联笔记:

Base-面试问题汇总
Unity-URP延迟渲染Feature

TBDR 与移动端性能

必须能讲:

  1. TBR / TBDR 把屏幕分成 Tile,尽量在片上内存完成 Color / Depth / Stencil。
  2. Binning 阶段收集每个 Tile 覆盖的图元。
  3. Tile Rendering 阶段在片上内存做光栅化、深度测试、着色。
  4. HSR 试图在片元着色前剔除不可见表面。
  5. Tile Flush / Store / Load 是移动端性能杀手之一。
  6. Pre-Z 在移动端不一定赚,因为可能增加 Binning 和 Tile 读写。
  7. Framebuffer Fetch / Subpass Input 适合当前像素读写,不适合邻域采样类算法。

关联笔记:

Base-TBDR架构
Base-面试问题汇总

性能优化复习

分析流程

面试不要直接说“我会优化 Shader”。先说流程:

  1. 先确定瓶颈:CPU、GPU、内存、带宽、加载、脚本还是渲染线程。
  2. 用 Profiler / Frame Debugger / RenderDoc / Xcode / Snapdragon Profiler 抓证据。
  3. 做控制变量:关闭 Feature、替换材质、降采样、减少灯光、关闭阴影。
  4. 定位到 Pass、DrawCall、Shader、RT、纹理采样或带宽。
  5. 提方案并比较画质、性能和维护成本。
  6. 建立规范或工具,防止问题重复出现。

Shader 优化

按收益排序准备:

  1. 减少无效绘制:剔除、LOD、距离裁剪、Pre-Z、遮挡剔除。
  2. 减少 Overdraw:透明层数、AlphaTest、排序、粒子范围。
  3. 减少采样:贴图合并、Mip、LUT、降分辨率、缓存中间结果。
  4. 控制变体:shader_feature、multi_compile、SVC、OnProcessShader 剔除。
  5. 控制分支:重路径用变体,统一开关用 Uniform Branch,避免高频数据导致发散。
  6. 控制寄存器和插值器:少传无用 Varying,复杂中间量不要滥塞。
  7. 精度优化:half 用于范围受控的数据,float 保留给世界坐标、深度重建、矩阵、长累加和阴影。

GPU 硬件视角

需要会说这些词的关系:

  1. ALU:执行数学运算的电路。
  2. SIMD / SIMT:一条指令驱动多个 Lane / 多个 Shader 线程。
  3. Warp / Wave:GPU 调度的一组线程。
  4. SM / CU / Shader Core:包含 ALU、寄存器、调度器、缓存等。
  5. Register:线程局部变量,过多会降低 Occupancy。
  6. L1 / L2 / Texture Cache:缓存不同访问模式的数据。
  7. Memory / Texture Bound:采样和带宽才是瓶颈时,少几条 ALU 没意义。

一句话:

优化要先判断 Shader 是 ALU Bound、Texture Bound、Bandwidth Bound、Latency Bound 还是 Occupancy 受限,否则容易改了很多代码但没有性能收益。

美术工作流与工具支持

岗位强调“解决美术开发需求和问题”,这里要准备 TA 的沟通方式。

可讲的支持内容

  1. 材质规范:BaseColor 不带光照,法线贴图 Non-Color,Metallic / Roughness 通道打包规则。
  2. 贴图规范:尺寸、压缩格式、Mip、移动端 ASTC / ETC、Mask 合并。
  3. Shader 规范:关键字数量、变体限制、功能开关、性能等级。
  4. 场景规范:LOD、阴影距离、透明层数、特效 Overdraw。
  5. Debug 工具:显示 GBuffer、法线、深度、Overdraw、Cascade、Mip、变体数量。
  6. 自动检查:导入器脚本、资源扫描、ShaderVariant 收集、构建前检查。

可以举的工具插件方向

  1. 材质检查器:检查贴图 sRGB、压缩格式、通道占用、关键字。
  2. Shader 变体统计工具:统计每个 Shader 的变体数和关键字组合。
  3. 场景性能扫描:找超大贴图、透明材质、过远阴影投射物、未设置 LOD 的对象。
  4. 美术 Debug 面板:一键切换法线、粗糙度、AO、深度、光照通道。
  5. 草地 / 植被生成与剔除工具:结合你 GPU Driven 草地项目讲。

回答重点:

TA 的价值不是只写一个效果,而是把效果、规范、检查工具和问题定位流程一起交给团队。

Houdini 程序化准备

你当前笔记里没有明显 Houdini 系列,所以明天建议走“了解流程 + 能协作接入 Unity”的答法,不要硬装资深 Houdini。

准备三句话:

  1. Houdini 程序化的核心是把可重复的美术生产逻辑节点化、参数化,例如地形、道路、建筑、植被散布、破碎和烘焙。
  2. 对 Unity 项目来说,重点是 Houdini Engine / HDA 的参数暴露、生成结果的 Mesh / 材质 / UV / 碰撞 / LOD / Lightmap 数据是否符合运行时规范。
  3. 我更熟的是 Unity 渲染和性能落地,可以和 TA / 美术一起把 Houdini 产出的资源接入材质、Shader、LOD、烘焙和性能检查流程。

可能追问:

  1. HDA 是什么?
  2. 程序化资产进入 Unity 后要检查什么?
  3. 程序化生成的植被如何和渲染管线结合?

回答方向:

我会关注生成资产的数据质量:拓扑、UV、法线 / 切线、顶点色、实例属性、材质槽、LOD、碰撞、包围盒、Lightmap UV、贴图通道和运行时剔除。

明天前复习顺序

第一轮:1 小时,保底必会

  1. Unity-URP架构
  2. Base-面试问题汇总
  3. Base-GPU硬件架构基础
  4. Base-Shader分支与线程发散

目标:

能把 URP、RenderFeature、RenderGraph、DrawIndirect、TAA、PBR、TBDR、half、分支发散这些问题讲成完整回答。

第二轮:1 小时,项目案例

  1. Unity-URP延迟渲染Feature
  2. Unity-GPUDriven草地渲染
  3. Unity-SRP前向渲染管线
  4. Unity-渲染性能优化

目标:

准备 2 到 3 个“我做过 / 我研究过 / 我能落地”的案例,每个案例都包含背景、方案、难点、性能、工具和结果。

第三轮:40 分钟,基础图形学

  1. Base-PBR
  2. Base-法线贴图
  3. Base-阴影ShadowMap
  4. Base-透明渲染
  5. Base-各个坐标空间

目标:

避免基础题翻车。PBR、法线、阴影、透明排序、坐标变换都是 TA 面试高频。

第四轮:20 分钟,软能力和岗位匹配

准备这些问题:

  1. 遇到美术说“效果不对”,你怎么排查?
  2. 遇到移动端发热 / 掉帧,你怎么定位?
  3. 如何制定 Shader 和材质规范?
  4. 如何推动美术使用工具,而不是只靠口头约定?
  5. 你如何和程序沟通管线改造的风险?

自我介绍技术版

可以按这个结构说:

我主要偏 Unity 渲染和客户端 TA 方向,平时关注 URP / SRP 管线、Shader 效果、屏幕空间算法和性能优化。做过 URP 延迟渲染 Feature,包括 GBuffer、HBAO、SSR、TAA、Contact Shadow 这类效果;也做过 GPU Driven 草地,用 Compute 做剔除,再用 DrawIndirect 绘制。底层方面我整理过 GPU 架构、TBDR、Shader 分支发散、half 精度和 RenderGraph 这些内容。我的优势是能把效果实现、性能分析和美术工作流规范结合起来,既能写 Shader,也能做工具和定位问题。

项目案例模板

每个项目都按这个顺序讲。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
背景:
项目里遇到什么需求或问题。

方案:
我选择了什么渲染路径、Shader 结构、Pass 组织或工具流程。

关键实现:
数据从哪里来,经过哪些 Buffer / RT / Pass,最后怎么输出。

难点:
兼容性、性能、画质、资源生命周期、调试成本。

优化:
如何定位瓶颈,做了哪些取舍。

结果:
画质、性能、生产效率或维护成本有什么改善。

可能被问的问题清单

管线类

  1. URP 的 ScriptableRenderer 和 ScriptableRenderPass 分别负责什么?
  2. RenderFeature 如何插入自定义 Pass?
  3. RenderGraph 和传统 CommandBuffer 写法有什么区别?
  4. Forward 和 Deferred 怎么选?
  5. 透明物体为什么一般不能直接走延迟光照?
  6. CopyColor / CopyDepth 为什么可能影响性能?

Shader 类

  1. HLSL 中 half 一定比 float 快吗?
  2. Shader 分支一定慢吗?
  3. discard 会影响什么优化?
  4. 法线贴图为什么不能用 sRGB?
  5. TBN 里的 tangent.w 有什么用?
  6. 非均匀缩放下法线为什么用逆转置矩阵?

PBR 类

  1. Diffuse 为什么除以 π?
  2. GGX 的 D、F、G 分别是什么?
  3. Metallic 工作流里 BaseColor 表示什么?
  4. Roughness 和 Smoothness 有什么关系?
  5. AO 应该影响直接光还是间接光?

性能类

  1. 怎么判断一个 Shader 是 ALU 瓶颈还是带宽瓶颈?
  2. Overdraw 怎么看,怎么优化?
  3. Pre-Z 什么时候有收益,什么时候亏?
  4. 移动端 TBDR 为什么怕 Tile Flush?
  5. Shader Variant 爆炸怎么处理?
  6. DrawCall、Batch、Instancing、SRP Batcher 的差异是什么?

项目类

  1. GPU Driven 草地的完整流程?
  2. DrawIndirect 的 Args Buffer 里有什么?
  3. TAA 的 Ghosting 怎么处理?
  4. SSR 的局限是什么?
  5. HBAO / SSAO 的输入是什么?
  6. PCSS 和 PCF 的区别?

TA 协作类

  1. 美术提交的材质太贵,你怎么处理?
  2. 如何制定 Shader 规范?
  3. 如何让美术知道某个效果为什么贵?
  4. 如何做资源导入检查?
  5. 项目中你怎么平衡画质和性能?

临场回答原则

  1. 不确定版本细节时,说“具体实现和 Unity 版本有关”,再讲通用原理。
  2. 不要只说结论,要说定位路径。
  3. 遇到性能问题,先问瓶颈类型,再给优化方案。
  4. 遇到美术问题,先复现和可视化,再谈规范和工具。
  5. 不会 Houdini 深水区就承认边界,但把 Unity 接入和资源规范讲清楚。
  6. 多把答案落回你的案例:URP Feature、GPU Driven 草、SRP 前向管线、性能优化。

最后一遍速记

URP:Pipeline 驱动 Camera,Renderer 管 Pass,Feature 加 Pass,Pass 做渲染。

RenderGraph:显式声明资源依赖,换来 Pass 裁剪、RT 复用、同步和 Native Pass 合并机会。

DrawIndirect:GPU Buffer 提供绘制参数,适合 GPU Culling 后直接绘制可见实例。

PBR:能量守恒 + 微表面 + Fresnel;Diffuse 除 π,Specular 的归一化在 DFG 和分母里。

TAA:Jitter + MotionVector Reprojection + History Clamp + 动态权重。

TBDR:Tile 内片上渲染省带宽,怕 Tile Flush,多 Pass 和中间 RT 要谨慎。

Shader 分支:关键不是有没有 if,而是同一 Wave 内路径是否一致、是否真的跳过重工作。

half:看平台 FP16 支持、寄存器压力和数值范围,不是写了就一定快。

TA:效果实现只是第一步,真正价值是规范、工具、定位流程和跨团队落地。

总结

这次面试最适合你的打法是:用 Unity 渲染管线和 Shader 基础打底,用 URP 延迟 Feature、GPU Driven 草地、自定义 SRP / RenderGraph 三个案例证明你能落地,再用 GPU 架构和性能分析说明你不是只会写效果。

Houdini 可以作为协作项处理,重点强调你能把程序化资产接入 Unity 的材质、Shader、LOD、剔除、烘焙和性能规范。只要别把不会的部分说满,反而会显得稳。