Unity中Shader编译目标级别

文章目录

  • 前言
  • 一、Shader Model
  • 二、Shader编译目标级别
    • 法1: #pragma target 3.0
    • 法2:#pragma require integers geometry
  • 三、测试代码


前言

针对不同平台的特性,所做的一些功能


一、Shader Model

  • ShaderModel 由微软提出,要求显卡厂商按 SM 级别提供对应的功能与指令支持
  • 不同的SM包含不同的指令集与Shader规范
  • 高版本的SM时低版本的超集
  • 微软Shader帮助文档

二、Shader编译目标级别

法1: #pragma target 3.0

Shader编绎目标级别,默认值为2.5
可以通过#if (SHADER_TARGET < 30)来做分支判断
● 2.0:
● 2.5: derivatives
● 3.0: 2.5 + interpolators10 + samplelod + fragcoord
● 3.5(相当于OpenGL ES3.0): 3.0 + interpolators15 + mrt4 + integers + 2darray + instancing
● 4.0: 3.5 + geometry
● 4.5(相当于OpenGL ES3.1): 3.5 + compute + randomwrite
● 4.6: 4.0 + cubearray + tesshw + tessellation
● 5.0: 4.0 + compute + randomwrite + tesshw + tessellation

  • #pragma target怎么用?
    可以结合 CGINCLUDE 来实现多个 SubShader 共用 一个 CG 代码段

  • 1、把CGPROGRAM中需要共用的代码,移入CGINCLUDE 内

 CGINCLUDE
    #include "UnityCG.cginc"
    struct appdata
    {
        float4 vertex : POSITION;
        float2 uv : TEXCOORD0;
    };

    struct v2f
    {
        float2 uv : TEXCOORD0;
        float4 vertex : SV_POSITION;
    };


    v2f vert(appdata v)
    {
        v2f o;
        o.vertex = UnityObjectToClipPos(v.vertex);
        return o;
    }

    fixed4 frag(v2f i) : SV_Target
    {
        return 1;
    }
    ENDCG
  • 2、写出 高配 和 低配 对应的 SubShader
//高配
    SubShader
    {
        Tags
        {
            "RenderType"="Opaque"
        }
        LOD 600

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 3.0
            ENDCG
        }
    }
    //低配
    SubShader
    {
        Tags
        {
            "RenderType"="Opaque"
        }
        LOD 200

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 2.0
            ENDCG
        }
    }
  • 3、在 CGINCLUDE 的代码块中,使用 SHADER_TARGET 来判断不同配置(target 2.0 对应 SHADER_TARGET = 20,其他以此类推)

fixed4 frag(v2f i) : SV_Target
{
#if (SHADER_TARGET < 30)
//低配返回黑色
return 0;
#else
//高配返回 白色
return 1;
#endif
}

  • 4、然后,在场景中使用我们之前使用的 ShaderLOD C# 控制脚本来改变 LOD 看看效果
  • Unity中Shader的ShaderLOD

Unity中Shader编译目标级别_第1张图片

法2:#pragma require integers geometry

表明shader需要的特性功能
● interpolators10: 至少支持10个插值器(从顶点到片断)
● interpolators15: 至少支持15个插值器(从顶点到片断)
● interpolators32: 至少支持32个插值器(从顶点到片断)
● mrt4: 至少支持4个Multiple Render Targets
● mrt8: 至少支持8个Multiple Render Targets
● derivatives: 片断着色器支持偏导函数(ddx/ddy)
● samplelod: 纹理LOD采样
● fragcoord: 将像素的位置(XY为屏幕上的坐标,ZW为齐次裁剪空间下的深度)传入到片断着色器中
● integers: 支持真正的整数类型,包括位/移位操作
● 2darray: 2D纹理数组
● cubearray: Cubemap纹理数组
● instancing: GPU实例化
● geometry: 几何着色器
● compute: Compute Shader
● randomwrite: 可以编写任意位置的一些纹理和缓冲区 (UAV,unordered access views)
● tesshw: GPU支持硬件的tessellation
● tessellation: Tessellation hull/domain Shader
● msaatex: 能够访问多采样纹理
● framebufferfetch: 主要用于在延迟渲染中减少采样的带宽消耗


三、测试代码

Shader "MyShader/P2_3_3"
{
    CGINCLUDE
    #include "UnityCG.cginc"
    struct appdata
    {
        float4 vertex : POSITION;
        float2 uv : TEXCOORD0;
    };

    struct v2f
    {
        float2 uv : TEXCOORD0;
        float4 vertex : SV_POSITION;
    };


    v2f vert(appdata v)
    {
        v2f o;
        o.vertex = UnityObjectToClipPos(v.vertex);
        return o;
    }

    fixed4 frag(v2f i) : SV_Target
    {
        #if (SHADER_TARGET < 30)
            return 0;
        #else
            return 1;
        #endif
    }
    ENDCG

    //高配
    SubShader
    {
        Tags
        {
            "RenderType"="Opaque"
        }
        LOD 400

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 3.0
            ENDCG
        }
    }
    //低配
    SubShader
    {
        Tags
        {
            "RenderType"="Opaque"
        }
        LOD 200

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 2.0
            ENDCG
        }
    }
}

你可能感兴趣的:(Unity,unity,游戏引擎)