27.Shader语法基础总结

27.Shader语法基础总结


27.1 核心要点速览

材质和Shader

  • Shader vs Unity Shader:Shader 是通用渲染程序,Unity Shader 是基于 ShaderLab 的封装实现
  • 使用流程:创建 Material → 选用/创建 Unity Shader → 应用到对象 → 在 Inspector 面板调整属性
  • 创建材质:Project 窗口右键 Create → Material;在 Inspector “Shader” 下拉选择;编辑下方暴露属性,无需改代码
  • 创建 Shader 模板:Standard Surface、Unlit(重点学顶点/片元)、Image Effect、Compute、Ray Tracing
  • Inspector 关键设置:Default Maps(默认纹理)、Keywords(功能开关)、Properties(面板属性)、Cast Shadows、Render Queue、LOD、Batching
  • 核心要点:材质是使用 Shader 的必要桥梁,通过材质面板即可灵活调控渲染效果,无需修改底层 Shader 代码

ShaderLab语法

ShaderLab基本结构

  • 什么是 ShaderLab:Unity 自定义的着色器描述语言,用于结构化组织和管理各种类型的 Shader
  • 四大组成
    • Shader "名称":声明着色器名称
    • Properties { … }:定义在材质面板可调的属性
    • 1~n 个 SubShader { … }:包含顶点/片元或表面/固定函数着色器,按设备能力降级
    • Fallback "备用Shader":指定不支持时的替代实现
  • 默认 NewSurfaceShader 示例
    • Properties:_Color_MainTex_Glossiness_Metallic
    • SubShader:#pragma surface surf Standard 定义标准光照模型,支持 Instancing
    • 可通过 Inspector “Compile and show code” 查看生成的底层代码
  • 核心要点:ShaderLab 提供统一框架,无需手写所有底层细节,即可管理属性、兼容多种渲染通道和设备。

Shader的名字

  • 四大结构定位:ShaderLab 由“名字、Properties、1~n 个 SubShader、Fallback”四部分组成
  • 名称作用:决定材质面板中的层级路径,方便查找和管理
  • 命名规则
    • 禁用中文,保持文件名与声明一致
    • 使用分级格式,如 Shader "ShaderTeach/Lesson03_NewUnlitShader"
  • 修改方式:直接在 .shader 文件中编辑 Shader "..." 后的字符串

Shader的属性

  • 作用:在材质面板暴露可调参数,作为子着色器输入
  • 基本语法
    _Name("Display Name", type) = defaultValue[{options}]
    
  • 三大类型
  • 数值:Int、Float、Range(min,max)
  • 颜色/向量:Color(RGBA)、Vector(XYZW)
  • 纹理:2D、2DArray、Cube、3D
  • 默认值与选项:常用默认纹理 white/black/gray/bump/red;{} 固定写法
  • 核心要点:只需在 Properties 块声明即可,运行时通过 Inspector 灵活调节,无需修改底层 Shader 代码

Shader的子着色器基本构成

  • SubShader 作用:包含至少一个 SubShader,Unity 会选择第一个与当前 GPU 兼容的执行

  • 三大要素

    1. 渲染标签(Tags):控制渲染条件与顺序,如 Tags { "RenderType"="Opaque" }
    2. 渲染状态(States):设置剔除、深度测试、混合模式、LOD 等,如 LOD 100
    3. 渲染通道(Pass):每个 Pass 执行一次渲染,内含顶点/片段程序或表面着色器
  • 多 SubShader 策略:通过多个 SubShader 兼容不同设备,确保高级效果与降级支持

  • 性能建议

    • 尽量减少 Pass 数量,避免多次渲染开销
    • 在 SubShader 中仅包含必要标签与状态,简化执行路径
Tags 渲染标签
  • 作用:通过键值对控制 SubShader 的渲染顺序、类型与行为,是 Unity 与渲染管线的通讯桥梁
  • 基本语法
Tags{ "标签名1" = "标签值1" "标签名2" = "标签值2" "标签名2" = "标签值2" .......}
  • RenderQueue(Queue):设置渲染队列顺序
  • Background (1000)、Geometry (2000)、AlphaTest (2450)、Transparent (3000)、Overlay (4000)
  • 自定义(如 "Geometry+1" = 2001,"Transparent-1" = 2999)
  • RenderType:分类着色器,用于后续替换
  • 常用:Opaque、Transparent、TransparentCutout、Background、Overlay
  • DisableBatching:控制是否禁用批处理
  • "True"(总是禁用)、"False"(默认)、"LODFading"(LOD 激活时禁用)
  • ForceNoShadowCasting:是否投射阴影
  • "False"(默认投射)、"True"(不投射)
  • IgnoreProjector:是否受 Projector 影响
  • "False"(默认)、"True"(忽略,一般半透明开启)
  • 其他常见标签
  • CanUseSpriteAtlas(精灵使用)、PreviewType(Panel/SkyBox)
  • 注意:仅在 SubShader 级别声明,Pass 中有专用标签,与这里分开使用
States渲染状态
  • 作用:通过关键字控制剔除、深度写入/测试、混合等底层渲染行为,影响最终像素输出
  • 基本语法
LOD 100
  • Cull(剔除)Cull Back(背面)、Cull Front(正面)、Cull Off(双面)
  • 深度缓冲(ZWrite)ZWrite On(写入)、ZWrite Off(不写入,用于透明效果)
  • 深度测试(ZTest):比较深度缓冲与当前片元
    • 常用:LEqual(≤ 默认)、Less(<)、Greater(>)、Always(始终)
  • 混合(Blend):控制颜色叠加
    • Blend SrcAlpha OneMinusSrcAlpha(标准透明)、Blend One One(线性减淡)等
  • 其他常用状态
    • LOD <等级>:层级细节切换
    • ColorMask RGBA/掩码:选择性写入颜色通道
  • 声明位置
    • 在 SubShader 级影响所有 Pass;在 Pass 级仅作用于当前通道
Pass渲染通道
  • SubShader vs Pass:SubShader 是兼容层级,一组完整渲染设置;Pass 是具体渲染步骤,可多次执行以叠加效果
  • Pass 结构
    1. Name:用于 UsePass 复用(Unity 会转为大写)
    2. 渲染标签(仅限 Pass):如 Tags{"LightMode"="ForwardBase"}"RequireOptions""PassFlags"
    3. 渲染状态:与 SubShader 相同,但仅影响当前通道
    4. 着色器逻辑:CG/HLSL 顶点与片元程序
  • 复用与抓取
    • UsePass "ShaderPath/PASSNAME" 引用其它 Shader 中的 Pass
    • GrabPass { "_BackgroundTexture" } 抓取屏幕内容供后续 Pass 使用
  • 核心要点:Pass 是渲染管线中的最小执行单元,通过合理命名、标签与状态设置,可以实现阶段性或条件性渲染及代码复用。

Shader的备用着色器

  • 作用:当所有 SubShader 不被当前硬件支持时,提供最低级别的渲染保障,让对象至少能够显示
  • 语法
    • Fallback "ShaderName":指定备用 Shader(如 "VertexLit"
    • Fallback Off:关闭备用机制(对象可能无法渲染)
  • 位置:紧跟在所有 SubShader 块之后
  • 核心要点:用简化的内置 Shader 作为“救命稻草”,确保在低端设备上也能正常显示物体

着色器类型

表面着色器

  • 定义:Unity 封装顶点/片元的高层 Shader 形式,代码写在 SubShader 的 CGPROGRAM…ENDCG 区块,用 #pragma surface 指令驱动
  • 位置:直接在 SubShader 块中,无需单独 Pass,简化写法
  • 优点:自动处理物理光照、阴影、GI 等细节,代码量少,上手快
  • 缺点:性能开销大、可控性低,难以做细粒度优化
  • 典型结构
    • Properties 定义外部参数(颜色、贴图、光滑度、金属度)
    • #pragma surface surf Standard fullforwardshadows 指定光照模型
    • void surf(Input IN, inout SurfaceOutputStandard o) 填充输出 o.Albedo, o.Metallic, o.Smoothness, o.Alpha
  • 适用场景:需要快速实现多光源物理光照效果的 PC/主机平台 Shader,移动平台需评估性能代价

顶点/片元着色器

  • 定义:直接在 Pass 中编写顶点 (vert) 和片元 (frag) 着色器,使用 #pragma vertex#pragma fragment 指令
  • 结构
    • 在 SubShader → Pass → CGPROGRAM…ENDCG 区块内
    • 自行包含顶点输入 (appdata)、中间结构 (v2f)、纹理采样与雾处理宏
  • 优点
    • 最大灵活性,可精确控制渲染状态、管线阶段与性能
    • 可实现自定义光照、后处理与特殊效果
  • 缺点
    • 代码量大,需要手动管理多个 Pass、状态与内置宏
  • 适用场景:移动平台首选、自定义渲染管线、对性能与特效有严格要求的 Shader

固定函数着色器

  • 定义:基于固定管线的 legacy Shader,仅用 ShaderLab 命令(Lighting、Color、Material、SetTexture)写在 Pass 中,无需 CG/HLSL
  • 特点
    • 适用于不支持可编程管线的极旧设备(DX7/OpenGL1.x)
    • 只能实现最简单的颜色与纹理效果
    • Unity 内部仍会编译为顶点/片元着色器,真·固定函数已不存在
  • 常用命令
    • Lighting on/off 控制光照
    • ColorColor[_Property] 设置纯色
    • Material{ Diffuse[_Color] } 打开漫反射
    • SetTexture[_MainTex]{ Combine texture } 应用纹理
  • 应用建议
    • 基本弃用,仅做了解
    • PC/主机用表面着色器;移动与自定义效果用顶点/片元

CG语句

CG语句写在哪里

  • 位置:所有 CG/HLSL 代码必须放在 Pass 块内的 CGPROGRAM … ENDCG 区间
  • 编译指令
    • #pragma vertex 函数名 指定顶点着色器入口
    • #pragma fragment 函数名 指定片元着色器入口
  • 常用宏与包含
    • #pragma multi_compile_fog 支持多种雾效编译
    • #include "UnityCG.cginc" 引入常用 Unity 着色器函数与宏
  • 函数结构
    • 定义 struct appdata(顶点输入)、struct v2f(片元输入)
    • 实现 v2f vert(appdata v)fixed4 frag(v2f i) : SV_Target
  • 核心要点:CGPROGRAM 块内声明编译指令并编写顶点/片元函数,是自定义渲染逻辑的唯一入口

CG基础数据类型

  • 基本类型

    • 整型:int(32 位)、uint(32 位无符号)
    • 浮点:float(32 位)、half(16 位)、fixed(12 位)
    • 逻辑与特殊:bool、(string 虽示例,但 HLSL/Cg 不支持)
  • 纹理采样器

    • 通用 samplersampler1Dsampler2Dsampler3DsamplerCUBEsamplerRECT
  • 数组

    • 声明类似 C#:int a[4] = {…}int b[2][3] = {{…},{…}}
    • 无内建长度属性,需手动维护长度变量并遍历
  • 结构体

    • 语法近 C#,无访问修饰符,声明末尾加分号
    • 可在函数外定义,按字段访问与赋值
  • 核心要点:CG 类型与 C# 类似,差异在于更细粒度的浮点分类(half、fixed)、丰富的 sampler 类型,以及数组需手动管理长度。

CG特殊数据类型

  • 向量
    内置类型,基于基础数据类型(如float、fixed等),最大维度4维。声明格式为“数据类型+维度”,如float2 vec2 = float2(1.0, 2.0)int4 vec4 = int4(1,2,3,4)

  • 矩阵
    内置类型,行列数范围1-4,基于基础数据类型。声明格式为“数据类型+n×m”,如half2x2 mat2x2 = half2x2(1.0h,2.0h,3.0h,4.0h)int4x4 mat4x4 = int4x4(...),赋值时需注意行列关系,建议换行增强可读性。

  • bool类型特殊使用
    可像向量一样声明(如bool3),用于存储向量比较结果。例如half3 a, b; bool3 c = a < b,结果为对应分量比较的bool向量(如bool3(true, false, false))。

  • 核心要点:向量最大4维,矩阵行列≤4且≥1;bool向量用于存储向量比较结果;向量和矩阵是内置类型,与数组(数据结构)不同。

CG的Swizzle操作符

  • 定义:用于获取向量元素的操作符,以点号(.)形式使用,四维向量可通过 .xyzw(坐标)或 .rgba(颜色)表示分量。

  • 用法

    1. 提取分量:如 fixed4 f4 = fixed4(1,2,3,4); fixed f = f4.w;(或 f4.a,均取第四个元素)。
    2. 重新排列分量:如 f4 = f4.yzxw(重排为原y、z、x、w)、f4 = f4.abgr(重排为原a、b、g、r)。
    3. 创建新向量:如 fixed3 f3 = f4.xyz(取前三维)、fixed2 f2 = f3.xz(取x和z)、fixed4 f4_2 = fixed4(f2, f2)(组合为xzxz)。
  • 向量与矩阵的扩展用法

    • 用向量声明矩阵:如 fixed4x4 f4x4 = {fixed4(1,2,3,4), ...}(每行用向量初始化)。
    • 获取矩阵元素:类似二维数组,如 f4x4[0][0](第一行第一列)。
    • 向量获取矩阵行:如 f4_2 = f4x4[3](取第四行)。
    • 高维转低维:如 fixed3 f3 = f4(自动舍弃f4的第四个元素)、fixed3x3 f3x3 = f4x4(取f4x4前三行前三列)。
  • 核心要点:Swizzle操作符简化向量元素的提取、重排与新向量创建;矩阵元素获取类似二维数组,向量与矩阵可配合使用,高维可自动转为低维(舍弃多余元素)。

CG运算符相关

  • 比较运算符
    包括>、<、>=、<=、==、!=,用法同C#,运算结果为bool值。

  • 条件运算符(三元运算符)
    格式为condition ? value_if_true : value_if_false,用法与C#一致,根据条件返回对应值。

  • 逻辑运算符
    包括||(或)、&&(与)、!(非),用法同C#,但无C#中的“短路”操作(即两边表达式都会执行)。

  • 数学运算符
    包括+、-、*、/、%(取余)、++、–,用法同C#,但取余仅能对整数操作

  • 核心要点:CG运算符基本用法与C#一致,差异在于逻辑运算符无短路操作,数学取余仅限整数。

CG流程控制语句

  • 条件分支语句
    包括if语句和switch语句,用法与C#完全一致。

    • if语句:通过条件判断执行不同代码块(如if (f1 < f2) { ... } else { ... })。
    • switch语句:根据变量值匹配case执行对应逻辑(需注意类型转换,如switch ((int)fSwitch))。
  • 循环语句
    包括for、while、do while循环,用法同C#。

    • for循环:如for (int i = 0; i < 3; i++) { ... },适合已知循环次数的场景。
    • while循环:先判断条件再执行(while (count < 3) { ... })。
    • do while循环:先执行一次再判断条件(do { ... } while (count < 3))。
  • 性能注意事项

    1. 尽量减少循环使用,如需使用需降低次数和复杂度。
    2. 利用GPU并行性替代循环。
    3. 避免复杂的条件分支,减少性能消耗。

CG函数

  • 无返回值函数
    结构:void 函数名(in 参数类型 输入参数, out 参数类型 输出参数) { ... }

    • in:输入参数,外部传入,内部仅使用不修改,可多个。
    • out:输出参数,内部必须初始化/修改,结果返回给调用者,可多个。
    • 建议保留in/out以明确参数传递方式,提升可读性。
      示例:void test(in fixed inF, out fixed outF) { outF = inF + 10; }
  • 有返回值函数
    结构:返回类型 函数名(in 参数类型 输入参数) { ... return 返回值; }

    • 顶点/片元着色器常用单返回值形式,不建议混合使用out参数(特殊逻辑除外)。
      示例:float test2(in float inF, out fixed f) { f = inF + 2; return inF * 2; }
  • 关键字补充

    • inout:输入输出参数,兼具in(外部传入)和out(内部可修改,结果保留)特性,内部可修改且修改后对外部可见。
  • 核心要点:CG函数语法近C#,核心差异在于in(输入)、out(输出)、inout(输入输出)参数修饰符,需明确参数交互方式;有返回值函数通常用单返回值,减少out混用。

CG顶点片元着色器基本结构

  • 基本框架
    基础结构包含Shader块(定义 shader 名称)、Properties块(可空)、SubShader块及内部的Pass块,核心逻辑在CGPROGRAMENDCG之间编写。

  • 顶点着色器

    • 编译指令:#pragma vertex 函数名(如#pragma vertex myVert)指定顶点着色器函数。
    • 函数结构:float4 函数名(float4 v:POSITION):SV_POSITION { ... }
      • POSITION语义:输入参数v接收模型空间顶点坐标。
      • SV_POSITION语义:返回裁剪空间坐标。
    • 核心功能:将模型空间坐标转换为裁剪空间,通过UnityObjectToClipPos(v)实现(替代旧版mul(UNITY_MATRIX_MVP, v))。
  • 片元着色器

    • 编译指令:#pragma fragment 函数名(如#pragma fragment myFrag)指定片元着色器函数。
    • 函数结构:fixed4 函数名():SV_Target { ... }
      • SV_Target语义:将返回的颜色输出到默认帧缓存。
    • 核心功能:计算每个片元的颜色,示例返回绿色(fixed4(0,1,0,1))。
  • 关键语义作用
    语义(如POSITIONSV_POSITIONSV_Target)用于告诉渲染器如何处理输入输出数据,确保数据流转正确。

CG语义

  • 作用
    修饰函数参数和返回值,告知Shader数据的读取来源与输出去向,确保数据正确传递。Unity仅支持CG中的部分语义。

  • 常用语义分类

    • 应用阶段→顶点着色器(顶点着色器输入参数):

      • POSITION:模型空间顶点位置(通常float4)。
      • NORMAL:顶点法线(通常float3)。
      • TANGENT:顶点切线(通常float4)。
      • TEXCOORDn(如TEXCOORD0、TEXCOORD1):顶点纹理坐标(UV,通常float2/float4,n表示组别)。
      • COLOR:顶点颜色(通常fixed4/float4)。
    • 顶点着色器→片元着色器(顶点着色器返回值):

      • SV_POSITION:裁剪空间顶点坐标(必备,必须包含)。
      • COLOR0/COLOR1:第一/二组顶点颜色输出(非必需)。
      • TEXCOORD0~TEXCOORD7:纹理坐标输出(非必需)。
    • 片元着色器输出(片元着色器返回值):

      • SV_TARGET:输出颜色至渲染目标(如默认帧缓存)。
  • 核心要点:需熟记各阶段常用语义,确保数据在Shader各环节正确传递,是编写顶点/片元着色器的基础。

CG顶点片元着色器传递更多参数

  • 核心方式:通过结构体封装数据,利用语义修饰结构体成员,实现多参数在应用阶段→顶点着色器→片元着色器之间的传递。

  • 结构体定义与作用

    • a2v结构体(应用阶段→顶点着色器)
      封装从应用阶段获取的模型数据,成员用对应语义修饰,供顶点着色器读取。
      示例:

      struct a2v {
          float4 vertex : POSITION; // 模型空间顶点位置
          float3 normal : NORMAL;   // 顶点法线
          float2 uv : TEXCOORD0;    // 纹理坐标(UV)
      };
      
    • v2f结构体(顶点着色器→片元着色器)
      封装顶点着色器处理后的数据,成员用语义修饰,作为顶点着色器返回值,供片元着色器接收。
      示例:

      struct v2f {
          float4 position : SV_POSITION; // 裁剪空间坐标
          float3 normal : NORMAL;        // 传递的顶点法线
          float2 uv : TEXCOORD0;         // 传递的纹理坐标
      };
      
  • 传递流程

    1. 顶点着色器以a2v为参数,获取应用阶段数据(如data.vertex)。
    2. 顶点着色器处理数据后,存入v2f结构体并返回(如v2fData.position = UnityObjectToClipPos(data.vertex))。
    3. 片元着色器以v2f为参数,接收传递的多参数(如data.uv)。
  • 注意事项
    仅顶点/片元着色器的回调函数相关参数和返回值需语义修饰,自定义函数无需(因参数作用明确)。

CG变量和ShaderLab属性的匹配

  • ShaderLab属性类型分类

    • 数值型:IntFloatRange(min,max)
    • 颜色/向量型:Color(RGBA,0~1)、Vector(XYZW,无范围限制)。
    • 纹理型:2D2DArrayCube3D(后两者不常用)。
  • 属性与CG变量类型对应关系

    ShaderLab属性类型 CG变量类型
    Color、Vector float4、half4、fixed4
    Range、Float、Int float、half、fixed
    2D sampler2D
    Cube samplerCube
    3D sampler3D
    2DArray sampler2DArray
  • CG中使用ShaderLab属性的方法
    在CG代码块中,声明与属性同名且类型匹配的变量,即可直接使用该属性值。
    示例:

    // Properties中声明
    _MyColor("MyColor", Color) = (1,1,1,1)
    // CG中声明并使用
    float4 _MyColor; 
    fixed4 frag() : SV_Target { return _MyColor; }
    
  • 核心要点:掌握属性类型与CG变量的对应关系,通过同名变量实现属性在CG逻辑中的调用,是Shader交互(如材质面板调整参数)的基础。

CG内置函数

  • 定义:CG语言中封装的图形编程函数,用于简化Shader开发中的常见计算(如数学运算、几何处理、纹理采样等)。

  • 主要分类及核心函数

    • 数学函数

      • 三角函数:sincos(x, out s, out c)(同时求sin和cos,效率高)、sin(x)cos(x)atan2(y,x)(求y/x的反正切)。
      • 向量/矩阵运算:cross(A,B)(三维向量叉乘)、dot(A,B)(三维向量点乘)、mul(M,N)(矩阵相乘)、mul(M,v)(矩阵与向量相乘)、transpose(M)(矩阵转置)。
      • 数值处理:abs(x)(绝对值)、clamp(x,a,b)(夹紧在[a,b]区间)、lerp(a,b,f)(插值计算(1-f)a + fb)、max(a,b)/min(a,b)(最值)、saturate(x)(限制在[0,1])、smoothstep(min,max,x)(平滑过渡,返回0~1)。
      • 其他:lit(NdotL,NdotH,m)(计算环境光、散射光、镜面光贡献)、noise(x)(噪声函数,返回0~1)。
    • 几何函数

      • length(v)(向量模长)、normalize(v)(向量归一化)、distance(p1,p2)(两点距离)、reflect(I,N)(反射光方向,I和N需归一化)、refract(I,N,eta)(折射方向,eta为折射系数)。
    • 纹理函数(返回fixed4颜色):

      • 二维纹理:tex2D(sampler2D tex, float2 s)(基础2D纹理采样,常用)、tex2Dproj(投影纹理采样)。
      • 立方体纹理:texCUBE(samplerCUBE tex, float3 s)(立方体贴图采样)。
      • 其他:tex1D(1D纹理)、tex3D(3D纹理)、texRECT(矩形纹理)等采样函数。
  • 核心要点:内置函数简化了图形计算,需掌握常用函数(如tex2Dlerpdotreflect)的用法;CG函数与HLSL类似,部分函数在Unity中可能不支持,可参考HLSL文档。

CG内置文件

  • 位置与作用
    位于Unity安装目录的Editor/Data/CGIncludes,后缀为.cginc,是预定义的Shader逻辑文件,包含函数、宏、结构体等,用于提升Shader开发效率。常用文件:

    • UnityCG.cginc:含常用函数、宏、结构体。
    • Lighting.cginc:内置光照模型,Surface Shader自动包含。
    • UnityShaderVariables.cginc:自动包含,含全局变量。
    • HLSLSupport.cginc:自动包含,跨平台编译宏定义。
  • 使用方法
    通过#include "文件名.cginc"在CG代码块中引用(建议显式引用避免报错),即可使用其中内容。

  • 核心内容

    • 方法(UnityCG.cginc)

      • 方向计算:WorldSpaceViewDir(v)(模型空间顶点到世界空间观察方向)、ObjSpaceViewDir(v)(模型空间观察方向)、WorldSpaceLightDir(v)(世界空间光照方向,前向渲染用)。
      • 空间转换:UnityObjectToWorldNormal(norm)(模型空间法线转世界空间)、UnityObjectToWorldDir(dir)(模型空间方向转世界空间)。
    • 结构体(UnityCG.cginc)

      • 顶点输入:appdata_base(顶点位置、法线、第一组UV)、appdata_tan(加切线)、appdata_full(多组UV)、appdata_img(仅位置和UV)。
      • 顶点输出:v2f_img(裁剪空间位置、UV)。
    • 变换矩阵宏(UnityShaderVariables.cginc)

      • 坐标转换:UNITY_MATRIX_MVP(模型×观察×投影矩阵,模型→裁剪空间)、unity_ObjectToWorld(模型→世界空间)、unity_WorldToObject(世界→模型空间)等。
    • 常用变量

      • _Time:自加载起的时间(t/20、t、t×2、t×3),用于动画。
      • _LightColor0:光源颜色(前向渲染需引对应文件)。
  • 示例
    引用UnityCG.cginc后,可直接使用appdata_basev2f_img结构体简化顶点/片元着色器代码,通过mul(unity_ObjectToWorld, v.vertex)将模型空间顶点转世界空间。



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

×

喜欢就点赞,疼爱就打赏