Unity中HLSL代码块的基本知识归纳整理
Posted 雨亦妖_JRegn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity中HLSL代码块的基本知识归纳整理相关的知识,希望对你有一定的参考价值。
Unity中HLSL代码块的基本知识归纳整理
Unity中HLSL代码块的基本知识归纳整理
着色器语义
编写 HLSL 着色器程序时, 输入和输出变量需要通过语义来表明 其“意图”。这是 HLSL 着色器语言中的 标准概念。
语义是附加到着色器输入或输出的字符串,用于传达有关参数预期用途的信息。 在着色器阶段之间传递的所有变量都需要语义.
顶点着色器输入语义
主顶点着色器函数(由 #pragma vertex
指令表示)需要在所有输入参数上都有语义。 这些对应于各个网格数据元素,如顶点位置、法线网格和纹理坐标。
对于 Cg/HLSL 顶点程序, 网格顶点数据作为输入传递给顶点 着色器函数。每个输入都需要有指定的语义:例如,POSITION
输入表示顶点位置,NORMAL
表示顶点法线。
通常,顶点数据输入在结构中声明,而不是 逐个列出。
几个常用的顶点结构:
appdata_base
:位置、法线和一个纹理坐标。appdata_tan
:位置、切线、法线和一个纹理坐标。appdata_full
:位置、切线、法线、四个纹理坐标和颜色。
要访问不同的顶点数据,需要自己声明顶点结构,或者将输入参数添加到顶点着色器。顶点数据由 Cg/HLSL 语义标识,并且必须来自以下列表:
POSITION
是顶点位置,通常为 float3 或 float4。NORMAL
是顶点法线,通常为 float3。TEXCOORD0
是第一个 UV 坐标,通常为 float2、float3 或 float4。TEXCOORD1
、TEXCOORD2
和TEXCOORD3
分别是第 2、第 3 和第 4 个 UV 坐标。TANGENT
是切线矢量(用于法线贴图),通常为 float4。COLOR
是每顶点颜色,通常为 float4。
示例:
我们在unity中创建一个‘Unlit Shader’,可以看见这一部分(我使用的unity版本是2019):
struct v2f
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
;
从这一部分可以发现,当我们需要读取顶点的uv和位置坐标时,使用了语义TEXCOORD0
和SV_POSITION
,也就是将自己创建的变量’uv’和’vertex’通过语义定义成了第一个UV坐标和顶点位置。
其中可以发现POSITION
语义这里写的是SV_POSITION
,而它俩的区别是什么呢?
这就涉及到另一个概念——System-Value语义。
System Value语义
系统值语义是 Direct3D 10 的新增功能。 所有系统值以 SV
前缀开头,一个常见示例是 SV_POSITION
,该位置由光栅器阶段解释。
意思是:
在DX10以后的语义绑定中被使用代表特殊的意义,和
POSITION
用法并无不同。唯一区别是SV_POSTION
一旦被作为vertex shader的输出语义,那么这个最终的顶点位置就被固定了,直接进入光栅化处理在DX10版本之前没有引入SV_的预定义语义,
POSITION
被用作vertex shader的输入/输出,fragment shader的输入参数。但DX10之后就推荐使用SV_POSITION
作为vertex shader的输出和fragment shader的输入了,注意vertex shader的输入还是使用POSITION
!参考自https://blog.csdn.net/zhao_92221/article/details/46797969
个人理解就是,经过SV_语义定义完后,POSITION
便被固定下来无法改变,因此才使用POSITION
作为Vertex shader的输入,而使用SV_POSITION
作为Vertex shader的输出。
因为经过顶点着色器后,顶点的坐标位置便被确定,在片元着色器中不允许再去更改这个变量。
内置着色器 include
文件
Unity 提供了若干文件供着色器程序用于引入预定义的变量和 helper 函数。这可以通过标准 #include 指令来完成,例如:
CGPROGRAM
// ...
#include"UnityCG.cginc"
// ...
ENDCG
Unity 中的着色器 include
文件采用 .cginc
扩展名,内置的着色器 include
文件包括:
HLSLSupport.cginc
-_(自动包含)_用于跨平台着色器编译的 helper 宏和定义。UnityShaderVariables.cginc
-_(自动包含)_常用的全局变量。UnityCG.cginc
- 常用的 helper 函数。AutoLight.cginc
- 光照和阴影功能,例如表面着色器在内部使用此文件。Lighting.cginc
- 标准表面着色器光照模型;当您编写表面着色器时会自动包含。TerrainEngine.cginc
- 地形和植被着色器的 helper 函数。
而在之中,常见的UnityCG.cginc
库便是调用常用的helper函数。
内置着色器 helper 函数
Unity 具有许多内置实用函数,旨在使编写着色器更简单,更轻松。
在这里罗列一些常见的help函数,更多的函数请前往 Unity 官方中文手册——内置着色器helper函数 查看
UnityCG.cginc 中的顶点变换函数
功能: | 描述: |
---|---|
float4 UnityObjectToClipPos(float3 pos) | 将对象空间中的点变换到齐次坐标中的摄像机裁剪空间。这等效于 mul(UNITY_MATRIX_MVP, float4(pos, 1.0)),应该在适当的位置使用。 |
float3 UnityObjectToViewPos(float3 pos) | 将对象空间中的点变换到视图空间。这等效于 mul(UNITY_MATRIX_MV, float4(pos, 1.0)).xyz,应该在适当的位置使用。 |
UnityCG.cginc 中的通用 helper 函数
功能: | 描述: |
---|---|
float3 WorldSpaceViewDir (float4 v) | 返回从给定对象空间顶点位置朝向摄像机的世界空间方向(未标准化)。 |
float3 ObjSpaceViewDir (float4 v) | 返回从给定对象空间顶点位置朝向摄像机的对象空间方向(未标准化)。 |
UnityCG.cginc 中的前向渲染 helper 函数
功能: | 描述: |
---|---|
float3 WorldSpaceLightDir (float4 v) | 根据给定的对象空间顶点位置计算朝向光源的世界空间方向(未标准化)。 |
float3 ObjSpaceLightDir (float4 v) | 根据给定对象空间顶点位置计算朝向光源的对象空间方向(未标准化)。 |
内置着色器变量
Unity 的内置文件包含着色器的全局变量:当前对象的变换矩阵、光源参数、当前时间等等。就像任何其他变量一样,可在着色器程序中使用这些变量,但如果已经包含相关的 include 文件,则不必声明这些变量。
同样,我在这里罗列一些常见的变量,更多请前往 Unity官方中文手册——内置着色器变量 中查看。
变换
所有这些矩阵都是float4×4
类型,并且是列主序的
名称: | 值 |
---|---|
unity_ObjectToWorld | 当前模型矩阵。 |
unity_WorldToObject | 当前世界矩阵的逆矩阵。 |
UNITY_MATRIX_MV | 当前模型 * 视图矩阵。 |
UNITY_MATRIX_MVP | 当前模型 * 视图 * 投影矩阵。 |
摄像机和屏幕
这些变量将对应于正在渲染的摄像机。例如,在阴影贴图渲染中,它们仍将引用摄像机组件值,而不是用于阴影贴图投影的“虚拟摄像机”。
名称 | 类型 | 值 |
---|---|---|
_WorldSpaceCameraPos | float3 | 摄像机的世界空间位置。 |
unity_CameraProjection | float4x4 | 摄像机的投影矩阵。 |
unity_CameraInvProjection | float4x4 | 摄像机投影矩阵的逆矩阵。 |
unity_CameraWorldClipPlanes[6] | float4 | 摄像机视锥体平面世界空间方程,按以下顺序:左、右、底、顶、近、远。 |
时间
名称 | 类型 | 值 |
---|---|---|
_Time | float4 | 自关卡加载以来的时间 (t/20, t, t2, t3),用于将着色器中的内容动画化。 |
_SinTime | float4 | 时间正弦:(t/8, t/4, t/2, t)。 |
_CosTime | float4 | 时间余弦:(t/8, t/4, t/2, t)。 |
光照
前向渲染(ForwardBase
和ForwardAdd
通道类型):
名称 | 类型 | 值 |
---|---|---|
_LightColor0(在 UnityLightingCommon.cginc 中声明) | fixed4 | 光源颜色。 |
_WorldSpaceLightPos0 | float4 | 方向光:(世界空间方向,0)。其他光源:(世界空间位置,1)。 |
延迟着色和延迟光照,在光照通道着色器中使用:
名称 | 类型 | 值 |
---|---|---|
_LightColor | float4 | 光源颜色。 |
顶点光照渲染(Vertex
通道类型):
最多可为 Vertex
通道类型设置 8 个光源;始终从最亮的光源开始排序。因此,如果希望一次渲染受两个光源影响的对象,可直接采用数组中前两个条目。如果影响对象的光源数量少于 8,则其余光源的颜色将设置为黑色。
名称 | 类型 | 值 |
---|---|---|
unity_LightColor | half4[8] | 光源颜色 |
unity_LightPosition | float4[8] | View-space light positions. (-direction,0) for directional lights; (position,1) for Point or Spot Lights. |
光照贴图
名称 | 类型 | 值 |
---|---|---|
unity_Lightmap | Texture2D | 包含光照贴图信息 |
unity_LightmapST | float4[8] | 缩放 UV 信息并转换到正确的范围以对光照贴图纹理进行采样 |
雾效和环境光
名称 | 类型 | 值 |
---|---|---|
unity_AmbientSky | fixed4 | 梯度环境光照情况下的天空环境光照颜色。 |
unity_FogColor | fixed4 | 雾效颜色。 |
本文参考自Unity 官方中文手册 与 Microsoft 文档
关于SV语义部分参考了https://blog.csdn.net/zhao_92221/article/details/46797969
如文中有理解错误或遗漏部分,欢迎批评指出
HLSL高级着色器语言怎样在unity3d只用,使用的步骤是啥
参考技术A 新建shader然后双击或者点击Inspector窗口中的open,然后即可在跳出的脚本编辑器中编写shader,编写完保存以后unity3d会自动编译,如果有错会提示以上是关于Unity中HLSL代码块的基本知识归纳整理的主要内容,如果未能解决你的问题,请参考以下文章
HLSL高级着色器语言怎样在unity3d只用,使用的步骤是啥