Unity Shader - if 和 keyword 的指令比较

文章目录

  • 环境
  • TestingIf4Sample
    • [unity shaderlab 中的 TestingIf4Sample.shader](#unity shaderlab 中的 TestingIf4Sample.shader)
    • [graphics analyzer 中的 TestingIf4Sample.glsl](#graphics analyzer 中的 TestingIf4Sample.glsl)
  • TestingKW4Sample
    • [unity shaderlab 中的 TestingKW4Sample.shader](#unity shaderlab 中的 TestingKW4Sample.shader)
    • [graphics analyzer 中的 TestingKW4Sample.glsl](#graphics analyzer 中的 TestingKW4Sample.glsl)
  • 比较

环境

Unity : 2020.3.37f1

Pipeline : BRP


TestingIf4Sample

下面是 shaderlab 和 arm mobile studio 中的 graphics analyzer 的 glsl 代码


unity shaderlab 中的 TestingIf4Sample.shader

c 复制代码
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)

Shader "TestingIf4Sample"
{
    Properties
    {
        _A_Tex ("A Texture", 2D) = "white" {}
        _B_Tex ("B Texture", 2D) = "white" {}
        _USE_TEX_A ("Using Tex A", Float) = 1.0
    }
    SubShader
    {
        Tags
        {
            "Queue"="Geometry"
            "RenderType"="Opaque"
        }
        Pass
        {
            Name "Default"
        CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 2.0
            #include "UnityCG.cginc"
            struct appdata_t
            {
                float4 vertex   : POSITION;
                float2 texcoord : TEXCOORD0;
            };
            struct v2f
            {
                float4 vertex   : SV_POSITION;
                float2 texcoord  : TEXCOORD0;
            };
            sampler2D _A_Tex;
            sampler2D _B_Tex;
            fixed _USE_TEX_A;
            v2f vert(appdata_t v)
            {
                v2f OUT;
                float4 vPosition = UnityObjectToClipPos(v.vertex);
                OUT.vertex = vPosition;
                OUT.texcoord = v.texcoord.xy;
                return OUT;
            }
            fixed4 frag(v2f IN) : SV_Target
            {
                return _USE_TEX_A == 1.0 ? tex2D(_A_Tex, IN.texcoord) : tex2D(_B_Tex, IN.texcoord);
            }
        ENDCG
        }
    }
}

graphics analyzer 中的 TestingIf4Sample.glsl

VS

c 复制代码
#version 320 es

precision highp float;
precision highp int;
#define HLSLCC_ENABLE_UNIFORM_BUFFERS 1
#if HLSLCC_ENABLE_UNIFORM_BUFFERS
#define UNITY_UNIFORM
#else
#define UNITY_UNIFORM uniform
#endif
#define UNITY_SUPPORTS_UNIFORM_LOCATION 1
#if UNITY_SUPPORTS_UNIFORM_LOCATION
#define UNITY_LOCATION(x) layout(location = x)
#define UNITY_BINDING(x) layout(binding = x, std140)
#else
#define UNITY_LOCATION(x)
#define UNITY_BINDING(x) layout(std140)
#endif
uniform 	mediump float _USE_TEX_A;
UNITY_LOCATION(0) uniform mediump sampler2D _A_Tex;
UNITY_LOCATION(1) uniform mediump sampler2D _B_Tex;
in highp vec2 vs_TEXCOORD0;
layout(location = 0) out mediump vec4 SV_Target0;
vec4 u_xlat0;
bool u_xlatb0;
vec4 u_xlat1;
vec4 u_xlat2;
void main()
{
#ifdef UNITY_ADRENO_ES3
    u_xlatb0 = !!(_USE_TEX_A==1.0);
#else
    u_xlatb0 = _USE_TEX_A==1.0;
#endif
    u_xlat1 = texture(_A_Tex, vs_TEXCOORD0.xy);
    u_xlat2 = texture(_B_Tex, vs_TEXCOORD0.xy);
    u_xlat0 = (bool(u_xlatb0)) ? u_xlat1 : u_xlat2;
    SV_Target0 = u_xlat0;
    return;
}

FS

c 复制代码
#version 320 es

precision highp float;
precision highp int;
#define HLSLCC_ENABLE_UNIFORM_BUFFERS 1
#if HLSLCC_ENABLE_UNIFORM_BUFFERS
#define UNITY_UNIFORM
#else
#define UNITY_UNIFORM uniform
#endif
#define UNITY_SUPPORTS_UNIFORM_LOCATION 1
#if UNITY_SUPPORTS_UNIFORM_LOCATION
#define UNITY_LOCATION(x) layout(location = x)
#define UNITY_BINDING(x) layout(binding = x, std140)
#else
#define UNITY_LOCATION(x)
#define UNITY_BINDING(x) layout(std140)
#endif
uniform 	mediump float _USE_TEX_A;
UNITY_LOCATION(0) uniform mediump sampler2D _A_Tex;
UNITY_LOCATION(1) uniform mediump sampler2D _B_Tex;
in highp vec2 vs_TEXCOORD0;
layout(location = 0) out mediump vec4 SV_Target0;
vec4 u_xlat0;
bool u_xlatb0;
vec4 u_xlat1;
vec4 u_xlat2;
void main()
{
#ifdef UNITY_ADRENO_ES3
    u_xlatb0 = !!(_USE_TEX_A==1.0);
#else
    u_xlatb0 = _USE_TEX_A==1.0;
#endif
    u_xlat1 = texture(_A_Tex, vs_TEXCOORD0.xy);
    u_xlat2 = texture(_B_Tex, vs_TEXCOORD0.xy);
    u_xlat0 = (bool(u_xlatb0)) ? u_xlat1 : u_xlat2;
    SV_Target0 = u_xlat0;
    return;
}

TestingKW4Sample


下面是 shaderlab 和 glsl


unity shaderlab 中的 TestingKW4Sample.shader

c 复制代码
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)

Shader "TestingKW4Sample"
{
    Properties
    {
        _A_Tex ("A Texture", 2D) = "white" {}
        _B_Tex ("B Texture", 2D) = "white" {}
        [Toggle(_USE_TEX_A)]_USE_TEX_A ("Using Tex A", Float) = 1.0
    }
    SubShader
    {
        Tags
        {
            "Queue"="Geometry"
            "RenderType"="Opaque"
        }
        Pass
        {
            Name "Default"
        CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 2.0
            #pragma multi_compile _ _USE_TEX_A
            #include "UnityCG.cginc"
            struct appdata_t
            {
                float4 vertex   : POSITION;
                float2 texcoord : TEXCOORD0;
            };
            struct v2f
            {
                float4 vertex   : SV_POSITION;
                float2 texcoord  : TEXCOORD0;
            };
            sampler2D _A_Tex;
            sampler2D _B_Tex;
            v2f vert(appdata_t v)
            {
                v2f OUT;
                float4 vPosition = UnityObjectToClipPos(v.vertex);
                OUT.vertex = vPosition;
                OUT.texcoord = v.texcoord.xy;
                return OUT;
            }
            fixed4 frag(v2f IN) : SV_Target
            {
                #ifdef _USE_TEX_A
                    return tex2D(_A_Tex, IN.texcoord);
                #else
                    return tex2D(_B_Tex, IN.texcoord);
                #endif
            }
        ENDCG
        }
    }
}

graphics analyzer 中的 TestingKW4Sample.glsl

VS: 和上面的一样,就不复制上来的

主要看 FS:

c 复制代码
#version 320 es

precision highp float;
precision highp int;
#define UNITY_SUPPORTS_UNIFORM_LOCATION 1
#if UNITY_SUPPORTS_UNIFORM_LOCATION
#define UNITY_LOCATION(x) layout(location = x)
#define UNITY_BINDING(x) layout(binding = x, std140)
#else
#define UNITY_LOCATION(x)
#define UNITY_BINDING(x) layout(std140)
#endif
UNITY_LOCATION(0) uniform mediump sampler2D _A_Tex;
in highp vec2 vs_TEXCOORD0;
layout(location = 0) out mediump vec4 SV_Target0;
mediump vec4 u_xlat16_0;
void main()
{
    u_xlat16_0 = texture(_A_Tex, vs_TEXCOORD0.xy);
    SV_Target0 = u_xlat16_0;
    return;
}

比较

if 是指令实打实存在的

kw 原理是 macro 的 define,是在预编辑级别的分支,因此指令少一些也很正常

if 的推荐使用 记得是 if ... else ... 中 cycles 在 < 4 cycles 的,可以使用 if

否则还是使用 kw 的写法

下面的示例是 texture 的 sample,也就是 T unit 的采样

我印象中记得: (到时我再补回来,或是看到的大佬可以指导一下、分享一下资料)

  • register op: 1 cycles
  • sfu : 4~6 (忘记了)
  • texture sample : 300+ cyles

因此 T unit 优化是非常有必要的

相关推荐
海清河晏11115 小时前
数据结构 | 单链表
数据结构·unity·dreamweaver
mxwin17 小时前
Unity URP 下 MatCap 技术详解 无视光照环境的卡通与质感渲染方案
unity·游戏引擎
山檐雾2 天前
OctreeNode
unity·c#·八叉树
WarPigs2 天前
Unity协程返回值的解决方案
unity·游戏引擎
WarPigs2 天前
Unity单例笔记
unity·游戏引擎
Allen74743 天前
ComfyUI 自动化生产 3D资产 工作流笔记
图像处理·opencv·unity·自然语言处理·3d模型生成·confyui
nnsix3 天前
Unity Windows11 打字中文显示不出来输入法的候选框
unity
adogai3 天前
unity mcp接入 实现一句话生成游戏!
游戏·unity·游戏引擎
mxwin3 天前
Unity Shader 逐像素光照 vs 逐顶点光照性能与画质的权衡策略
unity·游戏引擎·shader·着色器
CDN3603 天前
游戏盾导致 Unity/UE 引擎崩溃的主要原因排查?
游戏·unity·游戏引擎