Unity中Shader变体优化
在Shader中,一般有两个方面的优化:一方面是内存优化(即变体优化);一方面是渲染优化(即Shader中计算的优化)。我们这篇文章来了解一下Shader变体的优化。
文章目录
前言
在Shader中,一般有两个方面的优化:一方面是内存优化(即变体优化);一方面是渲染优化(即Shader中计算的优化)。我们这篇文章来了解一下Shader变体的优化。
一、在Unity中查看变体个数,以及有哪些变体
- 创建一个UnlitShader,里面有一个默认的Shader
#pragma multi_compile_fog
- 选择Shader后,点击Compile and show code 右边的小箭头可以可见变体数
- 变体数后面有一个 Show,可以展示有哪些变体
二、若使用预定义的变体太多,我们只使用其中的几个变体,我们该怎么做
优化一:可以直接定义需要的那个变体
- 例如,我们只需要线性雾 FOG_LINEAR 变体,可以单独定义这个变体
#pragma multi_compile _ FOG_LINEAR
-
空格 _ 空格 是空变体的意思
-
可以看见我们的变体数变少了
优化二:使用 skip_variants 剔除不需要的变体
- 我们剔除 指数雾1 和 指数雾2
#pragma multi_compile_fog
//优化法二 (使用 skip_variants 剔除变体)
#pragma skip_variants FOG_EXP FOG_EXP2
三、变体的数量增长
1、使用 multi_compile 再定义 3 个变体
#pragma multi_compile_fog
//我们再定义3个变体 A B C 看一下变体数量会增加到多少
#pragma multi_compile A B C
- 我们会看见,虽然我们只定义了三个变体。但是,最后的变体数,却是相乘的数量
由此可见变体数很容易达到成百上千的,所以我们要尽可能地控制变体的数量
2、再用 shader_feature 定义三个变体 D E F
shader_feature定义的变体,只有在使用的时候才会生成
//我们再用 shader_feature 定义三个变体 D E F(shader_feature定义的变体,只有在使用的时候才会生成)
#pragma shader_feature D E F
- 我们可以看见在剔除没有用到的变体前,我们的变体数由上升了 3 倍
- 勾选剔除后,可以把 shader_feature 没有使用的变体剔除
四、变体收集器
1、我们在资源管理界面,创建变体收集器
2、创建了变体收集器后,我们把刚才使用的Shader加入变体收集器
3、然后点击加号,可以看见变体收集器中收集的变体
变体收集器一般是由程序使用的,在游戏一开始对其进行着色器加载,比如说原神中进入游戏时,卡岩那个游戏加载。
五、Unity 项目设置 中的 变体收集器
- Edit->Project Setting->Graphics->Shader Stripping
- 可以在其中自定义是否使用变体
- 还可以把用到的变体,全都打包成一个变体收集器(一般不推荐这样用,变体太多太杂了)
六、测试代码
Shader "MyShader/P2_3_2"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
//优化法一 ( _ 是空变体的意思)
//#pragma multi_compile _ FOG_LINEAR
//优化法二 (使用 skip_variants 剔除变体)
//#pragma skip_variants FOG_EXP FOG_EXP2
//我们再定义3个变体 A B C 看一下变体数量会增加到多少
#pragma multi_compile A B C
//我们再用 shader_feature 定义三个变体 D E F(shader_feature定义的变体,只有在使用的时候才会生成)
#pragma shader_feature D E F
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
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;
}
ENDCG
}
}
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)