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

Unity Shader - UI Sprite Shader之抠图+纯色

  1. 添加一个 _SolidColor 属性,用于指定纯色。

  2. 添加一个 _UseSolidColor 属性,用于控制是否启用纯色模式。

  3. 在片段着色器中,根据 _UseSolidColor 的值决定是否将图像替换为纯色。

以下是修改后的Shader代码:

Shader "Demo/SpriteShader"
{
    Properties
    {
        [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
        _Color ("Alpha Color Key", Color) = (0,0,0,1)
        _Range("Range", Range(0, 1.01)) = 0.1
        _SolidColor("Solid Color", Color) = (1,1,1,1) // 新增:纯色属性
        _UseSolidColor("Use Solid Color", Float) = 0 // 新增:是否启用纯色模式
        [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
    }
    SubShader
    {
        Tags 
        { 
            "Queue"="Transparent" 
            "IgnoreProjector"="True" 
            "RenderType"="Transparent" 
            "PreviewType"="Plane"
            "CanUseSpriteAtlas"="True"
        }

        // 关键修复:添加Stencil块以支持Mask组件
        Stencil
        {
            Ref 1
            Comp Equal
            Pass Keep
            Fail Keep
        }

        Pass
        {
            Cull Off
            Lighting Off
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile _ PIXELSNAP_ON

            sampler2D _MainTex;
            float4 _Color;
            half _Range;
            float4 _SolidColor; // 新增:纯色属性
            float _UseSolidColor; // 新增:是否启用纯色模式

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

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

            v2f vert(appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                #ifdef PIXELSNAP_ON
                o.vertex = UnityPixelSnap(o.vertex);
                #endif
                return o;
            }

            half4 frag(v2f IN) : SV_Target
            {
                half4 c = tex2D(_MainTex, IN.uv);
                
                // 计算颜色差值
                half3 diff = abs(c.rgb - _Color.rgb);
                half maxDiff = max(diff.r, max(diff.g, diff.b));
                
                // 使用clip函数直接丢弃像素,兼容AlphaTest
                clip(maxDiff - _Range);

                // 新增:纯色模式
                if (_UseSolidColor > 0.5)
                {
                    c.rgb = _SolidColor.rgb; // 替换为纯色
                    c.a *= _SolidColor.a; // 保留原始Alpha值,与纯色的Alpha混合
                }

                return c;
            }
            ENDCG
        }
    }
}

新增功能说明

  1. _SolidColor 属性

    • 用于指定纯色的颜色值。

    • 在材质面板中可以调整颜色。

  2. _UseSolidColor 属性

    • 用于控制是否启用纯色模式。

    • 值为 1 时启用纯色模式,值为 0 时禁用。

  3. 纯色模式逻辑

    • 在片段着色器中,如果 _UseSolidColor > 0.5,则将像素颜色替换为 _SolidColor

    • 同时保留原始Alpha值,与 _SolidColor 的Alpha混合,确保透明效果正确。

使用示例

  1. 创建材质

    • 将Shader赋给一个材质。

    • 在材质面板中设置 _SolidColor 为你想要的纯色(例如红色 (1,0,0,1))。

    • 勾选 _UseSolidColor 启用纯色模式。

  2. 应用到RawImage

    • 将材质赋给 RawImage 组件。

    • 运行场景,观察图像是否被替换为纯色。

  3. 动态切换纯色模式

    • 可以通过脚本动态修改 _UseSolidColor 的值,实现纯色模式的开关:

Material material = rawImage.material;
material.SetFloat("_UseSolidColor", 1); // 启用纯色模式
material.SetFloat("_UseSolidColor", 0); // 禁用纯色模式

效果展示

  • 禁用纯色模式
    图像正常显示,抠图逻辑生效。

  • 启用纯色模式
    图像被替换为指定的纯色,同时保留抠图逻辑(透明区域仍然透明)。


注意事项

  1. Alpha混合

    • 如果 _SolidColor 的Alpha值小于 1,图像会与背景混合。

    • 如果需要完全不透明,可以将 _SolidColor 的Alpha值设为 1

  2. 性能优化

    • 如果不需要动态切换纯色模式,可以将 _UseSolidColor 设为材质常量,避免每帧上传。

  3. 兼容性

    • 该Shader兼容 Mask 组件,确保裁剪效果正常。

通过以上修改,你的Shader现在既能实现抠图功能,又能将图像处理为纯色,满足更多使用场景!

相关文章:

  • 深入理解 lt; 和 gt;:HTML 实体转义的核心指南!!!
  • OpenHarmony子系统开发 - 电源管理(二)
  • NVMe(Non-Volatile Memory Express)详解
  • 如何在 Redis 中使用哈希(Hash)数据类型存储和管理对象数据的详细指南
  • 【mysql】唯一性约束unique
  • 常考计算机操作系统面试习题(二)(上)
  • 云服务器运维
  • w266农产品直卖平台的设计与实现
  • 关于在vscode中的Linux 0.11 应用程序项目的生成和运行
  • 稳定运行的以ElasticSearch数据库为数据源和目标的ETL性能变差时提高性能方法和步骤
  • new Proxy的应用
  • 《AI大模型趣味实战》第6集:基于大模型和RSS聚合打造个人新闻电台
  • QGroupBox取消勾选时不禁用子控件
  • 人工智能在医疗影像诊断中的应用与挑战
  • 【红黑树封装map和set】—— 我与C++的不解之缘(二十六)
  • Java之网络编程
  • [前端面试场景题]虚拟列表
  • OceanBase数据库基于脚本的分布式存储层性能深度优化
  • C++:背包问题习题
  • 022-spdlog
  • 默茨在第二轮投票中当选德国总理
  • 世界银行最新营商环境体检单:59个测评点,上海22项达全球最优水平
  • 上海市政府常务会议部署提升入境旅游公共服务水平,让国际友人“无障碍”畅游上海
  • A股高开高走,三大股指涨超1.1%:两市成交1.3万亿元,近5000股收涨
  • 10家A股农商行去年年报:瑞丰银行营收增速领跑,常熟银行等4家净利增速超11%
  • 这样喝酸奶相当于在喝糖水,会导致娃龋齿、肥胖