目录:Unity Shader - 知识点目录(先占位,后续持续更新)
原文:Shader data types and precision
版本:2019.1
Shader data types and precision
着色器数据类型和精度
在Unity中,标准的Shader语言是HLSL,一般的HLSL数据类型都支持。但是,Unity也有一些HLSL之外的类型,为了更好的支持移动平台。
Basic data types
基础的数据类型
在shader中的主要计算部分是浮点型的数值计算(就像C#编程语言的float)。一些不同的浮点类型有:float,half和fixed(就像vector/matrix(向量和矩阵)的不同的精度,如:half3 和 float4x4)。这些类型区别在于精度不同(因此,要区别性能与效果的使用场合)。
High precision:float
高精度:float
最高精度浮点值,一般都是32位(就像一般编程语言中的float)。
float 精度一般用于世界空间的坐标,纹理坐标,或是涉及复杂的标量计算,如:三角函数的或是power次数(幂)或是exponentiation(指数)。
Medium precision:half
中等精度的浮点数值,一般是16位(数值范围在:-60000 到 +60000,还有3个小数精度)。
半精度在下面一些计算都很有用:短小的向量,对象空间坐标,高动态范围颜色值(HDR color)。
Low precision:fixed
最低精度浮点数值。一般是11位,数据范围是:-2.0 到 +2.0,与最小精度位:1/256。
Fixed 精度在一般的颜色数值上很有用(如存有纹理的颜色)。
Integer data types
整形数据类型
整型(int 数据类型)常用于循环遍历数组是的索引值。并且他们通常在不同平台上都可以计算处理的很好。
不同的平台上的GPU可能不支持整型类型。例如,Direct3D 9 和 OpenGL ES 2.0 GPU仅在浮点数据上操作,与看起来简单的整型表达式(包括位运算或是逻辑运算)可以使用相当复杂的浮点数学指令进行模拟。
Direct3D 11,OpenGL ES 3,Metal和其他的现代平台都有对整型数据类型的支持,所以使用位运算都能按预期的结果一样。
Composite vector/matrix types
复合型的数据类型:向量/矩阵
HLSL有内置的向量与矩阵类型,它们都是由基础的类型创建的。例如,float3 是一个3D向量,有x,y,z分量,half4是一个中等精度的4D向量,有x,y,z,w分量。另外,向量也可以使用.r, .g, .b, .a的模式来访问分量,这对于颜色上使用很有用。
矩阵类型也是类似的方式来构建的;例如 float4x4 是一个4x4的变换矩阵。注意一些平台仅仅支持方正矩阵,最需要注意的是 OpenGL ES 2.0。
Texture/Sampler types
纹理/采样器类型
通常你在HLSL代码中定义声明纹理如下:
sampler2D _MainTex;
samplerCUBE _Cubemap;
对于移动平台,它们会转换为"low precision samplers"(低精度的采样器)。例如,纹理经需要低精度数据存储在里面。如果你的纹理是HDR颜色的,你需要使用half精度采样器:
sampler2D_half _MainTex;
samplerCUBE_half _Cubemap;
或是如果你的纹理是需要满精度的数据(例如:depth texture(深度图)),那么将使用一个满精度的采样器:
sampler2D_float _MainTex;
samplerCUBE_float _Cubemap;
Precision, Hardware Support and Performance
精度,硬件支持与性能
float/half/fixed数据类型在PC 的GPUS上总会使用高精度的。这里的PC是指(Windows/Mac/Linux)GPU,这对于你的shader中写的是 float,half 或是 fixed 都无所谓了。它们计算所有的浮点运算都使用满精度32位浮点精度。
half 和 fixed 类型只会在运行目标文移动平台的GPU上才有意义,这些类型主要用在减少能耗(或是为了提升性能方面中)。记住,你需要在移动设备上测试你的shader,查看是否有数值精度上的问题。
在移动设备上的GPU,在不同GPU家族对的精度支持也有些不同。这里我们列出移动设备GPU加速处理浮点类型的总览(有数值的代表是支持的):
GPU 家族 | float | half | fixed |
---|---|---|---|
PowerVR 系列 6/7 | 32 | 16 | 同左 |
PowerVR SGX 5xx | 32 | 16 | 11 |
Qualcomm Adreno 4xx/3xx | 32 | 16 | 同左 |
Qualcomm Adreno 2xx | 32 vertex 24 fragment(顶点中使用32位,片段使用24位) | 同左 | 同左 |
ARM Mali T6xx/7xx | 32 | 16 | 同左 |
ARM Mali 400/500 | 32 vertex 24 fragment(顶点中使用32位,片段使用24位) | 同左 | 同左 |
NVIDIA X1 | 32 | 16 | 同左 |
NVIDIA K1 | 32 | 同左 | 同左 |
NVIDIA Tegra 3/4 | 32 | 16 | 同左 |
多数现在移动设备GPU仅支持32位(使用float类型)或是16位的数值(使用half和fixed)。一个比较老旧的GPU在vertex shader和fragment shader计算都有不同精度。
使用较低的精度通常可以更快,要么是由于改进的GPU寄存器分配,要么是由于特定的"fast path"(快速路径)执行单元的某些较低精度的数学运算。及时没有原生性能的优点,使用比较低精度通常会比较低的GPU能耗,让电池寿命也更好一些。
经验法则是,对所有的位置坐标和纹理坐标都使用half。如果发现half精度不能满足部分计算时,在提升精度。
Support for infinities, NaNs and other special floating point values
对无限大,非数字和其他浮点数值的支持
特定的浮点数值的支持与否依赖于你(多数指移动设备的)正在运行的GPU家族。
所有支持Direct3D 10的GPU都支持明确规定的IEEE 754浮点数值标准。这意味着浮点数值的正确运算正如运行在GPU上的一般编程语言一样。
移动设备GPU支持的级别稍微有些不同。如,除以0的结果可能会是一个NaN("not a number"非数字);在其他的一些GPU上可能是无限大,零或是其他不确定的值。确保在目标设备上测试你的shader,来检测它们是否支持。
External GPU Documentation
其他的GPU文档
GPU提供商有关于其GPU性能和功能的深入指南。详情请参阅:
- ARM Mali Guide for Unity Developers
- Qualcomm Adreno OpenGL ES Developer Guide
- PowerVR Architecture Guides