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。
  • TEXCOORD1TEXCOORD2TEXCOORD3 分别是第 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和位置坐标时,使用了语义TEXCOORD0SV_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当前模型 * 视图 * 投影矩阵。

摄像机和屏幕

这些变量将对应于正在渲染的摄像机。例如,在阴影贴图渲染中,它们仍将引用摄像机组件值,而不是用于阴影贴图投影的“虚拟摄像机”。

名称类型
_WorldSpaceCameraPosfloat3摄像机的世界空间位置。
unity_CameraProjectionfloat4x4摄像机的投影矩阵。
unity_CameraInvProjectionfloat4x4摄像机投影矩阵的逆矩阵。
unity_CameraWorldClipPlanes[6]float4摄像机视锥体平面世界空间方程,按以下顺序:左、右、底、顶、近、远。

时间

名称类型
_Timefloat4自关卡加载以来的时间 (t/20, t, t2, t3),用于将着色器中的内容动画化。
_SinTimefloat4时间正弦:(t/8, t/4, t/2, t)。
_CosTimefloat4时间余弦:(t/8, t/4, t/2, t)。

光照

前向渲染(ForwardBaseForwardAdd通道类型):

名称类型
_LightColor0(在 UnityLightingCommon.cginc 中声明)fixed4光源颜色。
_WorldSpaceLightPos0float4方向光:(世界空间方向,0)。其他光源:(世界空间位置,1)。

延迟着色和延迟光照,在光照通道着色器中使用:

名称类型
_LightColorfloat4光源颜色。

顶点光照渲染(Vertex 通道类型):
最多可为 Vertex 通道类型设置 8 个光源;始终从最亮的光源开始排序。因此,如果希望一次渲染受两个光源影响的对象,可直接采用数组中前两个条目。如果影响对象的光源数量少于 8,则其余光源的颜色将设置为黑色。

名称类型
unity_LightColorhalf4[8]光源颜色
unity_LightPositionfloat4[8]View-space light positions. (-direction,0) for directional lights; (position,1) for Point or Spot Lights.

光照贴图

名称类型
unity_LightmapTexture2D包含光照贴图信息
unity_LightmapSTfloat4[8]缩放 UV 信息并转换到正确的范围以对光照贴图纹理进行采样

雾效和环境光

名称类型
unity_AmbientSkyfixed4梯度环境光照情况下的天空环境光照颜色。
unity_FogColorfixed4雾效颜色。

本文参考自Unity 官方中文手册Microsoft 文档

关于SV语义部分参考了https://blog.csdn.net/zhao_92221/article/details/46797969

如文中有理解错误或遗漏部分,欢迎批评指出

HLSL高级着色器语言怎样在unity3d只用,使用的步骤是啥

参考技术A 新建shader然后双击或者点击Inspector窗口中的open,然后即可在跳出的脚本编辑器中编写shader,编写完保存以后unity3d会自动编译,如果有错会提示

以上是关于Unity中HLSL代码块的基本知识归纳整理的主要内容,如果未能解决你的问题,请参考以下文章

HLSL高级着色器语言怎样在unity3d只用,使用的步骤是啥

HLSL ddx / ddy

ShaderLab和CG/HLSL的一些数据类型归纳(转)

九年级英语语法知识点整理归纳

[Unity] Shader - CG语言 和 HLSL语言

UE4的资产可以给u3d用吗