FairyGUI文本自定义shader

好久不写了,简单做个记录。

需求是在UI的数字上做个扫光效果,文字使用了TextMeshPro,需要自定义shader。

复制了“FairyGUI/TextMeshPro/Distance Field”,然后AI生成代码,就是方便。

        // === 扫光参数(无贴图版) ===
        _SweepColor      ("Sweep Color", Color) = (1,1,1,1)
        _SweepAngle      ("Sweep Angle (Rad)", Range(0, 6.2831853)) = 0.0
        _SweepPos        ("Sweep Position", Range(0,1)) = 0.0
        _SweepWidth      ("Sweep Width", Range(0,1)) = 0.2
        _SweepIntensity  ("Sweep Intensity", Range(0,2)) = 1.0


                // 计算屏幕空间 uv:NDC(-1~1) -> 0~1
                float2 ndc = vPosition.xy / vPosition.w;
                output.sweepUV = ndc * 0.5 + 0.5;


                // === 扫光叠加:颜色 + 角度 + 位置(0~1) + 宽度,使用屏幕空间 sweepUV ===
                {
                    float2 uv = input.sweepUV;

                    float2 dir = float2(cos(_SweepAngle), sin(_SweepAngle));
                    float coord = dot(uv - 0.5, dir) + 0.5;

                    float dist = abs(coord - _SweepPos);

                    float w = max(_SweepWidth, 1e-4);
                    float intensity = saturate(1.0 - dist / w);
                    intensity = smoothstep(0.0, 1.0, intensity);
                    intensity *= _SweepIntensity;
                    faceColor.rgb = lerp(faceColor.rgb, _SweepColor.rgb, intensity * _SweepColor.a);
                }

这里有个小坑,就是文本的atlas很大,直接取uv是不能用的。
这里是用屏幕空间计算的,但这样当文本移动时,扫光的位置不准确,好在我的文本是固定位置,能用就得呗。
然后就是替换材质,tween一个参数让它扫过去就行了:

                var mat = new Material(this.numberTitle.displayObject.material)
                {
                    shader = Shader.Find("FairyGUI/TextMeshPro/Distance Field Light Sweep")
                };
                this.numberTitle.displayObject.material = mat;
                this.UI_Enter.SetHook("LightSweep", LightSweep);

        private void LightSweep()
        {
            var m = this.numberTitle.displayObject.material;
            m.SetColor("_SweepColor", Color.white);
            m.SetFloat("_SweepAngle", 5.5f);
            m.SetFloat("_SweepWidth", 0.02f);
            GTween.ToDouble(0.2, 0.6, 2f).SetDelay(0.7f).OnUpdate((tweener =>
            {
                m?.SetFloat("_SweepPos", (float)tweener.value.x);
            }));
        }
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容