当前位置: 首页 > article >正文

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

请添加图片描述

法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
        }
    }
}

http://www.kler.cn/a/153752.html

相关文章:

  • Linux C语言 31-网络编程之TCP例程
  • 「随笔」编程中的技术难题与挑战
  • 操作系统,并行性:两个或多个事件在同一时刻发生并发性:两个或多个事件在同一时间间隔内发生 ,就绪状态执行状态阻塞状态
  • ⭐ Unity 开发bug —— 打包后shader失效或者bug (我这里用Shader做两张图片的合并发现了问题)
  • 代洋集团:太阳能充电宝,为您的未来充电
  • 统信UOS安装Virtualbox虚拟机和Windows10系统
  • Echarts大屏可视化_05 折线图的定制开发
  • Android Studio build.gradle获取项目绝对路径
  • LeetCode Hot100 287.寻找重复数
  • 剑指 Offer(第2版)题解(C++ Version)
  • Visual Studio Code之自动补全的设置
  • WPF不使用AllowsTransparency实现高性能透明背景异形窗体
  • MidJourney笔记(6)-Niji模式
  • 解决element ui tree组件不产生横向滚动条
  • JVM 类的加载
  • [Linux] 正则表达式及grep和awk
  • 微信小程序自定义tabBar简易实现
  • 二叉树的遍历及哈夫曼编码的代码思路及实现
  • Linux 系统是如何收发网络包的?(计算机网络)
  • 向量数据库,展望AGI时代