Unity-TA面试复习大纲
这次岗位是客户端 TA 方向,重点不是单纯背 Shader 语法,而是看你能不能把 Unity URP/HDRP 管线、Shader 效果、性能分析、工具插件、美术工作流 串成一个能落地的技术支持体系。
明天面试前的目标很明确:
- 能讲清楚 URP / SRP 的执行结构,以及自定义 Pass / Feature 怎么接入。
- 能用自己的项目经历讲 Shader、后处理、GPU Driven、延迟渲染 Feature。
- 能从 GPU 瓶颈角度解释优化,而不是只说“少采样、少分支、少 DrawCall”。
- 能给美术和程序之间的问题提供定位路径、工具方案和规范建议。
- Houdini 程序化如果不是强项,要准备诚实但不空的回答。
岗位要求拆解
截图里的岗位可以拆成五类能力。
1. Unity URP / HDRP Shader 编写
需要准备的关键词:
URP、HDRP、ShaderLab、HLSL、SRP Batcher、RenderFeature、ScriptableRenderPass、RenderGraph、Forward、Deferred、GBuffer、Depth、Normal、MotionVector、ShadowCaster。
你要能回答:
- URP 的渲染入口是什么?
- 一个自定义后处理或渲染效果如何接进 URP?
- Forward 和 Deferred 的差别是什么?
- URP 做一个自定义 Feature 时,资源怎么申请、Pass 在哪里执行、如何避免多余 CopyColor / CopyDepth?
- Shader 变体为什么会爆炸,怎么剔除?
关联笔记:
Unity-URP架构
Unity-SRP前向渲染管线
Unity-URP延迟渲染Feature
Base-面试问题汇总
2. CG / GLSL / HLSL 基础
面试里不会只问语法,更可能通过问题看你是否理解 Shader 数据流。
必须过一遍:
- 顶点阶段到片元阶段的数据传递:Attributes、Varyings、插值器、语义。
- 坐标空间:Object、World、View、Clip、NDC、Screen、Tangent。
- 法线贴图:TBN、切线空间、法线编码、DX / OpenGL 绿通道差异。
- 纹理采样:sRGB / Linear、Mip、LOD、Sampler、Wrap / Filter。
- 精度:float / half 的真实收益与风险。
- 分支:静态分支、Uniform 动态分支、线程发散。
一句话版本:
Shader 优化不能只看源码里有没有 if 或 half,要看最终编译到目标 GPU 后的寄存器、Occupancy、纹理等待、带宽和线程发散。
关联笔记:
Base-各个坐标空间
Base-法线贴图
Base-Shader分支与线程发散
Base-GPU硬件架构基础
3. 引擎与渲染效果开发
岗位提到“编写插件,提升生产效率”,所以最好把你的经验说成工具链,而不是单个效果。
可以主讲三个案例。
案例 A:URP 延迟渲染 Feature
可讲内容:
- 自定义 GBuffer Shader。
- HBAO、SSAO、SSGI、SSR、TAA、Contact Shadow 等屏幕空间效果。
- Hi-Z Build 的用途:遮挡查询、SSR Ray March 加速、屏幕空间效果快速深度判断。
- MotionVector 对 TAA 的作用。
- RenderFeature 接入点、RT 生命周期、Debug 视图和性能验证。
可能追问:
- SSR 为什么会丢失屏幕外信息?
- TAA 为什么会有拖影,怎么处理 History?
- HBAO / SSAO 为什么依赖深度和法线?
- 延迟渲染为什么不适合所有透明物体?
关联笔记:
Unity-URP延迟渲染Feature
Shader-RayMarch
Shader-屏幕空间
Base-透明渲染
案例 B:GPU Driven 草地渲染
可讲内容:
- 离线或加载时根据地形 Mesh 和草地 Mask 生成 GrassInfo。
- 上传 StructuredBuffer。
- Compute Shader 做视锥剔除。
- 输出可见实例列表和 Indirect Args。
- DrawMeshInstancedIndirect 绘制。
- Pre-Z 降低草地 Overdraw。
回答重点:
这个方案主要解决 CPU 逐对象提交和大量实例剔除的问题。如果瓶颈在透明 Overdraw、阴影或片元采样,DrawIndirect 本身不会自动解决。
可能追问:
- Indirect Draw 为什么叫间接?
- Compute 写 Buffer 后 Draw 读取需要注意什么?
- 草地阴影、LOD、风动、Lightmap / ShadowMask 怎么处理?
- Bounds 过大或过小有什么问题?
关联笔记:
Unity-GPUDriven草地渲染
Base-面试问题汇总
Unity-渲染性能优化
案例 C:自定义 SRP / RenderGraph 前向管线
可讲内容:
- 基于 RenderGraph 组织基础 Pass。
- PCSS 软阴影。
- Tiled Based Forward 光照。
- 资源声明、Pass Culling、临时 RT 复用。
回答重点:
RenderGraph 不是自动变快的开关,它的价值是显式声明 Pass 依赖和资源生命周期,让引擎有机会做 Pass 裁剪、资源复用和 Native Render Pass 合并。
关联笔记:
Unity-SRP前向渲染管线
Base-面试问题汇总
Base-TBDR架构
高频技术主题
URP 架构
复习顺序:
- UniversalRenderPipelineAsset:序列化管线设置。
- UniversalRenderPipeline:Render 入口,遍历 Camera。
- CameraData、LightData、ShadowData、RenderingData:渲染上下文数据。
- ScriptableRenderer:组织 Pass 队列。
- ScriptableRenderPass:实际执行渲染逻辑。
- ScriptableRenderFeature:序列化配置,并向 Renderer 添加 Pass。
- UniversalRenderer:Unity 提供的 Forward / Deferred Renderer 实现。
面试回答模板:
URP 的核心是 Pipeline 负责驱动每个 Camera,Renderer 负责组织一帧里要跑哪些 Pass,RenderFeature 用来把自定义功能挂进 Renderer,RenderPass 则真正记录 CommandBuffer 或执行绘制。
Forward / Deferred
Forward:
- 每个物体渲染时直接算光照。
- 材质和透明支持自然。
- 多光源可能导致重复计算或多 Pass。
- MSAA 支持相对直接。
Deferred:
- 先写 GBuffer,再统一做 Lighting。
- 多光源更容易控制。
- GBuffer 占显存和带宽。
- 透明物体通常仍需 Forward。
- 移动端要特别注意 MRT、带宽和 Tile Store / Load。
可以补一句:
URP 里的 Deferred 不是替代 Forward,而是根据场景光源数量、材质需求、平台带宽和透明比例做取舍。
ShadowMap / CSM / PCF / PCSS
必须会讲:
- ShadowMap 是从光源视角渲染深度,再在主相机渲染时比较当前点到光源的深度。
- Bias 用来处理 Shadow Acne,但过大导致 Peter Panning。
- Normal Bias 沿法线偏移,Depth Bias 改变深度比较。
- CSM 把相机视锥按距离分段,提高近处阴影精度。
- PCF 通过多次比较平均软化边缘。
- PCSS 先估算遮挡物距离,再根据接收面距离扩大 Filter 半径,得到接触硬、远处软的阴影。
可结合你的 SRP 前向管线讲 PCSS 经验。
关联笔记:
Base-阴影ShadowMap
Unity-SRP前向渲染管线
PBR
面试最容易问基础公式。
必须背熟:
1 | |
核心解释:
- PBR 的重点是能量守恒、菲涅尔、微表面。
- Diffuse 除以 π 是 Lambert 半球积分归一化。
- Specular 不额外整体除以 π,因为 D、G 和分母已经包含微表面分布和投影变换,GGX 的 D 项里本身也有 π。
- 非金属 F0 常用 0.04,金属 F0 有颜色。
- Metallic 为 1 时,Diffuse 接近 0。
关联笔记:
Base-PBR
Base-法线贴图
TAA
回答结构:
- 当前帧加 Jitter,跨帧积累不同采样位置。
- 使用 MotionVector 把当前像素重投影到上一帧。
- 采样 History Color。
- 用当前帧邻域颜色做 Clamp / Clip,避免历史颜色不可信。
- 根据运动、遮挡显露、亮度变化决定混合权重。
追问准备:
- Ghosting 来源:遮挡显露、透明、粒子、反射、MotionVector 缺失。
- 颜色空间转换:YCoCg 或亮度压缩让 History Clamp 更稳定。
- 边缘 MotionVector:常取邻域更近深度对应的 MotionVector,避免背景历史拖到前景。
关联笔记:
Base-面试问题汇总
Unity-URP延迟渲染Feature
TBDR 与移动端性能
必须能讲:
- TBR / TBDR 把屏幕分成 Tile,尽量在片上内存完成 Color / Depth / Stencil。
- Binning 阶段收集每个 Tile 覆盖的图元。
- Tile Rendering 阶段在片上内存做光栅化、深度测试、着色。
- HSR 试图在片元着色前剔除不可见表面。
- Tile Flush / Store / Load 是移动端性能杀手之一。
- Pre-Z 在移动端不一定赚,因为可能增加 Binning 和 Tile 读写。
- Framebuffer Fetch / Subpass Input 适合当前像素读写,不适合邻域采样类算法。
关联笔记:
Base-TBDR架构
Base-面试问题汇总
性能优化复习
分析流程
面试不要直接说“我会优化 Shader”。先说流程:
- 先确定瓶颈:CPU、GPU、内存、带宽、加载、脚本还是渲染线程。
- 用 Profiler / Frame Debugger / RenderDoc / Xcode / Snapdragon Profiler 抓证据。
- 做控制变量:关闭 Feature、替换材质、降采样、减少灯光、关闭阴影。
- 定位到 Pass、DrawCall、Shader、RT、纹理采样或带宽。
- 提方案并比较画质、性能和维护成本。
- 建立规范或工具,防止问题重复出现。
Shader 优化
按收益排序准备:
- 减少无效绘制:剔除、LOD、距离裁剪、Pre-Z、遮挡剔除。
- 减少 Overdraw:透明层数、AlphaTest、排序、粒子范围。
- 减少采样:贴图合并、Mip、LUT、降分辨率、缓存中间结果。
- 控制变体:shader_feature、multi_compile、SVC、OnProcessShader 剔除。
- 控制分支:重路径用变体,统一开关用 Uniform Branch,避免高频数据导致发散。
- 控制寄存器和插值器:少传无用 Varying,复杂中间量不要滥塞。
- 精度优化:half 用于范围受控的数据,float 保留给世界坐标、深度重建、矩阵、长累加和阴影。
GPU 硬件视角
需要会说这些词的关系:
- ALU:执行数学运算的电路。
- SIMD / SIMT:一条指令驱动多个 Lane / 多个 Shader 线程。
- Warp / Wave:GPU 调度的一组线程。
- SM / CU / Shader Core:包含 ALU、寄存器、调度器、缓存等。
- Register:线程局部变量,过多会降低 Occupancy。
- L1 / L2 / Texture Cache:缓存不同访问模式的数据。
- Memory / Texture Bound:采样和带宽才是瓶颈时,少几条 ALU 没意义。
一句话:
优化要先判断 Shader 是 ALU Bound、Texture Bound、Bandwidth Bound、Latency Bound 还是 Occupancy 受限,否则容易改了很多代码但没有性能收益。
美术工作流与工具支持
岗位强调“解决美术开发需求和问题”,这里要准备 TA 的沟通方式。
可讲的支持内容
- 材质规范:BaseColor 不带光照,法线贴图 Non-Color,Metallic / Roughness 通道打包规则。
- 贴图规范:尺寸、压缩格式、Mip、移动端 ASTC / ETC、Mask 合并。
- Shader 规范:关键字数量、变体限制、功能开关、性能等级。
- 场景规范:LOD、阴影距离、透明层数、特效 Overdraw。
- Debug 工具:显示 GBuffer、法线、深度、Overdraw、Cascade、Mip、变体数量。
- 自动检查:导入器脚本、资源扫描、ShaderVariant 收集、构建前检查。
可以举的工具插件方向
- 材质检查器:检查贴图 sRGB、压缩格式、通道占用、关键字。
- Shader 变体统计工具:统计每个 Shader 的变体数和关键字组合。
- 场景性能扫描:找超大贴图、透明材质、过远阴影投射物、未设置 LOD 的对象。
- 美术 Debug 面板:一键切换法线、粗糙度、AO、深度、光照通道。
- 草地 / 植被生成与剔除工具:结合你 GPU Driven 草地项目讲。
回答重点:
TA 的价值不是只写一个效果,而是把效果、规范、检查工具和问题定位流程一起交给团队。
Houdini 程序化准备
你当前笔记里没有明显 Houdini 系列,所以明天建议走“了解流程 + 能协作接入 Unity”的答法,不要硬装资深 Houdini。
准备三句话:
- Houdini 程序化的核心是把可重复的美术生产逻辑节点化、参数化,例如地形、道路、建筑、植被散布、破碎和烘焙。
- 对 Unity 项目来说,重点是 Houdini Engine / HDA 的参数暴露、生成结果的 Mesh / 材质 / UV / 碰撞 / LOD / Lightmap 数据是否符合运行时规范。
- 我更熟的是 Unity 渲染和性能落地,可以和 TA / 美术一起把 Houdini 产出的资源接入材质、Shader、LOD、烘焙和性能检查流程。
可能追问:
- HDA 是什么?
- 程序化资产进入 Unity 后要检查什么?
- 程序化生成的植被如何和渲染管线结合?
回答方向:
我会关注生成资产的数据质量:拓扑、UV、法线 / 切线、顶点色、实例属性、材质槽、LOD、碰撞、包围盒、Lightmap UV、贴图通道和运行时剔除。
明天前复习顺序
第一轮:1 小时,保底必会
Unity-URP架构Base-面试问题汇总Base-GPU硬件架构基础Base-Shader分支与线程发散
目标:
能把 URP、RenderFeature、RenderGraph、DrawIndirect、TAA、PBR、TBDR、half、分支发散这些问题讲成完整回答。
第二轮:1 小时,项目案例
Unity-URP延迟渲染FeatureUnity-GPUDriven草地渲染Unity-SRP前向渲染管线Unity-渲染性能优化
目标:
准备 2 到 3 个“我做过 / 我研究过 / 我能落地”的案例,每个案例都包含背景、方案、难点、性能、工具和结果。
第三轮:40 分钟,基础图形学
Base-PBRBase-法线贴图Base-阴影ShadowMapBase-透明渲染Base-各个坐标空间
目标:
避免基础题翻车。PBR、法线、阴影、透明排序、坐标变换都是 TA 面试高频。
第四轮:20 分钟,软能力和岗位匹配
准备这些问题:
- 遇到美术说“效果不对”,你怎么排查?
- 遇到移动端发热 / 掉帧,你怎么定位?
- 如何制定 Shader 和材质规范?
- 如何推动美术使用工具,而不是只靠口头约定?
- 你如何和程序沟通管线改造的风险?
自我介绍技术版
可以按这个结构说:
我主要偏 Unity 渲染和客户端 TA 方向,平时关注 URP / SRP 管线、Shader 效果、屏幕空间算法和性能优化。做过 URP 延迟渲染 Feature,包括 GBuffer、HBAO、SSR、TAA、Contact Shadow 这类效果;也做过 GPU Driven 草地,用 Compute 做剔除,再用 DrawIndirect 绘制。底层方面我整理过 GPU 架构、TBDR、Shader 分支发散、half 精度和 RenderGraph 这些内容。我的优势是能把效果实现、性能分析和美术工作流规范结合起来,既能写 Shader,也能做工具和定位问题。
项目案例模板
每个项目都按这个顺序讲。
1 | |
可能被问的问题清单
管线类
- URP 的 ScriptableRenderer 和 ScriptableRenderPass 分别负责什么?
- RenderFeature 如何插入自定义 Pass?
- RenderGraph 和传统 CommandBuffer 写法有什么区别?
- Forward 和 Deferred 怎么选?
- 透明物体为什么一般不能直接走延迟光照?
- CopyColor / CopyDepth 为什么可能影响性能?
Shader 类
- HLSL 中
half一定比float快吗? - Shader 分支一定慢吗?
discard会影响什么优化?- 法线贴图为什么不能用 sRGB?
- TBN 里的 tangent.w 有什么用?
- 非均匀缩放下法线为什么用逆转置矩阵?
PBR 类
- Diffuse 为什么除以 π?
- GGX 的 D、F、G 分别是什么?
- Metallic 工作流里 BaseColor 表示什么?
- Roughness 和 Smoothness 有什么关系?
- AO 应该影响直接光还是间接光?
性能类
- 怎么判断一个 Shader 是 ALU 瓶颈还是带宽瓶颈?
- Overdraw 怎么看,怎么优化?
- Pre-Z 什么时候有收益,什么时候亏?
- 移动端 TBDR 为什么怕 Tile Flush?
- Shader Variant 爆炸怎么处理?
- DrawCall、Batch、Instancing、SRP Batcher 的差异是什么?
项目类
- GPU Driven 草地的完整流程?
- DrawIndirect 的 Args Buffer 里有什么?
- TAA 的 Ghosting 怎么处理?
- SSR 的局限是什么?
- HBAO / SSAO 的输入是什么?
- PCSS 和 PCF 的区别?
TA 协作类
- 美术提交的材质太贵,你怎么处理?
- 如何制定 Shader 规范?
- 如何让美术知道某个效果为什么贵?
- 如何做资源导入检查?
- 项目中你怎么平衡画质和性能?
临场回答原则
- 不确定版本细节时,说“具体实现和 Unity 版本有关”,再讲通用原理。
- 不要只说结论,要说定位路径。
- 遇到性能问题,先问瓶颈类型,再给优化方案。
- 遇到美术问题,先复现和可视化,再谈规范和工具。
- 不会 Houdini 深水区就承认边界,但把 Unity 接入和资源规范讲清楚。
- 多把答案落回你的案例: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、剔除、烘焙和性能规范。只要别把不会的部分说满,反而会显得稳。