diff options
Diffstat (limited to 'Assets/Scripts/Unit/LensEffect/LensEffects.cs')
-rw-r--r-- | Assets/Scripts/Unit/LensEffect/LensEffects.cs | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/Assets/Scripts/Unit/LensEffect/LensEffects.cs b/Assets/Scripts/Unit/LensEffect/LensEffects.cs new file mode 100644 index 00000000..4083eb88 --- /dev/null +++ b/Assets/Scripts/Unit/LensEffect/LensEffects.cs @@ -0,0 +1,166 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Rendering; + +public class MaterialEntry +{ + public Material material; + public string shader; +} + +public struct ScaleOffset +{ + public Vector2 scale; + public Vector2 offset; +} + +public class LensEffect +{ + #region callbacks + public delegate void BeforeIterateHandler(CommandBuffer cb); + public BeforeIterateHandler beforeIterate; + + public delegate void IterationHandler(CommandBuffer cb, BodyPartRenderer renderer); + public IterationHandler iterate; + + public delegate void AfterIterateHandler(CommandBuffer cb); + public AfterIterateHandler afterIterate; + + // 这一帧的这个特效结束 + public delegate void FinishRenderHandler(); + public FinishRenderHandler finishRender; + #endregion + + private static Dictionary<string/*shaderName*/, List<MaterialEntry>> m_MaterailPool; + + public static LensEffect Create(Func<LensEffect> create) + { + return create(); + } + + static LensEffect() + { + m_MaterailPool = new Dictionary<string, List<MaterialEntry>>(); + } + + static MaterialEntry ClaimMaterial(string shader) + { + List<MaterialEntry> mats; + if (m_MaterailPool.TryGetValue(shader, out mats) && mats.Count > 0) + { + MaterialEntry me = mats[mats.Count - 1]; + mats.RemoveAt(mats.Count - 1); + return me; + } + Material mat = new Material(Shader.Find(shader)); + MaterialEntry entry = new MaterialEntry(); + entry.material = mat; + entry.shader = shader; + return entry; + } + + static void ReleaseMaterial(MaterialEntry entry) + { + List<MaterialEntry> mats; + if (!m_MaterailPool.TryGetValue(entry.shader, out mats)) + { + mats = new List<MaterialEntry>(); + m_MaterailPool.Add(entry.shader, mats); + } + mats.Add(entry); + } + + #region LensEffects + + public static LensEffect MotionBlur() + { + LensEffect eff = LensEffect.Create(() => + { + LensEffect e = new LensEffect(); + + List<MaterialEntry> materials = ListPool<MaterialEntry>.Get(); + int tempID = Shader.PropertyToID("_Temp1"); + + ScaleOffset scaleOffset = new ScaleOffset(); + + e.beforeIterate = (CommandBuffer cb) => + { + cb.GetTemporaryRT(tempID, -1, -1, 24, FilterMode.Bilinear); + cb.SetRenderTarget(tempID); + cb.ClearRenderTarget(true, true, new Color(0, 0, 0, 0)); + }; + e.iterate = (CommandBuffer cb, BodyPartRenderer renderer) => + { + Matrix4x4 obj2Wod = Matrix4x4.identity; + int subMeshCount = 0; + if (renderer.renderer is SkinnedMeshRenderer) + { + SkinnedMeshRenderer smr = renderer.renderer as SkinnedMeshRenderer; + Vector3 pos = smr.rootBone.transform.position; + Quaternion rot = smr.rootBone.transform.rotation; + obj2Wod = MatrixUtility.RotateAndTranslate(pos, rot); + subMeshCount = smr.sharedMesh.subMeshCount; + } + else if (renderer.renderer is MeshRenderer) + { + obj2Wod = renderer.renderer.transform.localToWorldMatrix; + subMeshCount = renderer.renderer.GetComponent<MeshFilter>().sharedMesh.subMeshCount; + } + + for (int i = 0; i < subMeshCount; ++i) + { + MaterialEntry mat = ClaimMaterial(StaticDefine.shaders[EShader.SolidColor].name); + materials.Add(mat); + mat.material.SetColor("_Color", Color.red); + mat.material.SetMatrix("_ObjectToWorld", obj2Wod); + + cb.DrawRenderer(renderer.renderer, mat.material, i); + } + }; + e.afterIterate = (CommandBuffer cb) => + { + MaterialEntry blur = ClaimMaterial(StaticDefine.shaders[EShader.Blur].name); + materials.Add(blur); + + cb.Blit(tempID, BuiltinRenderTextureType.CameraTarget, blur.material); + }; + e.finishRender = () => + { + for (int i = materials.Count - 1; i >= 0; --i) + { + MaterialEntry mat = materials[i]; + ReleaseMaterial(mat); + materials.RemoveAt(i); + } + }; + return e; + }); + return eff; + } + + public static LensEffect Glitch() + { + + return null; + } + + public static LensEffect OutLine() + { + + return null; + } + + public static LensEffect RimLight() + { + return null; + } + + public static LensEffect Decals() + { + return null; + } + + #endregion +} |