{"id":13784075,"url":"https://github.com/rubbyzhang/Unity_Image_Flash_Effect","last_synced_at":"2025-05-11T19:32:11.577Z","repository":{"id":75969632,"uuid":"85464620","full_name":"rubbyzhang/Unity_Image_Flash_Effect","owner":"rubbyzhang","description":"图片流光效果","archived":false,"fork":false,"pushed_at":"2017-04-04T16:32:07.000Z","size":693,"stargazers_count":15,"open_issues_count":0,"forks_count":5,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-01T15:02:02.278Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"GLSL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rubbyzhang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-03-19T09:31:29.000Z","updated_at":"2025-03-06T08:28:47.000Z","dependencies_parsed_at":"2024-01-17T03:17:30.909Z","dependency_job_id":"1090956c-bbfc-458c-9371-29bf16209cd0","html_url":"https://github.com/rubbyzhang/Unity_Image_Flash_Effect","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubbyzhang%2FUnity_Image_Flash_Effect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubbyzhang%2FUnity_Image_Flash_Effect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubbyzhang%2FUnity_Image_Flash_Effect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubbyzhang%2FUnity_Image_Flash_Effect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rubbyzhang","download_url":"https://codeload.github.com/rubbyzhang/Unity_Image_Flash_Effect/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253621169,"owners_count":21937488,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T19:00:35.125Z","updated_at":"2025-05-11T19:32:10.864Z","avatar_url":"https://github.com/rubbyzhang.png","language":"GLSL","readme":"###Unity  Shader 效果（1） ：图片流光效果\n\n@(Unity)\n\n\u003e很多游戏Logo中可以看到这种流光效果，一般的实现方案就是对带有光条的图片uv根据时间进行移动，然后和原图就行叠加实现，不过实现过程中稍稍有点需要注意的地方。之前考虑过[风宇冲](http://blog.sina.com.cn/s/blog_471132920101d8zf.html)的实现方式，但是考虑到shader中太多的计算，还是放弃了。\n![mark](http://ohzzlljrf.bkt.clouddn.com/blog/20170319/165737095.png)\n#### 基础版本\n```\nShader \"UICustom/ImageFlashEffect2\"\n{\n\tProperties\n\t{\n\t\t_MainTex (\"Main Texture\", 2D) = \"white\" {}\n\n\t\t_LightTex (\"Light Texture\", 2D) = \"white\" {}\n\n\t\t_LightColor(\"Light Color\",Color) = (1,1,1,1)\n\n\t\t_LightPower(\"Light Power\",Range(0,5)) = 1\n\n\t\t//每次持续时间，受Angle和Scale影响\n\t\t_LightDuration(\"Light Duration\",Range(0,10)) = 1\n\t\t//时间间隔，受Angle和Scale影响\n\t\t_LightInterval(\"Light Interval\",Range(0,20)) = 3\n\t}\n\n\tSubShader\n\t{\n\t\tTags \n\t\t{\n\t\t\t\"Queue\"=\"Transparent\" \n\t\t\t\"IgnoreProjector\"=\"True\" \n\t\t\t\"RenderType\"=\"Transparent\"\n\t\t}\n\n\t\tCull Off\n\t\tLighting Off\n\t\tZWrite Off\n\t\tFog { Mode Off }\n\t\tOffset -1, -1\n\t\tBlend SrcAlpha OneMinusSrcAlpha \n        AlphaTest Greater 0.1\n\n\t\tPass\n\t\t{\n\t\t\tCGPROGRAM\n\t\t\t#pragma vertex vert\n\t\t\t#pragma fragment frag\n\t\t\t\n\t\t\t#include \"UnityCG.cginc\"\n\n\t\t\tstruct appdata\n\t\t\t{\n\t\t\t\tfloat4 vertex : POSITION;\n\t\t\t\tfloat2 uv : TEXCOORD0;\n\t\t\t};\n\n\t\t\tstruct v2f\n\t\t\t{\n\t\t\t\tfloat2 uv : TEXCOORD0;\n\t\t\t\tfloat4 vertex : SV_POSITION;\n\t\t\t\tfloat2 lightuv : TEXCOORD1;\n\t\t\t};\n\n\t\t\tsampler2D _MainTex;\n\t\t\tfloat4 _MainTex_ST;\n\n\t\t\tsampler2D _LightTex ;\n\t\t\tfloat4  _LightTex_ST;\n\n\t\t\thalf _LightInterval ;\n\t\t\thalf _LightDuration ;\n\n\t\t\thalf4 _LightColor ;\n\t\t\thalf _LightPower ;\n\n\t\t\thalf _LightOffSetX ;\n\t\t\thalf _LightOffSetY ;\n\n\t\t\tv2f vert (appdata v)\n\t\t\t{\n\t\t\t\tv2f o;\n\t\t\t\to.vertex = mul(UNITY_MATRIX_MVP, v.vertex);\n                fixed currentTimePassed = fmod(_Time.y,_LightInterval);\n\t\t\t\t//uv offset, Sprite wrap mode need \"Clamp\"\n\t\t\t\tfixed offsetX = currentTimePassed / _LightDuration;\n\t\t\t\tfixed offsetY = currentTimePassed / _LightDuration；\n\t\t\t\tfixed2 offset ;\n\t\t\t\toffset.x = offsetX - 0.5f;\n\t\t\t\toffset.y = offsetY - 0.5f;\n\n\t\t\t\to.lightuv = v.uv  + offset ;\n\n\t\t\t\to.uv\t\t = TRANSFORM_TEX(v.uv, _MainTex);\n\t\t\t\to.lightuv    = TRANSFORM_TEX(o.lightuv, _LightTex);\n\t\t\t\treturn o;\n\t\t\t}\n\t\t\t\n\t\t\tfixed4 frag (v2f i) : SV_Target\n\t\t\t{\n\t\t\t\tfixed4 mainCol   = tex2D(_MainTex, i.uv);\n\t\t\t\tfixed4 lightCol  = tex2D(_LightTex, i.lightuv);\n\t\t\t\tlightCol *= _LightColor ;\n\n\t\t\t\t//need blend\n\t\t\t\t//lightCol.rgb *= mainCol.rgb ;\n\t\t\t\tfixed4 fininalCol ;\n\t\t\t\tfininalCol.rgb   = mainCol.rgb +  lightCol.rgb * _LightPower;\n\t\t\t\tfininalCol.a =  mainCol.a * lightCol.a ;\n\t\t\t\treturn fininalCol ;\n\t\t\t}\n\t\t\tENDCG\n\t\t}\n\t}\n}\n```\n需要注意的点：\n1. 时间间隔问题\n```\nfixed currentTimePassed = fmod(_Time.y,_LightInterval);\n//uv offset, Sprite wrap mode need \"Clamp\"\nfixed offsetX = currentTimePassed / _LightDuration;\nfixed offsetY = currentTimePassed / _LightDuration；\n```\n\u003e offsetX 、offsetY其实是0~_LightInterval的数值，需要设置图片为光线图片的Wrap模式为Clamp，才能实现时间间隔控制\n2. 色彩融合\nPixel着色器中frag()函数是通过原始颜色和光线颜色叠加的方式实现的，也有将光线颜色和原图混合后再叠加的做法，这个我觉得看实际应用。注意alpha的控制\n\n#### 优化\n##### 1. 增加角度和大小控制\n基本版本的实现中光线只能根据流光图片中亮线的宽度和方向决定实际的滚动方向和大小。有时候如果需要经常调节方向和大小，可以考虑加入相关因素。流光的Uv是通过原图当前Uv加上时间轴参数获得，可以考虑通过修改流光uv的计算方式来实现。如下面代码。不过这种方式增加了一定计算量，不需要的话则直接跳过。还有一点就是流光贴图必须是垂直或者水平，不然\n```\nfloat2 base = v.uv ;\nbase.x -= _LightOffSetX ;\nbase.y -= _LightOffSetX ;\nbase = base / _LightScale ;\n\nfloat2 base2 = v.uv;\nbase2.x  = base.x * cosInRad - base.y * sinInRad ;\nbase2.y  = base.y * cosInRad + base.x * sinInRad ;\n\no.lightuv = base2 + offset ;\n```\n##### 材质复用\n只是想不同的图片都是使用相同的材质，应该保证每个图片的效果都可以独立进行修改保存，可以考虑每张图片都创建一份材质，然后修改其参数。\n```\n   void UpdateParam()\n   {\n       if (Material == null)\n       {\n           Debug.LogWarning(\"Metarial is miss\");\n           return;\n       }\n\n       if (mGraphic == null)\n       {\n           mGraphic = GetComponent\u003cMaskableGraphic\u003e();\n       }\n\n       if (mGraphic is Text)\n       {\n           Debug.LogError(\"FlashEffec need component type of Image、RawImage\");\n           return;\n       }\n\n       if (mDynaMaterial == null)\n       {\n           mDynaMaterial = new Material(Material);\n           mDynaMaterial.name = mDynaMaterial.name + \"(Copy)\";\n           mDynaMaterial.hideFlags = HideFlags.DontSave | HideFlags.NotEditable;\n       }\n\n       if (mDynaMaterial == null)\n       {\n           return;\n       }\n\n       mDynaMaterial.mainTexture = null;\n       if (OverrideTexture != null)\n       {\n           mDynaMaterial.mainTexture = OverrideTexture;\n\n           if (mGraphic is RawImage)\n           {\n               RawImage img = mGraphic as RawImage;\n               img.texture = null;\n           }\n           else if (mGraphic is Image)\n           {\n               Image img = mGraphic as Image;\n               img.sprite = null;\n           }\n       }\n       else\n       {\n           mDynaMaterial.mainTexture = mGraphic.mainTexture;\n       }\n\n       if (Duration \u003e Interval)\n       {\n           Debug.LogWarning(\"ImageFlashEffect.UpdateParam:Duration need less Interval\");\n           Interval = Duration + 0.5f;\n       }\n\n       mDynaMaterial.SetColor(\"_LightColor\", Color);\n       mDynaMaterial.SetFloat(\"_LightPower\", Power);\n       mDynaMaterial.SetFloat(\"_LightScale\", Scale);\n       mDynaMaterial.SetFloat(\"_LightAngle\", Angle);\n       mDynaMaterial.SetFloat(\"_LightDuration\", Duration);\n       mDynaMaterial.SetFloat(\"_LightInterval\", Interval);\n       mDynaMaterial.SetFloat(\"_LightOffSetX\", OffSet);\n       mGraphic.material = mDynaMaterial;\n       mGraphic.SetMaterialDirty();\n   }\n```\n\n#### 参考\nhttp://blog.csdn.net/qq992817263/article/details/51200424\nhttp://qkxue.net/info/169189/Unity-Simple-Shaderlab-uGui-shader-1\n\n\n","funding_links":[],"categories":["Post Effect"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubbyzhang%2FUnity_Image_Flash_Effect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frubbyzhang%2FUnity_Image_Flash_Effect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubbyzhang%2FUnity_Image_Flash_Effect/lists"}