版本:2022.3
语言: 英语
内置着色器包含文件
内置着色器辅助函数

内置宏

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_TARGET30。您可以在着色器代码中使用它来进行条件检查。例如

#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版本

UNITY_VERSION包含Unity版本的数值。例如,为Unity 2020.3.0,UNITY_VERSION202030。当需要编写使用不同内置着色器功能的不同版本的着色器时,可以用它进行版本比较。例如, #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_HLSLUNITY_COMPILER_HLSL2GLSLUNITY_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 buffergraphics 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 包含一些宏来处理此情况下的上述复杂性

  • COMPUTE_EYEDEPTH(i):计算顶点的眼睛空间深度,并在 o 中输出。在 不是 渲染到深度纹理时在顶点程序中使用。
  • DECODE_EYEDEPTH(i)/LinearEyeDepth(i):给定来自深度纹理 i 的高精度值,返回相应的眼睛空间深度。
  • Linear01Depth(i):给定来自深度纹理 i 的高精度值,返回介于0和1之间的线性深度。
  • UNITY_TRANSFER_DEPTH(o):已弃用。计算顶点的眼睛空间深度并在 o 中输出(o 必须是float2)。在具有原生深度纹理的平台上,此宏不起作用,因为Z缓冲区值是隐式渲染的。
  • UNITY_OUTPUT_DEPTH(i):已弃用。从 i(必须为float2)返回眼睛空间深度。在具有原生深度纹理的平台上,此宏始终返回零,因为Z缓冲区值是隐式渲染的。

注意:在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
        }
    }
}
内置着色器包含文件
内置着色器辅助函数