summaryrefslogtreecommitdiff
path: root/Assets/Scripts/Unit/LensEffect/LensEffects.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Assets/Scripts/Unit/LensEffect/LensEffects.cs')
-rw-r--r--Assets/Scripts/Unit/LensEffect/LensEffects.cs166
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
+}