Shader Feature 笔记
Feature
函数值收敛
saturate(x) 如果 x 小于0,返回 0;如果 x大于 1,返回1;否则,返回x
参考链接
获取模型中心点世界坐标
unity的世界变化矩阵最后一列是存的Transform里的Position,所以我们可以在shader里提取这部分数据做一些计算,下面是unity支持的几种写法:
1 | float3 center = float3(unity_ObjectToWorld[0].w, unity_ObjectToWorld[1].w, unity_ObjectToWorld[2].w); |
调用 LightMap 光照贴图
1 |
|
UNITY_SETUP_INSTANCE_ID
在 Unity 着色器编程中,UNITY_SETUP_INSTANCE_ID
宏是一个内置的预处理器指令,可用于检索当前正在渲染的对象的实例 ID。实例 ID 是分配给 Unity 中 GameObject 或 MeshRenderer 的每个实例的唯一标识符。
UNITY_SETUP_INSTANCE_ID
宏通常用于顶点着色器,以在使用相同着色器渲染多个对象时区分各个实例。它允许您执行特定于实例的计算或将每个实例的数据或变化应用到顶点或材质。
当在着色器中使用 UNITY_SETUP_INSTANCE_ID
宏时,Unity 会自动生成必要的代码以提供实例 ID 作为名为 unity_InstanceID
的内置变量。然后可以在着色器中使用此变量来访问每个实例的数据,例如每个实例的颜色、纹理或转换。
以下是如何在顶点着色器中使用 UNITY_SETUP_INSTANCE_ID
宏的示例:
1 | #pragma vertex vert |
在上面的示例中,UNITY_SETUP_INSTANCE_ID
宏并没有显式使用,但它在编译着色器时由 Unity 自动扩展。然后在 vert 函数中使用生成的 unity_InstanceID 变量将特定于实例的转换应用于顶点。
通过利用 UNITY_SETUP_INSTANCE_ID
宏,您可以在渲染同一对象的多个实例时在着色器中实现每个实例的自定义和变化。
HLSL noise
在 Unity 的 HLSL 着色器编程中,函数“噪声”是一个生成程序噪声值的内置函数。它通常用于在着色器中创建随机或伪随机图案和纹理。
“噪声”函数根据提供给它的输入坐标生成一个值。它使用噪声算法(例如 Perlin 噪声或 Simplex 噪声)来生成输出。 “噪声”函数使用的确切算法可能因 Unity 版本和平台而异。
下面是如何在着色器中使用“噪声”函数的示例:
1 | float3 位置 = float3(1.0, 2.0, 3.0); |
在上面的示例中,“噪声”函数以位置向量 (1.0, 2.0, 3.0) 作为输入被调用。该函数根据输入坐标生成噪声值并将其分配给变量“noiseValue”。
“噪声”功能可用于创建各种效果,例如程序纹理、地形生成或为着色器计算添加随机性。它可以与其他着色器功能和操作结合使用,以实现所需的视觉效果或程序模式。
请务必注意,“噪声”函数的行为和属性可能因 Unity 版本和您使用的平台而异。因此,建议查阅特定于您的 Unity 版本的 Unity 文档或着色器编程参考,以了解有关“噪声”功能及其具体实现的更多详细信息。
HLSL time.xx
在 HLSL 中是 time.xx ,在 CG 中是 _Time.xx.
在Unity的HLSL着色器编程中,表达式“time.xx”是指访问全局时间变量的X和X分量。
在 Unity 中,全局时间变量表示自应用程序开始运行以来经过的时间。它随着游戏的进行而不断增加,允许您在着色器中创建时间相关的效果。
“time.xx”表达式可用于提取全局时间值的 X 和 X 分量。每个组件代表时间的不同方面:
- X 组件表示自应用程序启动以来的总时间(以秒为单位)。
- Y 分量表示总时间的小数部分。
通过访问“time.xx”的 X 和 X 组件,您可以在着色器计算中使用它们来创建各种时间相关的效果。例如,您可以使用它们来制作纹理动画、控制动画速度、生成随时间变化的程序模式,或创建随时间推移而演变的动态视觉效果。
以下是如何在着色器中使用“time.xx”创建简单动画的示例:
1 | float2 timeValue = time.xx; |
在上面的示例中,“time.xx”被分配给“timeValue”变量,这使您可以访问全局时间的 X 和 X 分量。然后使用这些组件计算“uvOffset”值,该值可用于偏移纹理的 UV 坐标,创建简单的动画效果。
通过使用“time.xx”或其单独的组件,您可以在着色器中引入基于时间的变化和动画,从而在您的 Unity 项目中实现动态和视觉上有趣的效果。
cg reflect
在Unity的Cg语言中,reflect是一个内置函数,用于计算反射向量。它接受两个参数:入射向量(incident vector)和表面法线(surface normal)。
反射向量是指光线(或任何向量)在与表面法线相交的点上,沿着表面的法线方向反射出去的方向向量。当光线与表面发生反射时,它的方向可以通过reflect函数来计算。
reflect函数的使用格式如下:
1 | reflect(incident, normal) |
其中,incident是入射向量,normal是表面法线向量。函数会返回一个反射向量,表示入射向量相对于法线的反射方向。
使用reflect函数可以在着色器中模拟光线与表面的交互,用于计算反射效果或镜面反射效果。在计算光照或阴影的过程中,可以使用reflect函数来确定入射光线的反射方向,以便在光照模型中进行相应的计算。
请注意,reflect函数只计算反射向量的方向,不考虑光线的强度或衰减等因素。在实际应用中,还需要根据光照模型和材质属性等因素来计算最终的光照强度。
_MainTex_ST 等类似的 _NameTex_ST
在Unity中,_MainTex_ST
和类似的命名格式_Name_ST
通常是用于控制纹理坐标的平铺和偏移的属性。
_MainTex_ST
表示用于控制主纹理(Main Texture)的平铺和偏移的属性。这个属性可以用来控制纹理在模型表面的重复、缩放和偏移效果。
_Name_ST
中的Name
是一个自定义的纹理属性名称,可以是任何合法的标识符。这种命名格式用于表示其他纹理的平铺和偏移属性,以便你可以独立地控制不同纹理的平铺和偏移。
_ST
表示纹理的平铺和偏移的变换矩阵,它是一个4维向量(Vector4)类型的属性。这个向量的各个分量(x、y、z、w)对应着纹理的水平平铺、垂直平铺、水平偏移和垂直偏移。
例如,_MainTex_ST
的值为(1, 1, 0, 0)
表示主纹理在水平和垂直方向上都不发生平铺,也不发生偏移。如果将其设置为(2, 2, 0, 0)
,则表示主纹理在水平和垂直方向上重复平铺两次。
你可以在自定义的着色器中使用这些属性来控制纹理的平铺和偏移效果。在着色器中,可以通过访问这些属性来修改纹理坐标,并将其应用于纹理采样,从而实现不同的纹理重复和偏移效果。
需要注意的是,这些属性需要在材质中进行设置,或者通过脚本动态修改,才能在着色器中起作用。你可以在材质面板中找到这些属性,或者使用C#脚本来控制它们。
总结起来,_MainTex_ST
和类似的_Name_ST
是Unity中用于控制纹理坐标平铺和偏移的属性,它们允许你在着色器中独立地控制不同纹理的平铺和偏移效果。
shader_feature_local
#pragma shader_feature_local 表示定义local keywords,后缀_fragment表示关键字用于片元着色器阶段,这些关键字与材质面板上的参数有关,案例如下
1 | // 在 Shader 面板上定义一个属性 |