44.Shader开发入门总结
44.1 核心要点速览
光照模型
光照模型是用公式近似「光与材质如何作用」的算法。学习主线:漫反射 → 高光 → 综合模型 → Unity 辅助函数。
漫反射光照模型
漫反射强度由法线与光源方向夹角决定:夹角越小、余弦越大、越亮。
兰伯特光照模型
- 公式:
漫反射颜色 = 光源颜色 × 材质漫反射颜色 × max(0, 法线方向 · 光源方向)
\[
C_d = \mathbf{L} \odot \mathbf{M}_d \cdot \max(0, \mathbf{n}\cdot\mathbf{l})
\]
- 各项含义:\( \mathbf{L} \) 光源颜色,\( \mathbf{M}_d \) 漫反射色,\( \odot \) 按分量乘(R×R, G×G, B×B);\( \max(0, \mathbf{n}\cdot\mathbf{l}) \) 法线与光方向余弦,背光截为 0,须单位向量。
- 实践:
_LightColor0取光色;_WorldSpaceLightPos0.xyz并normalize;法线UnityObjectToWorldNormal转世界空间;UNITY_LIGHTMODEL_AMBIENT.rgb避免阴影死黑。
半兰伯特光照模型
纯兰伯特背光面整块为 0;半兰伯特把 \( \mathbf{n}\cdot\mathbf{l}\in[-1,1] \) 映射到 \( [0,1] \),背光仍有灰阶,是观感技巧而非物理模型。
- 公式:
漫反射颜色 = 光源颜色 × 材质漫反射颜色 × ((法线方向 · 光源方向) / 2 + 1/2)
\[
C_d^{\mathrm{half}} = \mathbf{L} \odot \mathbf{M}_d \cdot \left(\frac{\mathbf{n}\cdot\mathbf{l}}{2}+\frac{1}{2}\right)
\]
- 各项含义:与兰伯特相同,仅把 \( \max(0, \mathbf{n}\cdot\mathbf{l}) \) 换为 \( \dfrac{\mathbf{n}\cdot\mathbf{l}}{2}+\dfrac{1}{2} \),映射到 \( [0,1] \),不做硬截断。
高光反射光照模型
镜面感来自「视线方向」与「反射方向 / 半角方向」的对齐程度。
Phong 式高光反射
先算反射方向 \( \mathbf{r}=\mathrm{reflect}(-\mathbf{l},\mathbf{n}) \),再看 \( \mathbf{v} \) 与 \( \mathbf{r} \) 是否接近;pow 指数 \( n \) 控制高光锐利度。
- 公式:
高光颜色 = 光源颜色 × 材质高光颜色 × max(0, 视角方向 · 反射方向) ^ 光泽度
反射方向 = reflect(-光源方向, 法线方向)
\[
C_s = \mathbf{L} \odot \mathbf{M}_s \cdot \max(0,\mathbf{v}\cdot\mathbf{r})^{n},\quad \mathbf{r}=\mathrm{reflect}(-\mathbf{l},\mathbf{n})
\]
- 各项含义:\( \mathbf{M}_s \) 材质高光色;\( \max(0,\mathbf{v}\cdot\mathbf{r})^n \) 视线与反射方向对齐度,\( n \) 越大高光越尖;\( \mathbf{r} \) 由
reflect(-l, n)得到。 - 实践:
reflect入射符号用-光源方向;视角方向_WorldSpaceCameraPos - worldPos再normalize。
Blinn-Phong 式高光反射
用半角向量 \( \mathbf{h}=\mathrm{normalize}(\mathbf{v}+\mathbf{l}) \) 代替反射方向,看 \( \mathbf{n} \) 与 \( \mathbf{h} \) 是否接近;通常更快、高光略柔和。
- 公式:
高光颜色 = 光源颜色 × 材质高光颜色 × max(0, 法线方向 · 半角方向) ^ 光泽度
半角方向 = normalize(视角方向 + 光源方向)
\[
C_s = \mathbf{L} \odot \mathbf{M}_s \cdot \max(0,\mathbf{n}\cdot\mathbf{h})^{n},\quad \mathbf{h}=\mathrm{normalize}(\mathbf{v}+\mathbf{l})
\]
- 各项含义:与 Phong 同,仅把 \( \mathbf{v}\cdot\mathbf{r} \) 换为 \( \mathbf{n}\cdot\mathbf{h} \);\( \mathbf{h} \) 为视线与光方向的角平分方向。
综合光照模型
环境光 + 漫反射 + 高光,三项 RGB 相加。
Phong 光照模型
- 公式:
最终颜色 = 环境光 + 兰伯特漫反射 + Phong 高光
\[
C = C_{\mathrm{amb}} + C_d^{\mathrm{Lambert}} + C_s^{\mathrm{Phong}}
\]
- 各项含义:\( C_{\mathrm{amb}} \) 环境光(
UNITY_LIGHTMODEL_AMBIENT/ 天空盒),\( C_d \) 兰伯特漫反射,\( C_s \) Phong 高光。
Blinn-Phong 光照模型
与 Phong 相同的三项结构,仅高光换成 Blinn-Phong 项;实时渲染里更常见。
- 公式:
最终颜色 = 环境光 + 兰伯特漫反射 + Blinn-Phong 高光
\[
C = C_{\mathrm{amb}} + C_d^{\mathrm{Lambert}} + C_s
\]
- 各项含义:与 Phong 光照模型相同,仅 \( C_s \) 换为 Blinn-Phong 高光项。
光照模型对照表
| 名称 | 核心思路 | 公式骨架 | 关键参数与特点 | 白话一行 |
|---|---|---|---|---|
| 兰伯特漫反射 | 法线与光方向夹角越小越亮 | \( \mathbf{L}\odot\mathbf{M}_d\cdot\max(0,\mathbf{n}\cdot\mathbf{l}) \) | 世界空间法线、光向;背光可全黑 | 漫反 = 光×漫材×max(0, n·l) |
| 半兰伯特 | 点积映射到 \( [0,1] \),背光有层次 | 上式中把 \( \max(0,\cdot) \) 换为 \( \frac{\mathbf{n}\cdot\mathbf{l}}{2}+\frac{1}{2} \) | 风格化友好,非能量守恒物理模型 | 漫反 = 光×漫材×((n·l)/2+1/2) |
| Phong 高光 | 视线与反射方向对齐程度 | \( \propto \max(0,\mathbf{v}\cdot\mathbf{r})^{n} \) | reflect(-光向, 法线);\( n \) 越大越尖 |
高光 = 光×高光材×max(0,v·r)^n |
| Blinn-Phong 高光 | 法线与半角对齐程度 | \( \propto \max(0,\mathbf{n}\cdot\mathbf{h})^{n} \) | 少 reflect,常更快、略柔和 |
高光 = 光×高光材×max(0,n·h)^n |
| Phong 光照模型 | 环境 + 兰伯特 + Phong 高光 | 三项相加 | 经典完整模型 | 最终 = 环境 + 漫反 + Phong高光 |
| Blinn-Phong 光照模型 | 环境 + 兰伯特 + Blinn-Phong 高光 | 三项相加 | 游戏与引擎中更常用 | 最终 = 环境 + 漫反 + BP高光 |
- 名词分清:「Phong/Blinn-Phong 高光」只负责镜面项;「Phong/Blinn-Phong 光照模型」指 整碗汤(环境 + 漫反射 + 高光)。
- 效率:同条件下 Blinn-Phong 高光常省掉显式反射向量,更适合逐像素计算密集的实时场景。
逐顶点与逐片元光照
- 类比:顶点光照像在 几个角 算好明暗再插值涂满三角面,省算力但易糊;片元光照是 每个像素 用自身插值后的法线、位置再算,更准更贵。
- 原因:顶点间颜色由光栅化 插值 得到,无法表现细尺度明暗;片元阶段可再用高精度法线(如法线贴图)参与计算。
- 性能:顶点着色器按顶点计费,片元着色器按覆盖像素计费;同模型下移计算到片元通常更耗。
Unity 内置常用函数
| 函数 | 作用 |
|---|---|
WorldSpaceViewDir(v) |
模型空间顶点 → 世界空间观察方向(未归一化) |
UnityWorldSpaceViewDir(v) |
世界空间顶点 → 世界空间观察方向 |
ObjSpaceViewDir(v) |
模型空间顶点 → 模型空间观察方向 |
WorldSpaceLightDir(v) |
模型空间顶点 → 世界空间光照方向(Forward) |
UnityWorldSpaceLightDir(v) |
世界空间顶点 → 世界空间光照方向 |
ObjSpaceLightDir(v) |
模型空间顶点 → 模型空间光照方向 |
UnityObjectToWorldNormal |
法线模型→世界(含非均匀缩放修正) |
UnityObjectToWorldDir |
方向向量模型→世界 |
UnityWorldToObjectDir |
方向向量世界→模型 |
UnityObjectToClipPos |
模型空间 → 裁剪空间 |
返回方向常需 normalize;光照方向函数仅在 Forward 渲染有效。
纹理
纹理与 UV 在干什么
- 问题:模型只有几何,如何贴上「皮」?
- 分析:美术在 DCC 里为顶点写入 UV;GPU 光栅化时对 UV 插值,片元里用
tex2D取色。 - 公式:
纹理坐标取值范围 [0, 1]²,与贴图像素数无关
\[
(u,v) \in [0,1]^2
\]
- 各项含义:\( u,v \) 为纹理上横向、纵向归一化坐标,与贴图分辨率无关。
- 实践:
sampler2D _MainTex+float4 _MainTex_ST(xy 缩放、zw 偏移);TRANSFORM_TEX或手动uv * _ST.xy + _ST.zw。
导入设置:Wrap 与 Filter
- Wrap Mode:
Repeat像瓷砖重复;Clamp钳住边缘防绕回;还有镜像等变体,按美术需求选。 - Filter Mode:
Point硬边像素风;Bilinear/Trilinear缩放更柔,常配合 Mipmap 减闪烁与走样。
单张纹理 + Blinn-Phong
- 问题:贴图颜色与光照如何合成才不假灰、不假白?
- 分析:把采样结果当作 反照率 albedo:
albedo = texColor × 漫反射色;兰伯特项用albedo;环境光也乘albedo,避免「环境一块灰蒙在模型上」。 - 综合:
最终 ≈ 环境光×albedo + 漫反射项 + Blinn-Phong 高光项(与系列课文一致即可)。
凹凸纹理(法线贴图)
- 问题:不加三角面,如何做出细小凹凸?
- 分析:用贴图存 扰动后的法线,光照仍按新法线算,眼睛感到起伏。高度图 灰度存高度,常需额外求导变正法线,开销大;法线贴图 直接存法线向量更常用。
- 空间选择:切线空间 法线偏蓝紫,易复用到不同朝向表面;模型空间 法线彩色、直观但换模型常要重烘焙。世界空间 算法线光照利于点光等,但矩阵与变体更多。
- 实践套路:
appdata_full带切线;副切线bitangent = cross(n, t) * tangent.w;构建TBN;UnpackNormal解码;_BumpScale控制强度。切线空间算法:光向、视向转到切线空间再dot;世界空间算法:法线转到世界空间再与光向、半角算。
渐变纹理(Ramp)
- 问题:如何把连续明暗变成 色带、插画感?
- 分析:用半兰伯特标量当作 UV(如
float2(t,t))采样_RampTex,用纹理颜色 重映射 明暗,而非直接用标量当亮度。 - 公式:
明暗标量 = (法线方向 · 光源方向) / 2 + 1/2,用该值采样渐变纹理做明暗重映射
\[
t=\frac{\mathbf{n}\cdot\mathbf{l}}{2}+\frac{1}{2}\in[0,1]
\]
- 各项含义:\( t \) 为半兰伯特标量 \( \in[0,1] \),
_RampTex是渐变查找表。 - 实践:渐变图
Wrap Mode用Clamp,避免浮点误差在Repeat下绕回采到黑点。
遮罩纹理
- 问题:同一材质上,有的区域要更强高光、有的区域要压住特效?
- 分析:用贴图某一通道(如 R)作 局部权重,再乘自定义系数
_SpecularScale,最后乘进高光项。RGBA 四路可分别存高光、透明、特效等,减少贴图张数。
透明
前置概念:队列、深度、测试、混合
- 渲染队列:由 SubShader
Tags中的键Queue指定;决定大致绘制顺序。透明物体通常排在不透明之后,才能读到背后颜色做混合。 - 深度缓冲:每像素记「目前最近深度」;深度测试决定新片元是否通过;混合决定通过后的颜色如何与颜色缓冲已有值合成。
- 直觉:不透明物体常开深度写入,顺序不敏感;半透明常要
ZWrite Off(关深度写入)才能混合背后,但引入 排序敏感(前后穿插时可能错)。
深度写入、队列与混合(Shader 里怎么写)
ZWrite:写在 Pass 内,只影响该 Pass。半透明 Pass 常见ZWrite Off。- 队列与渲染类型:
Queue与RenderType写在 SubShader 的Tags中,影响其下所有 Pass。
Pass
{
Tags { "LightMode"="ForwardBase" }
ZWrite Off
}
SubShader
{
Tags{ "Queue" = "AlphaTest" "IgnoreProjector" = "True" "RenderType" = "TransparentCutout" }
}
SubShader
{
Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
}
混合通式(RGB 与 A 可分别指定因子;具体以目标平台文档为准)
公式:
混合 RGB = 源因子 × 片元色 + 目标因子 × 缓冲色
\[
O_{\mathrm{rgb}} = F_s \cdot S_{\mathrm{rgb}} + F_d \cdot D_{\mathrm{rgb}}
\]
- 各项含义:\( F_s,F_d \) 为源/目标混合因子(
Blend指令配置),\( S \) 片元色,\( D \) 缓冲已有色。
常见 透明度混合:Blend SrcAlpha OneMinusSrcAlpha,即
- 公式:
输出色 = α × 片元色 + (1 − α) × 缓冲色
\[
\mathbf{C}_{\mathrm{out}} = \alpha \mathbf{C}_S + (1-\alpha)\mathbf{C}_D
\]
- 各项含义:\( \alpha \) 片元透明度,\( \mathbf{C}_S \) 片元色,\( \mathbf{C}_D \) 缓冲色;对应
Blend SrcAlpha OneMinusSrcAlpha。
透明度测试(Alpha Test)
- 场景:树叶、栅栏、草等 镂空,不要真半透明。
- 做法:
clip(texColor.a - _Cutoff),低于阈值直接丢弃片元;通过的可按不透明写深度。Queue=AlphaTest,RenderType=TransparentCutout;不必关深度写入。
透明度混合
- 场景:玻璃、水、特效半透明层。
- 做法:
Queue=Transparent,ZWrite Off,Blend SrcAlpha OneMinusSrcAlpha;返回颜色的 alpha 常用texColor.a * _AlphaScale。注意整体渲染顺序与穿插。
双 Pass:先钉深度再混合
- 问题:复杂网格自穿插时,单纯关
ZWrite易导致片元顺序错乱。 - 解决:第一 Pass
ZWrite On且ColorMask 0只写深度;第二 Pass 正常半透明混合。代价是多一遍几何;模型内部一般不互相混合,仅最前层参与混合。
双面透明
Cull:Cull Back默认只正面;Cull Front只背面;Cull Off双面。- Alpha Test:常
Cull Off即可双面镂空。 - Alpha Blend:常用两 Pass——先
Cull Front画背,再Cull Back画前,保证混合顺序与薄壳玻璃观感。
44.2 面试题精选
基础题
1. 兰伯特与半兰伯特漫反射的区别
题目
兰伯特漫反射与半兰伯特漫反射各如何计算?半兰伯特解决了什么视觉问题?它是否更「物理正确」?
深入解析
- 兰伯特:\( C_d \propto \max(0, \mathbf{n}\cdot\mathbf{l}) \),背光侧点积为负时被截断为 0,整块背光可显得死黑;白话可记
C_d ∝ max(0, n·l)。 - 半兰伯特:把 \( \mathbf{n}\cdot\mathbf{l} \) 从 \( [-1,1] \) 线性映射到 \( [0,1] \),背光仍有明暗渐变,利于卡通、手绘感;白话可记
C_d ∝ (n·l)/2+1/2(代替max(0,n·l))。 - 物理性:半兰伯特是视觉近似,不是能量守恒的物理模型;面试里要能说清「为什么好看」和「为什么不等于真实漫反射」。
答题示例
兰伯特用 \( \max(0, \mathbf{n}\cdot\mathbf{l}) \),背光容易全黑。半兰伯特用 \( \frac{\mathbf{n}\cdot\mathbf{l}}{2}+\frac{1}{2} \) 把点积拉到 0~1,背光也有层次。它是风格化技巧,不强调物理正确。
参考文章
- 3.光照模型-漫反射光照模型-兰伯特光照模型-必备知识点
- 6.光照模型-漫反射光照模型-半兰伯特光照模型-必备知识点
2. Phong 高光与 Blinn-Phong 高光的差异
题目
Phong 高光与 Blinn-Phong 高光在方向量选择上差在哪里?为何实时渲染里更常见 Blinn-Phong?
深入解析
- Phong:用反射方向 \( \mathbf{r}=\mathrm{reflect}(-\mathbf{l},\mathbf{n}) \),高光项看 \( \mathbf{v}\cdot\mathbf{r} \);白话可记
C_s ∝ max(0, v·r)^n,r = reflect(−l, n)。 - Blinn-Phong:用半角向量 \( \mathbf{h}=\mathrm{normalize}(\mathbf{v}+\mathbf{l}) \),高光项看 \( \mathbf{n}\cdot\mathbf{h} \);白话可记
C_s ∝ max(0, n·h)^n,h = normalize(v+l)。 - 工程上:避免显式求反射向量、高光形状往往更稳;代价是「在相同指数 \( n \) 下」与 Phong 高光宽度并不完全一致,调参时要心里有数。
答题示例
Phong 用视角和反射方向的夹角;Blinn-Phong 用法线和半角向量的夹角。Blinn-Phong 少算反射方向、GPU 友好,游戏里更常用,但光泽度要和 Phong 一一对应需要重新调。
参考文章
- 9.光照模型-高光反射光照模型-Phong式高光反射模型-必备知识点
- 12.光照模型-高光反射光照模型-BlinnPhong式高光反射模型-必备知识点
3. 透明度测试与透明度混合怎么选
题目
AlphaTest(clip)与半透明 Alpha Blend 各适合什么效果?对深度写入、排序各有什么影响?
深入解析
- 透明度测试:像素要么保留要么
discard,一般可保持ZWrite On,排序压力小,适合镂空、树叶、栅栏。 - 透明度混合:真半透明,常配
ZWrite Off+Blend SrcAlpha OneMinusSrcAlpha,依赖渲染顺序,玻璃、水体、特效常用。 - 易错点:把需要柔和渐变的半透明硬做成 clip,或把镂空当半透明又开深度写入导致层次错误。
答题示例
Clip 是硬切,一般还能写深度,适合镂空。半透明要混合背后颜色,通常关深度写入,所以同一批透明物体排序很重要;玻璃、雾状用混合,草叶栅栏多用 AlphaTest。
参考文章
- 40.透明-效果实现-透明度测试
- 41.透明-效果实现-透明度混合
进阶题
1. 逐顶点与逐片元光照的取舍
题目
同样一套光照公式,放在顶点着色器和片元着色器里效果差在哪里?为什么片元更贵?
深入解析
- 逐顶点:光照在顶点上算完,颜色在三角形内插值,高光、法线变化快时容易「糊、条带」。
- 逐片元:每像素用插值后的法线、位置再算,细节好,但指令数随分辨率线性放大。
- 选用:移动端或大量简单物体可顶点光照;角色、法线贴图、锐利高光优先片元。
答题示例
顶点光照是算在顶点上再插值,中间像素不重新算光照,所以高光和法线细节容易糊。片元光照每像素算,贵但准。有法线贴图或要高光质量就上片元。
参考文章
- 2.光照模型-逐顶点光照和逐片元光照
- 21.光照模型-为什么逐片元比逐顶点平滑
2. 半透明为何常关闭深度写入
题目
不透明物体可以乱序画,半透明为什么往往要关 ZWrite?关了以后带来什么问题、引擎一般怎么缓解?
深入解析
- 关 ZWrite 的目的:同一像素要累积「背后已经画好的颜色」,若先写上近处深度,远处半透明片元可能被深度测试挡掉,混合无从谈起。
- 副作用:透明物体之间依赖绘制顺序,交叉、自穿插模型容易穿帮。
- 缓解:按队列排序、拆模型、双 Pass 深度预写、或接受限制并分材质排序。
答题示例
半透明要和 framebuffer 里已有颜色混合,如果还写深度,后面的透明片元可能被深度测试直接扔掉。所以常关深度写入,代价是透明物体谁先画谁后画会影响结果,要靠队列和排序,复杂情况用双 Pass 或拆 mesh。
参考文章
- 36.透明-必备知识点-重要知识回顾
- 37.透明-必备知识点-渲染顺序的重要性
3. 切线空间法线贴图为何更常用
题目
法线贴图为什么多做成切线空间?和模型空间法线比,各有什么代价?
深入解析
- 切线空间:纹素存的是相对表面的扰动,同一张贴图可跨不同朝向、可动画蒙皮复用,美术流水线友好。
- 模型空间:每个纹素对应绝对方向,物体变形、复用差,但实现上有时少一套 TBN 变换。
- Shader 侧:切线空间要在顶点构造 TBN,把光方向或法线转到同一空间再算点积;世界空间法则在世界空间算光照。
答题示例
切线空间里法线是相对表面局部坐标,贴图可以重复用在不同朝向的模型上,动画顶点也不会轻易「法线乱飞」。模型空间法线跟模型绑定,复用差。代价是 Shader 里要 TBN 变换,多一点顶点与矩阵工作。
参考文章
- 27.纹理-凹凸纹理-基本概念
- 28.纹理-凹凸纹理-法线贴图的计算方式
- 29.纹理-凹凸纹理-切线空间下计算
深度题
1. 法线贴图:切线空间与世界空间两条算路
题目
在切线空间采样法线贴图与在世界空间用 TBN 把法线转出来再光照,各适合什么光源与性能权衡?
深入解析
- 切线空间算光照:顶点把 \( \mathbf{l} \)、\( \mathbf{v} \) 变到切线空间,片元里与解包法线直接
dot,纹理采样与光照同空间,定向光下很顺。 - 世界空间:片元把切线法线乘 TBN 到世界空间,与
_WorldSpaceLightPos0等统一算;点光、聚光、多光源时少重复变换逻辑。 - 性能:切线空间常减少片元里矩阵组合次数;世界空间可能增加插值与寄存器(传 TBN 三向量)。选型看光源种类与变体数量。
答题示例
切线空间是把光向和视角转到切线空间,在片元里和法线贴图解包结果直接点积,定向光很省事。世界空间是把法线用 TBN 转到世界再算,点光源多的时候更自然。性能上要看是少算片元矩阵还是少插值数据,项目里会按光源类型选一条路或做 Shader 变体。
参考文章
- 29.纹理-凹凸纹理-切线空间下计算
- 30.纹理-凹凸纹理-世界空间下计算
2. 双 Pass 深度预写半透明
题目
ColorMask 0 + ZWrite On 的第一个 Pass 加上正常透明混合的第二个 Pass,解决了什么问题?仍有哪些现象是这套方案解决不了的?
深入解析
- 机制:Pass1 只写深度不写颜色,把「模型最前表面」钉在深度缓冲里;Pass2 半透明混合时深度测试能挡住被其它物体遮挡的片元,减轻凸包内部错误混合。
- 局限:同物体内部多层半透明仍不会像真实介质那样层层混合(近似成只有最前层参与);多 Pass 增加带宽与 Overdraw。
- 与排序关系:不能替代所有排序问题,只是减少「同物体内部」一类错误。
答题示例
第一遍只写深度不输出颜色,相当于先把物体最前面的深度定下来;第二遍再半透明混合,深度测试能去掉被挡住的片元,减轻比如头发、树叶那种内部乱序。但它不能让模型内部多层透明都物理正确混合,只是近似,还多一次 Pass 成本。
参考文章
- 42.透明-效果实现-开启深度写入的半透明效果
3. 渐变纹理与 Wrap Mode
题目
用半兰伯特标量去采样渐变纹理做卡通明暗时,为什么常把渐变纹理设为 Clamp?Repeat 下会出现什么现象?
深入解析
- 半兰伯特输出:理论在 \( [0,1] \),浮点误差可能略大于 1 或略小于 0。
- Repeat:UV 取小数部分,略大于 1 会绕回纹理左侧,出现错误条带或黑点。
- Clamp:越界钳在 0 或 1,明暗稳定在条带两端;与渐变纹理「一维查找表」语义一致。
答题示例
半兰伯特算出来应该是 0~1,但浮点会有 1.0001 这种。Repeat 会取小数部分,采样会跳到纹理另一端,出现噪点或黑条。Clamp 把坐标钉在 0~1 边界,卡通 ramp 一般都用它。
参考文章
- 31.纹理-渐变纹理-基本概念
- 32.纹理-渐变纹理-基础实现
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com