Unity在编译着色器程序时定义了几个预处理器宏。
宏 | 目标平台 |
---|---|
SHADER_API_D3D11 |
Direct3D 11 |
SHADER_API_GLCORE |
桌面OpenGL“核心”(GL 3/4) |
SHADER_API_GLES |
OpenGL ES 2.0 |
SHADER_API_GLES3 |
OpenGL ES 3.0/3.1 |
SHADER_API_METAL |
iOS/Mac Metal |
SHADER_API_VULKAN |
Vulkan |
SHADER_API_D3D11_9X |
针对通用Windows平台支持Microsoft In App Purchase (IAP)模拟器的功能,允许你在发布应用程序之前在设备上测试IAP购买流程。 更多信息 在术语表中查看的Direct3D 11“功能级别9.x”目标 |
SHADER_API_DESKTOP |
Windows、Mac和Linux桌面平台,WebGL在Web浏览器中渲染2D和3D图形的JavaScript API。Unity WebGL构建选项允许Unity将内容发布为JavaScript程序,这些程序使用HTML5技术和WebGL渲染API在Web浏览器中运行Unity内容。 更多信息 在术语表中查看、Stadia |
SHADER_API_MOBILE |
iOS和Android移动平台,tvOS |
此外,当目标着色语言为GLSL(对于OpenGL/GLES平台始终为真)时,定义了SHADER_TARGET_GLSL
。
SHADER_TARGET
定义为一个与着色器在GPU上运行的可执行程序。 更多信息
在术语表中查看目标编译模型(即与#pragma target
指令匹配)相对应的数值。例如,在编译到着色器模型3.0时,SHADER_TARGET
为30
。您可以在着色器代码中使用它来进行条件检查。例如
#if SHADER_TARGET < 30
// less than Shader model 3.0:
// very limited Shader capabilities, do some approximation
#else
// decent capabilities, do a better thing
#endif
UNITY_VERSION
包含Unity版本的数值。例如,为Unity 2020.3.0,UNITY_VERSION
是202030
。当需要编写使用不同内置着色器功能的不同版本的着色器时,可以用它进行版本比较。例如, #if UNITY_VERSION >= 202000
预处理检查仅在版本2020或更高版本时通过。
在编译每个着色器阶段时定义预处理器宏SHADER_STAGE_VERTEX
、 SHADER_STAGE_FRAGMENT
、 SHADER_STAGE_DOMAIN
、 SHADER_STAGE_HULL
、 SHADER_STAGE_GEOMETRY
、 SHADER_STAGE_COMPUTE
。通常,当着色器代码在像素着色器和计算着色器之间共享时非常有用,这对于某些事情需要稍微不同地处理的情况。
不鼓励直接使用这些平台宏,因为它们并不总是有助于保护代码的将来。例如,如果您正在编写一个检查D3D11的着色器,您可能想要确保将来检查可以扩展到Vulkan。相反,Unity定义了几个辅助宏(在HSLSupport.cginc
中)。
宏 | 使用 |
---|---|
UNITY_BRANCH |
在条件语句之前添加此内容,以便通知编译器这应该编译为实际分支。在HLSL平台上有代码时展开为[分支] |
UNITY_FLATTEN |
在条件语句之前添加,以便编译器知道应该将其展开以避免实际的分支指令。在HLSL平台上扩展为[flatten] 。 |
UNITY_NO_SCREENSPACE_SHADOWS |
在那些不使用级联屏幕空间阴影贴图的平台上定义(移动平台)。 |
UNITY_NO_LINEAR_COLORSPACE |
在那些不支持线性颜色空间的平台上定义(移动平台)。 |
UNITY_NO_RGBM |
在RGBM 压缩一种存储数据的方法,可以减少其所需的存储空间。参见纹理压缩、动画压缩、音频压缩、构建压缩。 在词汇中查看不被用于光贴图一种预先渲染的纹理,其中包含了场景中静态对象上光源的效果。光贴图被叠加到场景几何形状上,以创建照明效果。 更多信息 在词汇中查看(移动平台)。 |
UNITY_NO_DXT5nm |
在那些不使用DXT5nm法线贴图压缩的平台上定义(移动平台)。 |
UNITY_FRAMEBUFFER_FETCH_AVAILABLE |
在那些可以提供“帧缓冲区颜色提取”功能的平台上定义(通常为iOS平台 - OpenGL ES 2.0、3.0和Metal)。 |
UNITY_USE_RGBA_FOR_POINT_SHADOWS |
在点光阴影贴图使用带编码深度的RGBA纹理的平台上定义(其他平台使用单通道浮点纹理)。 |
UNITY_ATTEN_CHANNEL |
定义了包含数据的灯光衰减纹理的哪个通道;用于逐像素光照代码。定义为‘r’或‘a’。 |
UNITY_HALF_TEXEL_OFFSET |
在那些需要调整半纹理偏移以将纹理像素映射到像素的平台上定义。 |
UNITY_UV_STARTS_AT_TOP |
始终定义为1或0。值为1表示纹理V坐标在纹理的“顶部”为0。Direct3D-like平台使用值为1;OpenGL-like平台使用值为0。 |
UNITY_MIGHT_NOT_HAVE_DEPTH_Texture |
定义如果平台可能通过手动将深度渲染到纹理中来模拟阴影贴图或深度纹理。 |
UNITY_PROJ_COORD(a) |
给定一个4分量向量,这会返回一个适用于投影纹理读取的纹理坐标。在大多数平台上直接返回给定值。 |
UNITY_NEAR_CLIP_VALUE |
定义为近端裁剪平面一个平面,它限制了摄像机可以从中看到多远或多近。摄像机的可视范围在远裁剪平面和近裁剪平面之间。参见远裁剪平面和近裁剪平面。 更多信息 在词汇中查看的值。Direct3D-like平台使用1.0,而OpenGL-like平台使用-1.0。 |
UNITY_VPOS_TYPE |
定义所需的像素位置输入(VPOS)数据类型:float2 在D3D9上,在其他地方使用float4 。 |
UNITY_CAN_COMPILE_TESSELLATION |
当Shader编译器“理解”tessellation Shader HLSL语法时定义(目前仅为D3D11)。 |
UNITY_INITIALIZE_OUTPUT(type,name) |
将给定类型的变量name初始化为零。 |
UNITY_COMPILER_HLSL 、UNITY_COMPILER_HLSL2GLSL 、UNITY_COMPILER_CG |
指示正在使用的Shader编译器以编译Shader。有关详细信息,请参阅Shader编译文档。如果在编译器之间遇到非常具体的Shader语法处理差异,并且希望为每个编译器编写不同的代码,请使用此选项。 |
UNITY_REVERSED_Z
- 定义在采用反向Z缓冲区的平台上。存储的Z值范围是1..0,而不是0..1。根据平台,声明和提取阴影贴图可能会有很大的不同。Unity有多个宏来帮助做到这一点
宏 | 使用 |
---|---|
UNITY_DECLARE_SHADOWMAP(tex) |
声明一个名为“tex”的阴影贴图纹理变量。 |
UNITY_SAMPLE_SHADOW(tex,uv) |
在给定“uv”坐标上采样阴影贴图纹理“tex”(XY分量是纹理位置,Z分量是用于比较的深度)。返回0..1范围内的单个浮点值,包含阴影项。 |
UNITY_SAMPLE_SHADOW_PROJ(tex,uv) |
类似于上述操作,但执行投影阴影贴图读取。 “uv”是一个float4,其他所有分量都将除以.w来进行查找。 |
tex
的格式必须是RenderTextureFormat.Shadowmap。
注意:并非所有的显卡都支持阴影贴图。使用SystemInfo.SupportsRenderTextureFormat来检查支持。
Direct3D 11将所有着色器变量分组到“常量缓冲区”中。大多数Unity内置变量已经分组,但对于您自己的着色器中的变量,根据预期的更新频率,可能更优将它们放入单独的常量缓冲区。
使用CBUFFER_START(name)
和CBUFFER_END
宏。
CBUFFER_START(MyRarelyUpdatedVariables)
float4 _SomeGlobalValue;
CBUFFER_END
如果您使用GPU compute buffer或graphics buffer来设置变量的值,请确保缓冲区和常量缓冲区在所有目标图形API中的数据布局匹配。更多信息请见使用GPU缓冲区中的常量缓冲区。
通常您会在着色器代码中使用texture2D
声明一个纹理和采样器对。然而在某些平台(如DX11)中,纹理和采样器是独立的对象,采样器的最大可能数量非常有限。Unity提供了一些宏用于声明没有采样器的纹理,以及使用来自另一个纹理的采样器来采样纹理。如果在达到采样器限制时使用,并且知道您的许多纹理实际上可以共享一个采样器(采样器定义纹理的过滤和环绕模式),请使用此宏。
宏 | 使用 |
---|---|
UNITY_DECLARE_TEX2D(name) |
声明一个纹理和采样器对。 |
UNITY_DECLARE_TEX2D_NOSAMPLER(name) |
声明一个没有采样器的纹理。 |
UNITY_DECLARE_TEX2DARRAY(name) |
声明一个纹理数组和采样器变量。 |
UNITY_SAMPLE_TEX2D(name,uv) |
使用给定的纹理坐标从纹理和采样器对中采样。 |
UNITY_SAMPLE_TEX2D_SAMPLER(name,samplername,uv) |
使用来自另一个纹理(samplername)的采样器从纹理(name)中进行采样。 |
UNITY_SAMPLE_TEX2DARRAY(name,uv) |
使用float3 UV从纹理数组中采样;坐标的z分量是数组元素索引。 |
UNITY_SAMPLE_TEX2DARRAY_LOD(name,uv,lod) |
使用显式的mipmap级别从纹理数组中采样。 |
更多信息请见采样器状态文档。
当编译表面着色器编写内置渲染管线着色器的一种简化的方法。请见更多信息,查看词汇表时,会为各种光照通过生成大量代码。在编译每个通过时,定义以下宏之一
宏 | 使用 |
---|---|
UNITY_PASS_FORWARDBASE |
前向渲染一种渲染路径,根据影响对象的灯光在单个或多个通过中渲染每个对象。根据灯光的设置和强度,前向渲染本身也根据不同的方式处理灯光。请见更多信息,查看词汇表基本通过(主方向光、光照贴图、SH)。 |
UNITY_PASS_FORWARDADD |
前向渲染加法通过(每个通过一个灯光)。 |
UNITY_PASS_DEFERRED |
延迟着色内置渲染管线中的一种渲染路径,不对影响一个游戏对象的光照数量进行限制。所有光照都在每个像素上进行评估,这意味着它们都能正确地与法线贴图等交互。此外,所有光照都可以有cookie和阴影。 更多信息 在术语表中查看 过滤器(渲染G缓冲区)。 |
UNITY_PASS_SHADOWCASTER |
阴影投射器和深度纹理渲染过滤器。 |
UNITY_SHADER_NO_UPGRADE
允许您禁用Unity自动升级或修改您的着色器文件。
大多数时候,深度纹理用于从 摄像机一个组件,用于创建场景中特定视点的图像。输出可以是屏幕上绘制的,也可以作为纹理捕捉。《a class="tooltipMoreInfoLink" href="CamerasOverview.html">更多信息
在术语表中查看 渲染深度。UnityCG.cginc 包含一些宏来处理此情况下的上述复杂性
注意:在DX11/12和Metal上,Z缓冲区范围是1-0,并且定义了UNITY_REVERSED_Z。在其他平台上,范围是0-1。
例如,此着色器会渲染其 GameObjectUnity场景中的基本对象,可以代表角色、道具、场景、摄像机、航位点等。GameObject的功能由附加的组件定义。《a class="tooltipMoreInfoLink" href="class-GameObject.html">更多信息
在术语表中查看 的深度。
Shader "Render Depth" {
SubShader {
Tags { "RenderType"="Opaque" }
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 depth : TEXCOORD0;
};
v2f vert (appdata_base v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
UNITY_TRANSFER_DEPTH(o.depth);
return o;
}
half4 frag(v2f i) : SV_Target {
UNITY_OUTPUT_DEPTH(i.depth);
}
ENDCG
}
}
}