#pragma multi_compile和#pragma shader_feature

https://catlikecoding.com/unity/tutorials/rendering/part-9/

when using a multi-compile directive, unity generates shader variants for all possible combinations.
compiling all permutations can take a lot of time, when many keywords are used.
all these variants are also included in builds, which might be unnecessary.

an alternative is to define a shader feature, instead of multi-compile directive.
the difference is that permutations of shader features are only compiled when needed.
if no material uses a certain keyword, then no shader variants for that keyword are compiled. Unity also checks which keywords are used in builds, only including the necessary shader variants.

在这里插入图片描述
上面的这段话已经写的很明白了。经过我的测试:
1、在编辑器下你使用shader_feature,不会有任何的影响。在运行的时候,unity会自动根据EnableKeyword和DisableKeyword去生成对应的变体。
2、however,但是,在打包成exe、apk、ipa时,就不能这么随意了。例如:

Shader "Unlit/NewUnlitShader"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
		[Toggle(_NEAR_FADE)] _NearFade("Near Fade", Float) = 0
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma shader_feature _NEAR_FADE

			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				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);
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				#if defined(_NEAR_FADE)
					return fixed4(1,0,0,1); //红色
				#else
					return fixed4(0, 1, 0, 1); //绿色
				#endif
			}
			ENDCG
		}
	}
}

在编辑下创建一个材质球:
在这里插入图片描述
此时,我们没有勾选Near Fade,
查看shader生成的变体:
在这里插入图片描述
此时没有生成关键字。

那么C#中我们使用这样的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{

    public GameObject cube;

    public void OnClickButton()
    {
        MeshRenderer mr = cube.GetComponent<MeshRenderer>();
        mr.material.EnableKeyword("_NEAR_FADE");
        Debug.LogError("Enable");
    }

    public void OnClickButton2()
    {
        Debug.LogError("Disable");
        MeshRenderer mr = cube.GetComponent<MeshRenderer>();
        mr.material.DisableKeyword("_NEAR_FADE");
    }
}

然后我们打包成exe,结果,无论你执行EnableKeyword还是DisableKeyword都是显示的绿色。
这是为啥呢?
因为我们在编辑器下,没有勾选Near Fade,所以unity也就未给我们生成_NEAR_FADE的变体。在打包成exe之后,也就没有这个变体的shader。所以你开启这个关键字也就不起作用了。

那么怎么办呢?
1、在编辑器下勾选Near Fade,生成对应变体:
在这里插入图片描述
这样查看shader变体:
在这里插入图片描述
就有FadeNear的变体了。在打包成exe之后,也就能通过开启关键字和关闭关键字了。

2、使用multi_compile
#pragma multi_compile _ _NEAR_FADE
这样无论你勾选材质球上的Fade Near与否,都会生成两个变体:
在这里插入图片描述
这样在打包成exe之后,开启和关闭关键字都是起效果的。

所以上面的一段话,建议最好使用multi_compile进行编译,因为不用关心是否有对应的变体。但是与之带来的坏处是,shader多了很多变体。
比如:
在这里插入图片描述

将会有8个变体:
在这里插入图片描述
所以读者自己斟酌选用吧。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值