8.Shader概念基础总结

8.Shader概念基础总结


8.1 核心要点速览

渲染管线

概述

渲染管线(流水线)的核心逻辑是 将数据分阶段转化为屏幕图像的过程,其关键要素可拆解为:

  • 数据来源:游戏场景中部署的 模型、光源、摄像机 等内容的底层信息;
  • 阶段划分:渲染流程的三大核心阶段,按顺序依次为:
    应用阶段 ——> 几何阶段 ——> 光栅化阶段

通过上述阶段对数据的逐步处理,最终在屏幕上生成可视化的渲染结果。

应用阶段

应用阶段是渲染管线中 由CPU主导 的核心环节,核心使命是 为后续渲染流程提供基础数据

  • 数据类型:涵盖顶点、法线、切线、纹理坐标、变换矩阵、材质属性等关键信息;
  • 开发逻辑:开发者只需 遵循Unity引擎规则 进行场景搭建、逻辑编写等工作,即可驱动该阶段运行;
  • 性能优化:当 DrawCall数量过多 时,会引发CPU侧性能瓶颈,可通过 批处理技术(合并绘制指令)优化。

几何阶段

几何阶段是渲染管线中 由GPU主导 的处理环节,核心围绕三维几何数据的加工与筛选展开:

  • 核心任务:对模型 顶点数据 进行计算(如位置修正、属性赋值),完成 坐标空间转换(例:模型空间→世界空间→裁剪空间的映射),并执行 图元裁剪(剔除屏幕视野外的无效几何,降低后续渲染压力);
  • 开发可干预点:通过 自定义顶点着色器 编写逻辑,修改顶点的位置、颜色等属性,实现顶点动画、风格化形变等独特画面效果。

光栅化阶段

光栅化阶段是渲染管线中 由GPU主导 的核心流程,核心围绕 片元的最终渲染决策 展开:

  • 核心任务:通过深度测试、透明度测试等逻辑,判定片元是否最终渲染;同时融合光照、纹理、材质等信息,计算片元的 最终渲染颜色
  • 开发可干预点:通过 自定义片元着色器 编写逻辑,控制片元的色彩、透明度、特效(如卡通渲染、辉光、溶解效果等),实现差异化画面表现。

Shader开发是什么

Shader开发的核心是 通过自定义逻辑处理渲染管线中的数据,以此决定最终渲染效果:

  • 本质逻辑:介入渲染管线的几何阶段(如顶点着色)、光栅化阶段(如片元着色),对顶点、片元等数据进行编程改造;
  • 实现形式:通过编写Shader代码,控制光照计算、纹理融合、颜色输出等渲染细节,实现卡通风格、辉光、溶解等定制化视觉效果。

如何学习Shader开发

学习Shader开发,需构建三类核心知识体系:

  • 数学知识:矩阵运算、向量变换、光照模型等(支撑坐标转换、光影计算的底层逻辑);
  • 语法知识:掌握Shader编程语言规则(如HLSL、GLSL,或Unity的ShaderLab语法);
  • 着色器开发知识:理解渲染管线阶段的干预逻辑(如顶点/片元着色器的工作流程与编程方法)。

掌握以上内容后,即可 按需求处理渲染数据,最终在屏幕呈现符合设计的图像效果。

Shader开发必备概念

  • 渲染管线与图形接口的关系:图形接口程序(如 OpenGLDX 等)是开发者与硬件交互的中间层,提供对渲染管线的控制与管理功能 。
  • Shader与图形接口的关系:Shader 属于 图形接口程序 的组成部分,用于编写渲染管线内的数据处理逻辑 。
  • 不同图形接口的影响:开发语言存在差异(如 DX 采用 HLSLOpenGL 常用 GLSL ),且坐标系规则不同(原点位置、轴向定义有别,需调整坐标计算逻辑) 。

8.2 面试题精选

基础题

1. 渲染管线三大阶段是什么?顺序能不能乱?

题目

应用阶段、几何阶段、光栅化阶段各自在干什么?谁先谁后?

深入解析
  • 应用阶段(CPU):准备场景与绘制所需数据(网格、材质、变换、相机等),发出绘制指令。
  • 几何阶段(GPU):处理顶点、做空间变换与裁剪相关准备,顶点着色器在此介入。
  • 光栅化阶段(GPU):光栅化生成片元,深度/模板/透明度等测试与着色,片元/像素着色器在此介入。
  • 顺序固定为 应用 → 几何 → 光栅化,输出最终写入帧缓冲的颜色(再经显示等链路)。
答题示例

渲染管线固定三段:应用阶段、几何阶段、光栅化阶段,顺序不能乱。

应用阶段 CPU 负责,把 mesh、材质、相机参数这些准备好,打包成绘制命令提交给 GPU。几何阶段 GPU 处理顶点,做空间变换、裁剪,顶点着色器就在这一步介入。光栅化阶段把图元拆成片元,片元着色器算最终颜色,再经深度测试等判定写不写进帧缓冲。

顺序固定是因为后一阶段的输入就是前一阶段的输出,跳步数据接不上。

参考文章
  • 1.渲染管线-概述

2. 为什么说应用阶段经常是 CPU 瓶颈?DrawCall 多意味着什么?

题目

批处理大致在优化什么?

深入解析
  • 应用阶段负责 场景遍历、提交绘制、资源绑定与状态切换;DrawCall 过多会导致 CPU 忙于发令与状态变更,GPU 反而等数据。
  • 批处理通过合并网格、合批、实例化等方式 减少绘制提交次数或合并绘制,降低 CPU 侧开销(具体手段依引擎与管线而定)。
答题示例

应用阶段是 CPU 驱动的,场景遍历、资源绑定、状态切换、提交 DrawCall 都压在这。DrawCall 一多,CPU 光发指令和切状态就忙不过来,GPU 反而在等数据——瓶颈就卡在 CPU 侧。

批处理本质是减少提交次数:合批把多个小网格攒成一次画,实例化一条指令画多份相同 mesh,都是让 CPU 少做重复功、少切状态。

参考文章
  • 2.渲染管线-应用阶段

3. 顶点着色器和片元着色器各管什么?中间数据怎么接?

题目

光栅化起什么作用?和「写 Shader」有什么关系?

深入解析
  • 日常说的 Shader 开发,多半就是在管 顶点着色器片元(像素)着色器:前者按顶点跑,改位置、颜色、UV 等 per-vertex 输出;后者按片元跑,算最终颜色、透明度等。
  • 顶点着色器输出经 插值 后成为片元着色器输入;光栅化负责把图元离散成 片元(候选像素及其插值属性)。
  • 最终是否写入屏幕还受 深度测试、模板测试、透明度、混合 等影响。
  • 与固定管线对比:现在是 可编程阶段 决定怎么变换顶点、怎么给片元赋色。
答题示例

顶点着色器按顶点跑,负责位置变换、UV、法线这些 per-vertex 属性的处理,顶点动画通常也在这做。片元着色器按片元跑,拿到光栅化插值后的数据去采纹理、算光照、输出最终颜色。

中间光栅化把三角形离散成片元,顶点着色器的输出经插值传给片元着色器。片元算完颜色还得过深度测试、模板测试、alpha test、blend,能过才写进 framebuffer。

日常写 Shader 基本就在这两个可编程阶段做文章,一个管顶点怎么变换,一个管像素最终长什么样。

参考文章
  • 3.渲染管线-几何阶段
  • 4.渲染管线-光栅化阶段
  • 5.Shader开发是什么
  • 6.如何学习Shader开发

进阶题

1. 为什么要分模型空间、世界空间、裁剪空间?

题目

不直接在一种空间里算不行吗?

深入解析
  • 模型空间:建模局部坐标,方便美术与骨骼动画。
  • 世界空间:场景统一坐标,方便光照、物理与多物体关系。
  • 裁剪/齐次空间:方便 投影、裁剪与透视除法,为光栅化做准备。
  • 分空间是为了 职责清晰、公式标准、与管线阶段对齐;顶点着色器常承担 串联多种变换 的职责(具体矩阵乘积顺序以实现为准)。
答题示例

分空间是为了职责清晰。模型空间是建模用的局部坐标,美术和骨骼动画在这处理;世界空间统一了所有物体的坐标系,光照、物理、空间关系才算得通;裁剪空间服务于投影和裁剪,光栅化需要这个基础。

硬塞一个空间里也能算,但变换公式混在一起,调试和维护都很痛苦。工程上 MVP 矩阵一串在顶点着色器里乘完,每个空间对应明确的变换步骤,出问题好定位。

参考文章
  • 3.渲染管线-几何阶段
  • 1.渲染管线-概述

2. 图元裁剪和深度测试,直觉上差在哪一层?

题目

谁更偏「大块几何」,谁更偏「像素前后关系」?

深入解析
  • 图元裁剪:面向 三角形等图元,去掉视野外或无效图元,减少后续光栅化量。
  • 深度测试:面向 片元/像素,在 framebuffer 上解决 前后遮挡,决定保留哪个片元的颜色。
  • 二者粒度不同:前者减几何工作量,后者解决可见性竞争
答题示例

图元裁剪是几何阶段的事,粒度是整块三角形——视锥外的直接剔掉,后面少光栅化一大截,属于粗粒度减负。

深度测试是光栅化之后、片元级别的操作,在 framebuffer 上比 Z 值,近的留远的丢,解决的是前后遮挡关系。

一个管”要不要处理这块几何”,一个管”这个像素位置谁盖住谁”,层级和粒度完全不同。

参考文章
  • 3.渲染管线-几何阶段
  • 4.渲染管线-光栅化阶段

3. 图形 API、渲染管线、Shader,三句话怎么串起来?

题目

Shader 算不算脱离 API 自己跑的一套东西?

深入解析
  • 图形 API(OpenGL、DirectX、Vulkan、Metal 等)是 CPU 侧调用 GPU 的接口与驱动模型,负责资源、状态与绘制提交。
  • 渲染管线GPU 上数据变为像素的阶段化流程(概念模型与具体实现随 API/硬件演进)。
  • Shader 是跑在 GPU 上的 可编程阶段程序,由 API/引擎编译与绑定,属于图形栈的一部分,不是脱离 API 单独存在的黑盒。
答题示例

Shader 不是脱离 API 单独跑的,编译、绑定、调度全得走图形 API 那套流程。

三者关系可以这么串:图形 API(OpenGL、DX、Vulkan 这些)是 CPU 侧调 GPU 的接口,负责资源管理和绘制提交;渲染管线是 GPU 内部数据变成像素的阶段化流程;Shader 是管线里可编程阶段的代码,由 API 或引擎负责编译和绑定到对应阶段上。

简单说就是:API 发号施令,管线是流水线,Shader 是流水线上能自己写逻辑的那几个工位。

参考文章
  • 7.Shader开发必备概念

4. HLSL 和 GLSL 差异一般在哪?Unity 里常见是哪一种语境?

题目

换引擎或换 API 时,着色器代码为什么要改接口层?

深入解析
  • 语言与生态:HLSL 偏 DirectX / 主机与 Windows 系;GLSL 偏 OpenGL / 部分跨平台栈(现代还会遇到 SPIR-V 等中间表示,依项目而定)。
  • 语法细节:入口、语义、内置变量名、纹理采样函数名等 各不相同,移植要改接口层。
  • Unity:内置管线时代常见 ShaderLab + HLSL/CG 系;与纯 GLSL 移动端/自研引擎路径不同,面试要说清 目标平台与管线
答题示例

HLSL 和 GLSL 入口函数、语义标记、内置变量名、纹理采样接口全不一样,直接搬代码编译都过不了,换引擎或换 API 就得改接口层。

生态上,HLSL 绑定 DirectX,Windows 和主机项目居多;GLSL 跟 OpenGL 走,跨平台或移动端常见。Unity 内置管线主要是 ShaderLab 包 HLSL/CG,跟纯 GLSL 方案是两条路。

实际项目中讲清楚用的是哪条技术栈,比空泛对比两种语言更有针对性。

参考文章
  • 7.Shader开发必备概念
  • 6.如何学习Shader开发

深度题

1. 渲染管线中哪些环节是开发者能写代码介入的,哪些是固定流程?

题目

可编程阶段和固定功能阶段的划分对 Shader 开发意味着什么?

深入解析
  • 可编程阶段:本系列明确提到 顶点着色器(几何阶段的开发可干预点)和 片元着色器(光栅化阶段的开发可干预点),开发者通过编写 Shader 代码控制这两个阶段的行为。
  • 固定功能阶段:光栅化本身(图元→片元的离散化)、深度测试、透明度测试、混合等,由 GPU 硬件按固定规则执行,开发者只能通过渲染状态参数配置行为,不能重写其逻辑。
  • 意义:Shader 开发本质上就是在可编程阶段做文章——顶点着色器决定”几何怎么变换”,片元着色器决定”颜色怎么算”;固定阶段的规则(如深度比较方式、混合模式)只能通过引擎/API 提供的配置项调整。
答题示例

渲染管线里真正能写代码的就两块:顶点着色器和片元着色器。顶点着色器跑在几何阶段,管顶点位置变换、UV、法线这些;片元着色器跑在光栅化阶段后段,管最终颜色输出。

其他环节比如光栅化本身、深度测试、混合,都是 GPU 固定流程,开发者只能配参数,比如选深度比较函数、设混合模式,没法重写逻辑。

所以写 Shader 就是在这两个可编程工位上做文章,想实现什么效果都得落到”顶点怎么改”和”片元颜色怎么算”上来。

参考文章
  • 3.渲染管线-几何阶段
  • 4.渲染管线-光栅化阶段
  • 5.Shader开发是什么

2. 从应用阶段到最终出图,数据形态经历了哪些关键变化?

题目

能不能用一条线把数据从 CPU 到屏幕的变化串起来?

深入解析
  • 应用阶段(CPU):数据以 模型、材质、变换矩阵、相机参数 等高层描述存在,CPU 打包后通过绘制指令提交给 GPU。
  • 几何阶段(GPU):数据变成 逐顶点 的形式——位置、法线、UV 等属性经过坐标空间转换(模型空间→世界空间→裁剪空间),无效图元被裁剪剔除。
  • 光栅化阶段(GPU):顶点数据经插值变成 逐片元 的属性,片元着色器算出颜色后,经深度测试、透明度测试等筛选,最终写入 帧缓冲,由显示器读取输出。
  • 关键转变点:CPU→GPU 的提交边界顶点→片元的光栅化离散片元→帧缓冲的测试筛选
答题示例

可以用数据形态的变化串起来:应用阶段 CPU 这边,数据还是模型、材质、变换矩阵这些高层描述,打包成绘制命令提交给 GPU。

进了几何阶段,数据变成逐顶点的——位置、法线、UV 逐个做坐标空间转换,屏幕外的图元裁掉。然后光栅化把三角形离散成片元,顶点属性插值到每个片元上,片元着色器算颜色。

最后片元还得过深度测试、透明度测试这些关卡,能过的才写进帧缓冲。整条线就是:高层场景描述 → 逐顶点 → 逐片元 → 帧缓冲像素。

参考文章
  • 1.渲染管线-概述
  • 2.渲染管线-应用阶段
  • 3.渲染管线-几何阶段
  • 4.渲染管线-光栅化阶段

3. 学 Shader 为什么数学、语法、着色器知识缺一不可?

题目

三块知识在实际 Shader 开发中分别起什么作用?

深入解析
  • 数学知识:矩阵运算支撑坐标空间转换(模型→世界→裁剪),向量运算支撑光照计算(点积算漫反射、叉积算法线方向等)。没有数学基础,顶点着色器里的变换和片元着色器里的光照都写不明白。
  • 语法知识:HLSL、GLSL 或 ShaderLab 各有自己的入口函数、语义、内置变量规则。语法不熟,代码写不对、调不通,也看不懂引擎内置 Shader 的实现。
  • 着色器开发知识:理解渲染管线各阶段的职责与数据流向,知道顶点着色器和片元着色器各自能干什么、输入输出是什么。没有这层认知,数学和语法都学了也不知道往哪用。
  • 三者关系:管线认知定方向,数学定算法,语法定实现,实际开发中三者交织配合。
答题示例

三块知识各管一层。着色器开发知识管”方向”——得知道渲染管线怎么走、顶点着色器和片元着色器各自能干什么,不然写代码都不知道往哪个阶段写。

数学知识管”算法”——坐标变换靠矩阵乘法,光照计算靠向量点积叉积,这些是顶点着色器和片元着色器里最核心的运算逻辑。

语法知识管”落地”——同样的数学逻辑,HLSL、GLSL、ShaderLab 写法不一样,入口函数、语义、内置变量都得按目标语言的规矩来。三块缺哪块都会卡住。

参考文章
  • 6.如何学习Shader开发
  • 7.Shader开发必备概念


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏