44.Shader开发入门总结

  1. 44.Shader开发入门总结
    1. 44.1 核心要点速览
      1. 光照模型
        1. 光照模型概述
        2. 兰伯特漫反射
        3. 半兰伯特漫反射
        4. Phong 式高光反射
        5. Blinn-Phong 式高光反射
        6. Phong 光照模型(完整)
        7. Blinn-Phong 光照模型(完整)
        8. 光照模型对照表
        9. 逐顶点与逐片元光照
        10. Unity 内置常用函数(UnityCG.cginc)
      2. 纹理
        1. 纹理与 UV 在干什么
        2. 导入设置:Wrap 与 Filter
        3. 单张纹理 + Blinn-Phong
        4. 凹凸纹理(法线贴图)
        5. 渐变纹理(Ramp)
        6. 遮罩纹理
      3. 透明
        1. 前置概念:队列、深度、测试、混合
        2. 深度写入、队列与混合(Shader 里怎么写)
        3. 透明度测试(Alpha Test)
        4. 透明度混合
        5. 双 Pass:先钉深度再混合
        6. 双面透明
    2. 44.2 面试题精选
      1. 基础题
        1. 1. 兰伯特与半兰伯特漫反射的区别
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        2. 2. Phong 高光与 Blinn-Phong 高光的差异
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        3. 3. 透明度测试与透明度混合怎么选
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
      2. 进阶题
        1. 1. 逐顶点与逐片元光照的取舍
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        2. 2. 半透明为何常关闭深度写入
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        3. 3. 切线空间法线贴图为何更常用
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
      3. 深度题
        1. 1. 法线贴图:切线空间与世界空间两条算路
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        2. 2. 双 Pass 深度预写半透明
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章
        3. 3. 渐变纹理与 Wrap Mode
          1. 题目
          2. 深入解析
          3. 答题示例
          4. 参考文章

44.Shader开发入门总结


44.1 核心要点速览

光照模型

光照模型概述

  • 问题:已知管线、向量矩阵与 ShaderLab/CG 语法后,屏幕上「亮多少、什么颜色」仍要单独建模。
  • 定义:光照模型是用公式近似描述光与材质相互作用的算法,决定表面亮度与颜色(入射光、材质参数与交互规律共同作用)。
  • 学习主线:漫反射(墙壁、纸张等粗糙面)→ 高光(金属、塑料等镜面感)→ 综合模型(环境 + 漫反射 + 高光)→ Unity 内置方向/空间辅助函数减少手写矩阵。
  • 要点:它是工程上可实现的近似,不是唯一真理;Shader 里选对模型、算对空间,比死记名词更重要。

兰伯特漫反射

  • 问题:粗糙面各向反射较均匀,如何用简单式子表达「朝灯亮、背灯暗」?
  • 分析:漫反射强度由 法线与光源方向夹角 决定,夹角越小,余弦越大,越亮。背光侧点积为负时需截断,避免「负亮度」。
  • 公式:( \mathbf{n},\mathbf{l} ) 取单位向量,点积即 ( \cos\theta )。

\[
C_d = \mathbf{L} \odot \mathbf{M}_d \cdot \max(0, \mathbf{n}\cdot\mathbf{l})
\]

  • 实践要点Lighting.cginc_LightColor0;平行光方向用 _WorldSpaceLightPos0.xyz 并归一化;法线用 UnityObjectToWorldNormal 转到世界空间;常加 UNITY_LIGHTMODEL_AMBIENT.rgb 打底,避免阴影区死黑。

半兰伯特漫反射

  • 问题:纯兰伯特背光面可整块为 0,卡通、插画需要背光仍有灰阶。
  • 分析:在 观感 上做文章,把 ( \mathbf{n}\cdot\mathbf{l}\in[-1,1] ) 线性映射到 ( [0,1] ),声称比兰伯特更物理。
  • 公式

\[
C_d^{\mathrm{half}} = \mathbf{L} \odot \mathbf{M}_d \cdot \left(\frac{\mathbf{n}\cdot\mathbf{l}}{2}+\frac{1}{2}\right)
\]

Phong 式高光反射

  • 问题:镜面感来自「视线是否对准反射光方向」,如何量化?
  • 分析:先算反射方向 ( \mathbf{r}=\mathrm{reflect}(-\mathbf{l},\mathbf{n}) ),再看 ( \mathbf{v} ) 与 ( \mathbf{r} ) 是否接近;用 pow 抬指数 ( n ) 控制高光锐利度。
  • 公式

\[
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})
\]

  • 实践要点reflect 的入射方向与「光从哪来」符号约定要一致(常用 -光源方向);视角方向由 _WorldSpaceCameraPos 与顶点世界坐标构造并归一化。

Blinn-Phong 式高光反射

  • 问题:每像素算 reflect 略繁,且 Phong 高光在部分角度偏「硬」。
  • 分析:用 半角向量 ( \mathbf{h}=\mathrm{normalize}(\mathbf{v}+\mathbf{l}) ) 代替反射方向,看 ( \mathbf{n} ) 与 ( \mathbf{h} ) 是否接近共线;通常 更快、高光略柔和
  • 公式

\[
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 光照模型(完整)

  • 综合:环境光 + 兰伯特漫反射 + Phong 高光,三者 颜色相加(向更亮方向叠加,符合直觉上的多光源贡献)。
  • 公式

\[
C = C_{\mathrm{amb}} + C_d^{\mathrm{Lambert}} + C_s^{\mathrm{Phong}}
\]

  • 环境光UNITY_LIGHTMODEL_AMBIENT,或在 Lighting 里用天空盒、渐变、unity_AmbientSky 等;漫反射、高光项同前。

Blinn-Phong 光照模型(完整)

  • 综合:与 Phong 相同的三项结构,仅把高光换成 Blinn-Phong 项;实时渲染里很常见。
  • 公式

\[
C = C_{\mathrm{amb}} + C_d^{\mathrm{Lambert}} + C_s
\]

其中 ( C_s ) 按 Blinn-Phong 高光 式计算(半角向量版)。

光照模型对照表

名称 核心思路 公式骨架 关键参数与特点
兰伯特漫反射 法线与光方向夹角越小越亮 ( \mathbf{L}\odot\mathbf{M}_d\cdot\max(0,\mathbf{n}\cdot\mathbf{l}) ) 世界空间法线、光向;背光可全黑
半兰伯特 点积映射到 ( [0,1] ),背光有层次 上式中把 ( \max(0,\cdot) ) 换为 ( \frac{\mathbf{n}\cdot\mathbf{l}}{2}+\frac{1}{2} ) 风格化友好,非能量守恒物理模型
Phong 高光 视线与反射方向对齐程度 ( \propto \max(0,\mathbf{v}\cdot\mathbf{r})^{n} ) reflect(-光向, 法线);( n ) 越大越尖
Blinn-Phong 高光 法线与半角对齐程度 ( \propto \max(0,\mathbf{n}\cdot\mathbf{h})^{n} ) reflect,常更快、略柔和
Phong 光照模型 环境 + 兰伯特 + Phong 高光 三项相加 经典完整模型
Blinn-Phong 光照模型 环境 + 兰伯特 + Blinn-Phong 高光 三项相加 游戏与引擎中更常用
  • 名词分清:「Phong/Blinn-Phong 高光」只负责镜面项;「Phong/Blinn-Phong 光照模型」指 整碗汤(环境 + 漫反射 + 高光)。
  • 效率:同条件下 Blinn-Phong 高光常省掉显式反射向量,更适合逐像素计算密集的实时场景。

逐顶点与逐片元光照

  • 类比:顶点光照像在 几个角 算好明暗再插值涂满三角面,省算力但易糊;片元光照是 每个像素 用自身插值后的法线、位置再算,更准更贵。
  • 原因:顶点间颜色由光栅化 插值 得到,无法表现细尺度明暗;片元阶段可再用高精度法线(如法线贴图)参与计算。
  • 性能:顶点着色器按顶点计费,片元着色器按覆盖像素计费;同模型下移计算到片元通常更耗。

Unity 内置常用函数(UnityCG.cginc

  • 作用:统一处理「从模型空间顶点出发」的观察方向、光照方向与矩阵变换,减少手写出错。
  • 观察方向WorldSpaceViewDir(v)(输入模型空间顶点)、UnityWorldSpaceViewDir(v)(输入世界空间顶点)、ObjSpaceViewDir(v)(模型空间方向)。
  • 光照方向(Forward 渲染)WorldSpaceLightDir(v)UnityWorldSpaceLightDir(v)ObjSpaceLightDir(v);返回值 **常需 normalize**,且与管线版本、宏有关,以工程实际 include 为准。
  • 空间与裁剪UnityObjectToWorldNormalUnityObjectToWorldDirUnityWorldToObjectDirUnityObjectToClipPos

纹理

纹理与 UV 在干什么

  • 问题:模型只有几何,如何贴上「皮」?
  • 分析:美术在 DCC 里为顶点写入 UV;GPU 光栅化时对 UV 插值,片元里用 tex2D 取色。UV 一般归一化到 ( [0,1] ),与纹理分辨率无关。
  • 实践Properties 声明 2D,CG 中 sampler2D _MainTexfloat4 _MainTex_ST(xy 缩放、zw 偏移);顶点里 uv = texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zwTRANSFORM_TEX

导入设置:Wrap 与 Filter

  • Wrap ModeRepeat 像瓷砖重复;Clamp 钳住边缘防绕回;还有镜像等变体,按美术需求选。
  • Filter ModePoint 硬边像素风;Bilinear / Trilinear 缩放更柔,常配合 Mipmap 减闪烁与走样。

单张纹理 + Blinn-Phong

  • 问题:贴图颜色与光照如何合成才不假灰、不假白?
  • 分析:把采样结果当作 反照率 albedoalbedo = texColor × 漫反射色;兰伯特项用 albedo;环境光也乘 albedo,避免「环境一块灰蒙在模型上」。
  • 综合最终 ≈ 环境光×albedo + 漫反射项 + Blinn-Phong 高光项(与系列课文一致即可)。

凹凸纹理(法线贴图)

  • 问题:不加三角面,如何做出细小凹凸?
  • 分析:用贴图存 扰动后的法线,光照仍按新法线算,眼睛感到起伏。高度图 灰度存高度,常需额外求导变正法线,开销大;法线贴图 直接存法线向量更常用。
  • 空间选择切线空间 法线偏蓝紫,易复用到不同朝向表面;模型空间 法线彩色、直观但换模型常要重烘焙。世界空间 算法线光照利于点光等,但矩阵与变体更多。
  • 实践套路appdata_full 带切线;副切线 bitangent = cross(n, t) * tangent.w;构建 TBNUnpackNormal 解码;_BumpScale 控制强度。切线空间算法:光向、视向转到切线空间再 dot;世界空间算法:法线转到世界空间再与光向、半角算。

渐变纹理(Ramp)

  • 问题:如何把连续明暗变成 色带、插画感
  • 分析:用半兰伯特标量 ( t=\frac{\mathbf{n}\cdot\mathbf{l}}{2}+\frac{1}{2}\in[0,1] ) 当作 UV(如 float2(t,t))采样 _RampTex,用纹理颜色 重映射 明暗,而非直接用标量当亮度。
  • 实践:渐变图 Wrap Mode 建议 Clamp,避免浮点误差在 Repeat 下绕一圈采到缝上的 黑点。与凹凸结合时:在切线空间 Shader 上把漫反射项替换为「半兰伯特 → Ramp → 乘光色与 albedo」,高光仍可保留 Blinn-Phong。

遮罩纹理

  • 问题:同一材质上,有的区域要更强高光、有的区域要压住特效?
  • 分析:用贴图某一通道(如 R)作 局部权重,再乘自定义系数 _SpecularScale,最后乘进高光项。RGBA 四路可分别存高光、透明、特效等,减少贴图张数。

透明

前置概念:队列、深度、测试、混合

  • **渲染队列 Queue**:决定大致绘制顺序;透明物体通常排在不透明之后,才能读到背后颜色做混合。
  • 深度缓冲:每像素记「目前最近深度」;深度测试决定新片元是否通过;混合决定通过后的颜色如何与颜色缓冲已有值合成。
  • 直觉:不透明物体常开深度写入,顺序不敏感;半透明常 ZWrite 才能混合背后,但引入 排序敏感(前后穿插时可能错)。

深度写入、队列与混合(Shader 里怎么写)

  • **ZWrite**:写在 Pass 内,只影响该 Pass。半透明 Pass 常见 ZWrite Off
  • **QueueRenderType**:写在 SubShaderTags,影响其下所有 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 可分别指定因子;具体以目标平台文档为准):

\[
O_{\mathrm{rgb}} = F_s \cdot S_{\mathrm{rgb}} + F_d \cdot D_{\mathrm{rgb}}
\]

常见 透明度混合Blend SrcAlpha OneMinusSrcAlpha,即

\[
\mathbf{C}_{\mathrm{out}} = \alpha \mathbf{C}_S + (1-\alpha)\mathbf{C}_D
\]

透明度测试(Alpha Test)

  • 场景:树叶、栅栏、草等 镂空,不要真半透明。
  • 做法clip(texColor.a - _Cutoff),低于阈值直接丢弃片元;通过的可按不透明写深度。Queue=AlphaTestRenderType=TransparentCutout不必关深度写入。

透明度混合

  • 场景:玻璃、水、特效半透明层。
  • 做法Queue=TransparentZWrite OffBlend SrcAlpha OneMinusSrcAlpha;返回颜色的 alpha 常用 texColor.a * _AlphaScale。注意整体渲染顺序与穿插。

双 Pass:先钉深度再混合

  • 问题:复杂网格自穿插时,单纯关 ZWrite 易导致片元顺序错乱。
  • 解决:第一 Pass ZWrite OnColorMask 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,整块背光可显得死黑。
  • 半兰伯特:把 (\mathbf{n}\cdot\mathbf{l}) 从 ([-1,1]) 线性映射到 ([0,1]),背光仍有明暗渐变,利于卡通、手绘感。
  • 物理性:半兰伯特是视觉近似,不是能量守恒的物理模型;面试里要能说清「为什么好看」和「为什么不等于真实漫反射」。
答题示例

兰伯特用 (\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})。
  • Blinn-Phong:用半角向量 (\mathbf{h}=\mathrm{normalize}(\mathbf{v}+\mathbf{l})),高光项看 (\mathbf{n}\cdot\mathbf{h})。
  • 工程上:避免显式求反射向量、高光形状往往更稳;代价是「在相同指数 (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

题目

用半兰伯特标量去采样渐变纹理做卡通明暗时,为什么常把渐变纹理设为 ClampRepeat 下会出现什么现象?

深入解析
  • 半兰伯特输出:理论在 ([0,1]),浮点误差可能略大于 1 或略小于 0。
  • Repeat:UV 取小数部分,略大于 1 会绕回纹理左侧,出现错误条带或黑点。
  • Clamp:越界钳在 0 或 1,明暗稳定在条带两端;与渐变纹理「一维查找表」语义一致。
答题示例

半兰伯特算出来应该是 0~1,但浮点会有 1.0001 这种。Repeat 会取小数部分,采样会跳到纹理另一端,出现噪点或黑条。Clamp 把坐标钉在 0~1 边界,卡通 ramp 一般都用它。

参考文章
  • 31.纹理-渐变纹理-基本概念
  • 32.纹理-渐变纹理-基础实现


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

×

喜欢就点赞,疼爱就打赏