目录索引
译文
到目前为止,我们实现的许多变量、函数和向量都适用于Cg和HLSL,但是,在某些情况下,我们必须添加URP支持,以便着色器可以编译。
在着色器图形的情况下,如果我们想通过使用通用RP的代码创建着色器,我们必须添加一些依赖项,以便GPU可以读取此渲染管道。这种依赖关系可以在不同的路径中找到,比如下面两个路径:
Packages / Core RP Library / ShaderLibrary
Packages / Universal RP / ShaderLibrary
当我们在项目中安装Shader Graph时,“Core RP Library”会自动包含在内,同样,当我们选择此渲染管道作为渲染引擎时,“Universal RP”包也会包含在内。
这两个包都有扩展名为“.hlsl”的文件,我们的程序需要这些文件才能在hlsl中编译着色器。
为了理解这个概念,让我们复制着色器USB_simple_color,并将其重命名为USB_simple _color_URP。值得一提的是,着色器USB_simple_color(Cg)作为一个基本的颜色模型,已经在Universal RP中具有兼容性,然而,我们将生成它的副本并对其进行修改,以详细审查它在HLSL中的实现。
我们将从添加标签“RenderPipeline”开始,并使其等于“UniversalRenderPipline”,这样GPU就会知道该着色器在该渲染引擎中具有兼容性。
Tags
{
"RenderType"="Transparent"
"Queue"="Transparent"
"RenderPipeline"="UniversalRenderPipeline"
}
如本书所述,URP使用HLSL语言,因此CGPROGRAM/ENDCG块必须分别由HLSLPROGRAM和ENDHLSL代替。
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
...
ENDHLSL
}
为了使我们的着色器能够完美编译并提高其运行效率,我们必须包含依赖项“Core.hlsl”,它包含函数、结构和其他内容,从而允许程序在URP中正常运行。就其本身而言,Core.hlsl取代了“UnityCg.cginc”,这意味着我们必须消除着色器对UnityCg.cginc的依赖。
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
// #pragma multi_compile_fog
// #include "UnityCg.cginc"
#include "HLSLSupport.cginc"
#include "Package/com.unity.render - pipelines.universal/ShaderLibrary/Core.hlsl"
...
ENDHLSL
与Unity安装中包含的UnityCg.cginc不同,一旦我们在项目中安装了Universal RP,Core.hlsl就会作为一个包添加,因此,引用的时候,我们必须写其在项目中位置的完整路径。一旦我们替换了这些依赖关系,就会发生两件事。
1.GPU将无法编译雾坐标(UNITY_fog_COORDS、UNITY_TRANSFER_FOR和UNITY_APPLY_FOR),因为它们包含在UnityCg.cginc中。
2.同样的原因,您不能直接使用UnityObjectToClipPos函数。
相反,我们将不得不使用函数TransformObjectToHClip(v.vertex),该函数包含在依赖项“SpaceTransforms.hlsl”中,而该依赖项又包含在“Core.hlsl”中。
函数TransformObjectToHClip执行与UnityObjectToClipPos相同的操作,即将顶点的位置从对象空间转换到剪辑空间,但前者在执行过程中更高效。
v2f vert (appdata v)
{
v2f o;
// o.vertex = UnityObjectToClipPos(v.vertex);
o.vertex = TransformObjectToHClip(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
如上图,这个时候我们保存着色器并返回Unity,我们可以看到在控制台中生成了一个类型为“unrecognized identifier”的错误,这是什么原因?请记住,默认情况下,片段着色器阶段和col向量的类型都是fixed4。所以我们可以在函数中检查。
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
// UNITY_APPLY_FOG(i.fogcoord, col);
return col * _Color;
}
![图片[1]-《Unity着色器圣经》4.0.6. | Adding URP compatibility.-软件开发学习笔记](https://gamedevfan.cn/wp-content/uploads/2025/05/image-46-1024x234.jpeg)
正如我们已经知道的,URP不能编译“fixed”类型的变量或向量,相反,我们将不得不使用“half或float”。因此,在这一点上,我们可以做两件事。
1.手动将fixed类型的变量和向量替换为half。
2.或者包括“HLSLSupport.cginc”依赖项,它为着色器编译添加了帮助宏和跨平台定义。
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
// #pragma multi_compile_fog
// #include "UnityCg.cginc"
#include "HLSLSupport.cginc"
#include "Package/com.unity.render - pipelines.universal/ShaderLibrary/Core.hlsl"
...
ENDHLSL
一旦包含了这种依赖关系,我们就可以使用固定类型的变量和向量,因为现在我们的程序将根据其精度识别这种类型的数据,并自动用半值或浮点值替换它们。
原文对照
Up to this point, much of the variables, functions and vectors we have implemented, works for both Cg and HLSL, however, there will be some cases where we will have to add URP support so that our shader can compile.
In the case of Shader Graph, if we want to create a shader via code using Universal RP, we will have to add some dependencies so that the GPU can read this rendering pipeline. Such dependencies can be found in different routes, among which we can mention:
Packages / Core RP Library / ShaderLibrary
Packages / Universal RP / ShaderLibrary
The “Core RP Library” is included automatically when we install Shader Graph in our project, likewise, the “Universal RP” package is included when we select this rendering pipeline as our rendering engine.
Both packages have files with “.hlsl” extension, which are required by our program to compile shaders in HLSL.
To understand this concept, let’s duplicate the shader USB_simple_color and rename it as USB_simple_color_URP. It is worth mentioning that the shader USB_simple_color (Cg), being a basic color model, already has compatibility in Universal RP, however, we will generate a copy of this and modify it to review in detail its implementation in HLSL.
We will start by adding the Tags “RenderPipeline” and make it equal to “UniversalRenderPipeline”, in this way the GPU will know that this shader will have compatibility in this render engine.
Tags
{
"RenderType"="Transparent"
"Queue"="Transparent"
"RenderPipeline"="UniversalRenderPipeline"
}
As mentioned in this book, Universal RP works with HLSL language, therefore the CGPROGRAM/ ENDCG blocks will have to be replaced by HLSLPROGRAM and ENDHLSL respectively.
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
...
ENDHLSL
}
For our shader to compile perfectly and its process to be more efficient we will have to include the dependency “Core.hlsl”, which contains functions, structures and others, which allows the proper functioning of the program in Universal RP. In itself, Core.hlsl replaces “UnityCg.cginc”, which means that we will have to eliminate this dependency of our shader.
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
// #pragma multi_compile_fog
// #include "UnityCg.cginc"
#include "HLSLSupport.cginc"
#include "Package/com.unity.render - pipelines.universal/ShaderLibrary/Core.hlsl"
...
ENDHLSL
Unlike UnityCg.cginc which comes included in the Unity installation as such, Core.hlsl is added as a package once we install Universal RP in our project, therefore, we will have to write the full path of its location in the project. Once we replace these dependencies, two things will happen.
1. The GPU will not be able to compile the fog coordinates (UNITY_FOG_COORDS, UNITY_ TRANSFER_FOR, and UNITY_APPLY_FOR) since these are included in UnityCg.cginc.
2. Nor will you be able to compile the UnityObjectToClipPos function for the same reason.
Instead, we will have to use the function TransformObjectToHClip(v.vertex) which is included in the dependency “SpaceTransforms.hlsl”, which in turn, has been included in “Core.hlsl”.
The function TransformObjectToHClip performs the same operation as UnityObjectToClipPos, that is, it transforms the position of the vertices from object-space to clip-space, however, the former is more efficient in its execution process.
v2f vert (appdata v)
{
v2f o;
// o.vertex = UnityObjectToClipPos(v.vertex);
o.vertex = TransformObjectToHClip(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
If at this point we save our shader and go back to Unity, we can see that an error has been generated in the console of type “unrecognized identifier”, what is the reason for this? Remember that both the fragment shader stage and the col vector, by default, are of type fixed4. So we can check it in the function.
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
// UNITY_APPLY_FOG(i.fogcoord, col);
return col * _Color;
}
![图片[1]-《Unity着色器圣经》4.0.6. | Adding URP compatibility.-软件开发学习笔记](https://gamedevfan.cn/wp-content/uploads/2025/05/image-46-1024x234.jpeg)
As we already know, Universal RP can not compile variables or vectors of the type “fixed”, instead we will have to use “half or float”. Therefore, at this point, we can do two things.
1. Manually replace variables and vectors of type fixed with half.
2. Or include the “HLSLSupport.cginc” dependency that adds helper macros and cross-platform definitions for shader compilation.
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
// #pragma multi_compile_fog
// #include "UnityCg.cginc"
#include "HLSLSupport.cginc"
#include "Package/com.unity.render - pipelines.universal/ShaderLibrary/Core.hlsl"
...
ENDHLSL
Once this dependency is included, we can work with variables and vectors of the fixed type, since now our program will recognize this type of data according to its precision and will replace them with either half or float, automatically.
暂无评论内容