From 6eb915c129fc90c6f4c82ae097dd6ffad5239efc Mon Sep 17 00:00:00 2001 From: chai Date: Mon, 25 Jan 2021 14:28:30 +0800 Subject: +scripts --- Client/Assets/Scripts/PostEffect/Bloom.cs | 335 ++++++++++ Client/Assets/Scripts/PostEffect/Bloom.cs.meta | 8 + Client/Assets/Scripts/PostEffect/BloomHelper.cs | 215 +++++++ .../Assets/Scripts/PostEffect/BloomHelper.cs.meta | 8 + .../Scripts/PostEffect/ContrastStretchEffect.cs | 194 ++++++ .../PostEffect/ContrastStretchEffect.cs.meta | 12 + Client/Assets/Scripts/PostEffect/DOFHelper.cs | 383 +++++++++++ Client/Assets/Scripts/PostEffect/DOFHelper.cs.meta | 8 + Client/Assets/Scripts/PostEffect/FastBloom.cs | 98 +++ Client/Assets/Scripts/PostEffect/FastBloom.cs.meta | 8 + Client/Assets/Scripts/PostEffect/FxPro.cs | 699 +++++++++++++++++++++ Client/Assets/Scripts/PostEffect/FxPro.cs.meta | 8 + Client/Assets/Scripts/PostEffect/MobileBloom.cs | 118 ++++ .../Assets/Scripts/PostEffect/MobileBloom.cs.meta | 8 + .../Assets/Scripts/PostEffect/MobileDOFHelper.cs | 158 +++++ .../Scripts/PostEffect/MobileDOFHelper.cs.meta | 8 + .../Scripts/PostEffect/MobilePostEffectsBase.cs | 214 +++++++ .../PostEffect/MobilePostEffectsBase.cs.meta | 8 + .../Assets/Scripts/PostEffect/PostEffectsBase.cs | 214 +++++++ .../Scripts/PostEffect/PostEffectsBase.cs.meta | 8 + .../Scripts/PostEffect/RenderTextureManager.cs | 232 +++++++ .../PostEffect/RenderTextureManager.cs.meta | 8 + 22 files changed, 2952 insertions(+) create mode 100644 Client/Assets/Scripts/PostEffect/Bloom.cs create mode 100644 Client/Assets/Scripts/PostEffect/Bloom.cs.meta create mode 100644 Client/Assets/Scripts/PostEffect/BloomHelper.cs create mode 100644 Client/Assets/Scripts/PostEffect/BloomHelper.cs.meta create mode 100644 Client/Assets/Scripts/PostEffect/ContrastStretchEffect.cs create mode 100644 Client/Assets/Scripts/PostEffect/ContrastStretchEffect.cs.meta create mode 100644 Client/Assets/Scripts/PostEffect/DOFHelper.cs create mode 100644 Client/Assets/Scripts/PostEffect/DOFHelper.cs.meta create mode 100644 Client/Assets/Scripts/PostEffect/FastBloom.cs create mode 100644 Client/Assets/Scripts/PostEffect/FastBloom.cs.meta create mode 100644 Client/Assets/Scripts/PostEffect/FxPro.cs create mode 100644 Client/Assets/Scripts/PostEffect/FxPro.cs.meta create mode 100644 Client/Assets/Scripts/PostEffect/MobileBloom.cs create mode 100644 Client/Assets/Scripts/PostEffect/MobileBloom.cs.meta create mode 100644 Client/Assets/Scripts/PostEffect/MobileDOFHelper.cs create mode 100644 Client/Assets/Scripts/PostEffect/MobileDOFHelper.cs.meta create mode 100644 Client/Assets/Scripts/PostEffect/MobilePostEffectsBase.cs create mode 100644 Client/Assets/Scripts/PostEffect/MobilePostEffectsBase.cs.meta create mode 100644 Client/Assets/Scripts/PostEffect/PostEffectsBase.cs create mode 100644 Client/Assets/Scripts/PostEffect/PostEffectsBase.cs.meta create mode 100644 Client/Assets/Scripts/PostEffect/RenderTextureManager.cs create mode 100644 Client/Assets/Scripts/PostEffect/RenderTextureManager.cs.meta (limited to 'Client/Assets/Scripts/PostEffect') diff --git a/Client/Assets/Scripts/PostEffect/Bloom.cs b/Client/Assets/Scripts/PostEffect/Bloom.cs new file mode 100644 index 00000000..d7c17c40 --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/Bloom.cs @@ -0,0 +1,335 @@ +using UnityEngine; +using System.Collections; + +[ExecuteInEditMode] +[RequireComponent(typeof(Camera))] +public class Bloom : PostEffectsBase +{ + public enum LensFlareStyle { + Ghosting = 0, + Anamorphic = 1, + Combined = 2, + } + + public enum TweakMode { + Basic = 0, + Complex = 1, + } + + public enum HDRBloomMode { + Auto = 0, + On = 1, + Off = 2, + } + + public enum BloomScreenBlendMode { + Screen = 0, + Add = 1, + } + + public enum BloomQuality { + Cheap = 0, + High = 1, + } + + public TweakMode tweakMode = TweakMode.Basic; + public BloomScreenBlendMode screenBlendMode = BloomScreenBlendMode.Add; + + public HDRBloomMode hdr = HDRBloomMode.Auto; + private bool doHdr = false; + public float sepBlurSpread = 2.5f; + + public BloomQuality quality = BloomQuality.High; + + public float bloomIntensity = 0.5f; + public float bloomThreshhold = 0.5f; + public Color bloomThreshholdColor = Color.white; + public int bloomBlurIterations = 2; + + public int hollywoodFlareBlurIterations = 2; + public float flareRotation = 0.0f; + public LensFlareStyle lensflareMode = LensFlareStyle.Anamorphic; + public float hollyStretchWidth = 2.5f; + public float lensflareIntensity = 0.0f; + public float lensflareThreshhold = 0.3f; + public float lensFlareSaturation = 0.75f; + public Color flareColorA = new Color (0.4f, 0.4f, 0.8f, 0.75f); + public Color flareColorB = new Color(0.4f, 0.8f, 0.8f, 0.75f); + public Color flareColorC = new Color(0.8f, 0.4f, 0.8f, 0.75f); + public Color flareColorD = new Color(0.8f, 0.4f, 0.0f, 0.75f); + public float blurWidth = 1.0f; + public Texture2D lensFlareVignetteMask; + + public Shader lensFlareShader; + private Material lensFlareMaterial; + + public Shader screenBlendShader; + private Material screenBlend; + + public Shader blurAndFlaresShader; + private Material blurAndFlaresMaterial; + + public Shader brightPassFilterShader; + private Material brightPassFilterMaterial; + + new bool CheckResources () + { + CheckSupport (false); + + screenBlend = CheckShaderAndCreateMaterial (screenBlendShader, screenBlend); + lensFlareMaterial = CheckShaderAndCreateMaterial(lensFlareShader,lensFlareMaterial); + blurAndFlaresMaterial = CheckShaderAndCreateMaterial (blurAndFlaresShader, blurAndFlaresMaterial); + brightPassFilterMaterial = CheckShaderAndCreateMaterial(brightPassFilterShader, brightPassFilterMaterial); + + if(!isSupported) + ReportAutoDisable (); + return isSupported; + } + + void OnRenderImage (RenderTexture source,RenderTexture destination) { + if(CheckResources()==false) { + Graphics.Blit (source, destination); + return; + } + + // screen blend is not supported when HDR is enabled (will cap values) + + doHdr = false; + if(hdr == HDRBloomMode.Auto) + doHdr = source.format == RenderTextureFormat.ARGBHalf && GetComponent().hdr; + else { + doHdr = hdr == HDRBloomMode.On; + } + + doHdr = doHdr && supportHDRTextures; + + BloomScreenBlendMode realBlendMode = screenBlendMode; + if(doHdr) + realBlendMode = BloomScreenBlendMode.Add; + + var rtFormat = (doHdr) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.Default; + var rtW2 = source.width/2; + var rtH2 = source.height/2; + var rtW4 = source.width/4; + var rtH4 = source.height/4; + + float widthOverHeight = (1.0f * source.width) / (1.0f * source.height); + float oneOverBaseSize = 1.0f / 512.0f; + + // downsample + RenderTexture quarterRezColor = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat); + RenderTexture halfRezColorDown = RenderTexture.GetTemporary (rtW2, rtH2, 0, rtFormat); + if(quality > BloomQuality.Cheap) { + Graphics.Blit (source, halfRezColorDown, screenBlend, 2); + RenderTexture rtDown4 = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat); + Graphics.Blit (halfRezColorDown, rtDown4, screenBlend, 2); + Graphics.Blit (rtDown4, quarterRezColor, screenBlend, 6); + RenderTexture.ReleaseTemporary(rtDown4); + } + else { + Graphics.Blit (source, halfRezColorDown); + Graphics.Blit (halfRezColorDown, quarterRezColor, screenBlend, 6); + } + RenderTexture.ReleaseTemporary (halfRezColorDown); + + // cut colors (threshholding) + RenderTexture secondQuarterRezColor = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat); + BrightFilter (bloomThreshhold * bloomThreshholdColor, quarterRezColor, secondQuarterRezColor); + + // blurring + + if (bloomBlurIterations < 1) bloomBlurIterations = 1; + else if (bloomBlurIterations > 10) bloomBlurIterations = 10; + + for (int iter = 0; iter < bloomBlurIterations; iter++ ) { + float spreadForPass = (1.0f + (iter * 0.25f)) * sepBlurSpread; + + // vertical blur + RenderTexture blur4 = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat); + blurAndFlaresMaterial.SetVector ("_Offsets", new Vector4 (0.0f, spreadForPass * oneOverBaseSize, 0.0f, 0.0f)); + Graphics.Blit (secondQuarterRezColor, blur4, blurAndFlaresMaterial, 4); + RenderTexture.ReleaseTemporary(secondQuarterRezColor); + secondQuarterRezColor = blur4; + + // horizontal blur + blur4 = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat); + blurAndFlaresMaterial.SetVector("_Offsets", new Vector4((spreadForPass / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f)); + Graphics.Blit (secondQuarterRezColor, blur4, blurAndFlaresMaterial, 4); + RenderTexture.ReleaseTemporary (secondQuarterRezColor); + secondQuarterRezColor = blur4; + + if (quality > BloomQuality.Cheap) { + if (iter == 0) + { + Graphics.SetRenderTarget(quarterRezColor); + GL.Clear(false, true, Color.black); // Clear to avoid RT restore + Graphics.Blit (secondQuarterRezColor, quarterRezColor); + } + else + { + quarterRezColor.MarkRestoreExpected(); // using max blending, RT restore expected + Graphics.Blit (secondQuarterRezColor, quarterRezColor, screenBlend, 10); + } + } + } + + if(quality > BloomQuality.Cheap) + { + Graphics.SetRenderTarget(secondQuarterRezColor); + GL.Clear(false, true, Color.black); // Clear to avoid RT restore + Graphics.Blit (quarterRezColor, secondQuarterRezColor, screenBlend, 6); + } + + // lens flares: ghosting, anamorphic or both (ghosted anamorphic flares) + + if (lensflareIntensity > Mathf.Epsilon) { + + RenderTexture rtFlares4 = RenderTexture.GetTemporary (rtW4, rtH4, 0, rtFormat); + + if (lensflareMode == 0) { + // ghosting only + + BrightFilter (lensflareThreshhold, secondQuarterRezColor, rtFlares4); + + if(quality > BloomQuality.Cheap) { + // smooth a little + blurAndFlaresMaterial.SetVector("_Offsets", new Vector4(0.0f, (1.5f) / (1.0f * quarterRezColor.height), 0.0f, 0.0f)); + Graphics.SetRenderTarget(quarterRezColor); + GL.Clear(false, true, Color.black); // Clear to avoid RT restore + Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial, 4); + + blurAndFlaresMaterial.SetVector("_Offsets", new Vector4((1.5f) / (1.0f * quarterRezColor.width), 0.0f, 0.0f, 0.0f)); + Graphics.SetRenderTarget(rtFlares4); + GL.Clear(false, true, Color.black); // Clear to avoid RT restore + Graphics.Blit (quarterRezColor, rtFlares4, blurAndFlaresMaterial, 4); + } + + // no ugly edges! + Vignette (0.975f, rtFlares4, rtFlares4); + BlendFlares (rtFlares4, secondQuarterRezColor); + } + else { + + //Vignette (0.975f, rtFlares4, rtFlares4); + //DrawBorder(rtFlares4, screenBlend, 8); + + float flareXRot = 1.0f * Mathf.Cos(flareRotation); + float flareyRot = 1.0f * Mathf.Sin(flareRotation); + + float stretchWidth = (hollyStretchWidth * 1.0f / widthOverHeight) * oneOverBaseSize; + //float stretchWidthY = hollyStretchWidth * oneOverBaseSize; + + blurAndFlaresMaterial.SetVector("_Offsets", new Vector4(flareXRot, flareyRot, 0.0f, 0.0f)); + blurAndFlaresMaterial.SetVector("_Threshhold", new Vector4(lensflareThreshhold, 1.0f, 0.0f, 0.0f)); + blurAndFlaresMaterial.SetVector("_TintColor", new Vector4(flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * flareColorA.a * lensflareIntensity); + blurAndFlaresMaterial.SetFloat ("_Saturation", lensFlareSaturation); + + // "pre and cut" + quarterRezColor.DiscardContents(); + Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial, 2); + // "post" + rtFlares4.DiscardContents(); + Graphics.Blit (quarterRezColor, rtFlares4, blurAndFlaresMaterial, 3); + + blurAndFlaresMaterial.SetVector("_Offsets", new Vector4(flareXRot * stretchWidth, flareyRot * stretchWidth, 0.0f, 0.0f)); + // stretch 1st + blurAndFlaresMaterial.SetFloat ("_StretchWidth", hollyStretchWidth); + quarterRezColor.DiscardContents(); + Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial, 1); + // stretch 2nd + blurAndFlaresMaterial.SetFloat ("_StretchWidth", hollyStretchWidth * 2.0f); + rtFlares4.DiscardContents(); + Graphics.Blit (quarterRezColor, rtFlares4, blurAndFlaresMaterial, 1); + // stretch 3rd + blurAndFlaresMaterial.SetFloat ("_StretchWidth", hollyStretchWidth * 4.0f); + quarterRezColor.DiscardContents(); + Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial, 1); + + // additional blur passes + for (int iter = 0; iter < hollywoodFlareBlurIterations; iter++) + { + stretchWidth = (hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize; + + blurAndFlaresMaterial.SetVector("_Offsets", new Vector4(stretchWidth * flareXRot, stretchWidth * flareyRot, 0.0f, 0.0f)); + rtFlares4.DiscardContents(); + Graphics.Blit (quarterRezColor, rtFlares4, blurAndFlaresMaterial, 4); + + blurAndFlaresMaterial.SetVector("_Offsets", new Vector4(stretchWidth * flareXRot, stretchWidth * flareyRot, 0.0f, 0.0f)); + quarterRezColor.DiscardContents(); + Graphics.Blit (rtFlares4, quarterRezColor, blurAndFlaresMaterial, 4); + } + + if (lensflareMode == LensFlareStyle.Anamorphic) + // anamorphic lens flares + AddTo (1.0f, quarterRezColor, secondQuarterRezColor); + else { + + // "combined" lens flares + + Vignette (1.0f, quarterRezColor, rtFlares4); + BlendFlares (rtFlares4, quarterRezColor); + AddTo (1.0f, quarterRezColor, secondQuarterRezColor); + } + } + RenderTexture.ReleaseTemporary (rtFlares4); + } + + int blendPass = (int)realBlendMode; + //if(Mathf.Abs(chromaticBloom) < Mathf.Epsilon) + // blendPass += 4; + + screenBlend.SetFloat ("_Intensity", bloomIntensity); + screenBlend.SetTexture ("_ColorBuffer", source); + + if(quality > BloomQuality.Cheap) { + RenderTexture halfRezColorUp = RenderTexture.GetTemporary (rtW2, rtH2, 0, rtFormat); + Graphics.Blit (secondQuarterRezColor, halfRezColorUp); + Graphics.Blit (halfRezColorUp, destination, screenBlend, blendPass); + RenderTexture.ReleaseTemporary (halfRezColorUp); + } + else + Graphics.Blit (secondQuarterRezColor, destination, screenBlend, blendPass); + + RenderTexture.ReleaseTemporary (quarterRezColor); + RenderTexture.ReleaseTemporary (secondQuarterRezColor); + } + + private void AddTo (float intensity_, RenderTexture from, RenderTexture to) { + screenBlend.SetFloat ("_Intensity", intensity_); + to.MarkRestoreExpected(); // additive blending, RT restore expected + Graphics.Blit (from, to, screenBlend, 9); + } + + private void BlendFlares (RenderTexture from,RenderTexture to) { + lensFlareMaterial.SetVector("colorA", new Vector4(flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * lensflareIntensity); + lensFlareMaterial.SetVector("colorB", new Vector4(flareColorB.r, flareColorB.g, flareColorB.b, flareColorB.a) * lensflareIntensity); + lensFlareMaterial.SetVector("colorC", new Vector4(flareColorC.r, flareColorC.g, flareColorC.b, flareColorC.a) * lensflareIntensity); + lensFlareMaterial.SetVector ("colorD", new Vector4 (flareColorD.r, flareColorD.g, flareColorD.b, flareColorD.a) * lensflareIntensity); + to.MarkRestoreExpected(); // additive blending, RT restore expected + Graphics.Blit (from, to, lensFlareMaterial); + } + + private void BrightFilter (float thresh,RenderTexture from,RenderTexture to) { + brightPassFilterMaterial.SetVector("_Threshhold", new Vector4(thresh, thresh, thresh, thresh)); + Graphics.Blit (from, to, brightPassFilterMaterial, 0); + } + + private void BrightFilter (Color threshColor,RenderTexture from,RenderTexture to) { + brightPassFilterMaterial.SetVector ("_Threshhold", threshColor); + Graphics.Blit (from, to, brightPassFilterMaterial, 1); + } + + private void Vignette (float amount,RenderTexture from,RenderTexture to) { + if(lensFlareVignetteMask) { + screenBlend.SetTexture ("_ColorBuffer", lensFlareVignetteMask); + to.MarkRestoreExpected(); // using blending, RT restore expected + Graphics.Blit (from == to ? null : from, to, screenBlend, from == to ? 7 : 3); + } + else if (from != to) + { + Graphics.SetRenderTarget (to); + GL.Clear(false, true, Color.black); // clear destination to avoid RT restore + Graphics.Blit (from, to); + } + } +} diff --git a/Client/Assets/Scripts/PostEffect/Bloom.cs.meta b/Client/Assets/Scripts/PostEffect/Bloom.cs.meta new file mode 100644 index 00000000..bfa89d3c --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/Bloom.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a875414853e920742ab921c2b633e9ca +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Client/Assets/Scripts/PostEffect/BloomHelper.cs b/Client/Assets/Scripts/PostEffect/BloomHelper.cs new file mode 100644 index 00000000..e60a1052 --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/BloomHelper.cs @@ -0,0 +1,215 @@ +#define FXPRO_EFFECT +//#define BLOOMPRO_EFFECT + +#if FXPRO_EFFECT +#define BLOOMPRO_EFFECT +#endif + +using System; +using System.Collections.Generic; +using System.Linq; + +using UnityEngine; +using Object = UnityEngine.Object; + +#if FXPRO_EFFECT +namespace FxProNS { +#elif BLOOMPRO_EFFECT +namespace BloomProNS { +#endif + [Serializable] + public class BloomHelperParams { + public EffectsQuality Quality; + + public Color BloomTint = new Color(110.0f/255.0f,230.0f/255.0f,1.0f,1.0f); + + [Range( 0f, .99f )] + public float BloomThreshold = .8f; + + [Range( 0f, 3f )] + public float BloomIntensity = 0.7f; + + [Range( 0.01f, 3f )] + public float BloomSoftness = .5f; + } + + public class BloomHelper : Singleton, IDisposable + { + private static Material _mat; + + public static Material Mat + { + get + { + if (null == _mat) + { + Shader shader = XUtliPoolLib.ShaderManager.singleton.FindShader("BloomPro", "Hidden/BloomPro"); + _mat = new Material(shader) + { + hideFlags = HideFlags.HideAndDontSave + }; + } + + + return _mat; + } + } + + private BloomHelperParams p; + + private int bloomSamples = 5; + + private float bloomBlurRadius = 5f; + +#if ((UNITY_EDITOR) || (UNITY_STANDALONE)|| (UNITY_IOS)) + + public void SetParams(BloomHelperParams _p) + { + p = _p; + } + + public void Init() { + + float realBloomIntensity = Mathf.Exp( p.BloomIntensity ) - 1f; + + //if (Application.platform == RuntimePlatform.IPhonePlayer) + // p.BloomThreshold *= .75f; + + Mat.SetFloat( "_BloomThreshold", p.BloomThreshold ); + Mat.SetFloat( "_BloomIntensity", realBloomIntensity ); + + Mat.SetColor( "_BloomTint", p.BloomTint ); + +// Debug.Log( p.BloomTint ); + + //Bloom samples settings + if (p.Quality == EffectsQuality.High || p.Quality == EffectsQuality.Normal) { + bloomSamples = 5; + Mat.EnableKeyword( "BLOOM_SAMPLES_5" ); + } if (p.Quality == EffectsQuality.Fast || p.Quality == EffectsQuality.Fastest) { + bloomSamples = 3; + Mat.DisableKeyword( "BLOOM_SAMPLES_5" ); + } + + //Blur radius settings + if (p.Quality == EffectsQuality.High) { + bloomBlurRadius = 10f; + Mat.EnableKeyword( "BLUR_RADIUS_10" ); + Mat.DisableKeyword( "BLUR_RADIUS_5" ); + } else { + bloomBlurRadius = 5f; + Mat.EnableKeyword( "BLUR_RADIUS_5" ); + Mat.DisableKeyword( "BLUR_RADIUS_10" ); + } + + float[] bloomTexFactors = CalculateBloomTexFactors( Mathf.Exp( p.BloomSoftness ) - 1f ); + + if (bloomTexFactors.Length == 5) { + Mat.SetVector( "_BloomTexFactors1", + new Vector4( bloomTexFactors[0], bloomTexFactors[1], bloomTexFactors[2], bloomTexFactors[3] ) ); + Mat.SetVector( "_BloomTexFactors2", new Vector4( bloomTexFactors[4], 0f, 0f, 0f ) ); + } else if (bloomTexFactors.Length == 3) { + Mat.SetVector( + "_BloomTexFactors1", + new Vector4( bloomTexFactors[0], bloomTexFactors[1], bloomTexFactors[2], 0f ) ); + } else { + Debug.LogError( "Unsupported bloomTexFactors.Length: " + bloomTexFactors.Length ); + } + + RenderTextureManager.Instance.Dispose(); + } + + public void RenderBloomTexture( RenderTexture source, RenderTexture dest ) + { + RenderTexture curRenderTex = RenderTextureManager.Instance.RequestRenderTexture( source.width, source.height, source.depth, source.format ); + + //Prepare by extracting blooming pixels + Graphics.Blit( source, curRenderTex, Mat, 0 ); //Is it ok to extract blooming pixels at 1/4 res?????? + + //Downsample & blur + for (int i = 1; i <= bloomSamples; i++) { + float curSpread = Mathf.Lerp( 1f, 2f, (float)(i - 1) / (float)(bloomSamples) ); + + #if FXPRO_EFFECT + RenderTextureManager.Instance.SafeAssign( ref curRenderTex, FxPro.DownsampleTex( curRenderTex, 2f ) ); + #elif BLOOMPRO_EFFECT + RenderTextureManager.Instance.SafeAssign( ref curRenderTex, BloomPro.DownsampleTex( curRenderTex, 2f ) ); + #elif DOFPRO_EFFECT + RenderTextureManager.Instance.SafeAssign( ref curRenderTex, DOFPro.DownsampleTex( curRenderTex, 2f ) ); + #endif + + RenderTextureManager.Instance.SafeAssign( ref curRenderTex, BlurTex( curRenderTex, curSpread ) ); + + //Set blurred bloom texture + Mat.SetTexture( "_DsTex" + i, curRenderTex ); + } + + //Bloom composite pass + Graphics.Blit( null, dest, Mat, 1 ); + + RenderTextureManager.Instance.ReleaseRenderTexture(curRenderTex); + } + + + + public RenderTexture BlurTex( RenderTexture _input, float _spread ) { + //Blur + float curBlurSize = _spread * 10f / bloomBlurRadius; //Normalization - smaller blur = higher step + + RenderTexture tempRenderTex1 = RenderTextureManager.Instance.RequestRenderTexture( _input.width, _input.height, _input.depth, _input.format ); + RenderTexture tempRenderTex2 = RenderTextureManager.Instance.RequestRenderTexture( _input.width, _input.height, _input.depth, _input.format ); + + //Horizontal blur + Mat.SetVector( "_SeparableBlurOffsets", new Vector4( 1f, 0f, 0f, 0f ) * curBlurSize ); + Graphics.Blit( _input, tempRenderTex1, Mat, 2 ); + + //Vertical blur + Mat.SetVector( "_SeparableBlurOffsets", new Vector4( 0f, 1f, 0f, 0f ) * curBlurSize ); + Graphics.Blit( tempRenderTex1, tempRenderTex2, Mat, 2 ); + + tempRenderTex1 = RenderTextureManager.Instance.ReleaseRenderTexture( tempRenderTex1 ); + + return tempRenderTex2; + } + + private float[] CalculateBloomTexFactors( float softness ) { + var bloomTexFactors = new float[bloomSamples]; + for (int i = 0; i < bloomTexFactors.Length; i++) { + float t = (float)(i) / (float)(bloomTexFactors.Length - 1); + + bloomTexFactors[i] = Mathf.Lerp( 1f, softness, t ); + } + + bloomTexFactors = MakeSumOne( bloomTexFactors ); + + return bloomTexFactors; + } + + private float[] MakeSumOne( IList _in ) { + float sum = _in.Sum(); + + var res = new float[_in.Count]; + + for (int i = 0; i < _in.Count; i++) { + res[i] = _in[i] / sum; + } + + return res; + } + + public void Dispose() + { + if (null != Mat) + Object.DestroyImmediate(Mat); + + RenderTextureManager.Instance.Dispose(); + } +#else + + public void Dispose() { + } + +#endif + } + +} \ No newline at end of file diff --git a/Client/Assets/Scripts/PostEffect/BloomHelper.cs.meta b/Client/Assets/Scripts/PostEffect/BloomHelper.cs.meta new file mode 100644 index 00000000..5965678b --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/BloomHelper.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c3fa06406ed2ecf4f94e655537538d7f +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Client/Assets/Scripts/PostEffect/ContrastStretchEffect.cs b/Client/Assets/Scripts/PostEffect/ContrastStretchEffect.cs new file mode 100644 index 00000000..af72f0fc --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/ContrastStretchEffect.cs @@ -0,0 +1,194 @@ +using UnityEngine; +using System.Collections; + +[ExecuteInEditMode] +[AddComponentMenu("Image Effects/Color Adjustments/Contrast Stretch")] +public class ContrastStretchEffect : MonoBehaviour +{ + /// Adaptation speed - percents per frame, if playing at 30FPS. + /// Default is 0.02 (2% each 1/30s). + public float adaptationSpeed = 0.02f; + + /// If our scene is really dark (or really bright), we might not want to + /// stretch its contrast to the full range. + /// limitMinimum=0, limitMaximum=1 is the same as not applying the effect at all. + /// limitMinimum=1, limitMaximum=0 is always stretching colors to full range. + + /// The limit on the minimum luminance (0...1) - we won't go above this. + public float limitMinimum = 0.2f; + + /// The limit on the maximum luminance (0...1) - we won't go below this. + public float limitMaximum = 0.6f; + + + // To maintain adaptation levels over time, we need two 1x1 render textures + // and ping-pong between them. + private RenderTexture[] adaptRenderTex = new RenderTexture[2]; + private int curAdaptIndex = 0; + + + // Computes scene luminance (grayscale) image + public Shader shaderLum; + private Material m_materialLum; + protected Material materialLum { + get { + if( m_materialLum == null ) { + m_materialLum = new Material(shaderLum); + m_materialLum.hideFlags = HideFlags.HideAndDontSave; + } + return m_materialLum; + } + } + + // Reduces size of the image by 2x2, while computing maximum/minimum values. + // By repeatedly applying this shader, we reduce the initial luminance image + // to 1x1 image with minimum/maximum luminances found. + public Shader shaderReduce; + private Material m_materialReduce; + protected Material materialReduce { + get { + if( m_materialReduce == null ) { + m_materialReduce = new Material(shaderReduce); + m_materialReduce.hideFlags = HideFlags.HideAndDontSave; + } + return m_materialReduce; + } + } + + // Adaptation shader - gradually "adapts" minimum/maximum luminances, + // based on currently adapted 1x1 image and the actual 1x1 image of the current scene. + public Shader shaderAdapt; + private Material m_materialAdapt; + protected Material materialAdapt { + get { + if( m_materialAdapt == null ) { + m_materialAdapt = new Material(shaderAdapt); + m_materialAdapt.hideFlags = HideFlags.HideAndDontSave; + } + return m_materialAdapt; + } + } + + // Final pass - stretches the color values of the original scene, based on currently + // adpated minimum/maximum values. + public Shader shaderApply; + private Material m_materialApply; + protected Material materialApply { + get { + if( m_materialApply == null ) { + m_materialApply = new Material(shaderApply); + m_materialApply.hideFlags = HideFlags.HideAndDontSave; + } + return m_materialApply; + } + } + + void Start() + { + // Disable if we don't support image effects + if (!SystemInfo.supportsImageEffects) { + enabled = false; + return; + } + + if (!shaderAdapt.isSupported || !shaderApply.isSupported || !shaderLum.isSupported || !shaderReduce.isSupported) { + enabled = false; + return; + } + } + + void OnEnable() + { + for( int i = 0; i < 2; ++i ) + { + if( !adaptRenderTex[i] ) { + adaptRenderTex[i] = new RenderTexture(1, 1, 0); + adaptRenderTex[i].hideFlags = HideFlags.HideAndDontSave; + } + } + } + + void OnDisable() + { + for( int i = 0; i < 2; ++i ) + { + DestroyImmediate( adaptRenderTex[i] ); + adaptRenderTex[i] = null; + } + if( m_materialLum ) + DestroyImmediate( m_materialLum ); + if( m_materialReduce ) + DestroyImmediate( m_materialReduce ); + if( m_materialAdapt ) + DestroyImmediate( m_materialAdapt ); + if( m_materialApply ) + DestroyImmediate( m_materialApply ); + } + + + /// Apply the filter + void OnRenderImage (RenderTexture source, RenderTexture destination) + { + // Blit to smaller RT and convert to luminance on the way + const int TEMP_RATIO = 1; // 4x4 smaller + RenderTexture rtTempSrc = RenderTexture.GetTemporary(source.width/TEMP_RATIO, source.height/TEMP_RATIO); + Graphics.Blit (source, rtTempSrc, materialLum); + + // Repeatedly reduce this image in size, computing min/max luminance values + // In the end we'll have 1x1 image with min/max luminances found. + const int FINAL_SIZE = 1; + //const int FINAL_SIZE = 1; + while( rtTempSrc.width > FINAL_SIZE || rtTempSrc.height > FINAL_SIZE ) + { + const int REDUCE_RATIO = 2; // our shader does 2x2 reduction + int destW = rtTempSrc.width / REDUCE_RATIO; + if( destW < FINAL_SIZE ) destW = FINAL_SIZE; + int destH = rtTempSrc.height / REDUCE_RATIO; + if( destH < FINAL_SIZE ) destH = FINAL_SIZE; + RenderTexture rtTempDst = RenderTexture.GetTemporary(destW,destH); + Graphics.Blit (rtTempSrc, rtTempDst, materialReduce); + + // Release old src temporary, and make new temporary the source + RenderTexture.ReleaseTemporary( rtTempSrc ); + rtTempSrc = rtTempDst; + } + + // Update viewer's adaptation level + CalculateAdaptation( rtTempSrc ); + + // Apply contrast strech to the original scene, using currently adapted parameters + materialApply.SetTexture("_AdaptTex", adaptRenderTex[curAdaptIndex] ); + Graphics.Blit (source, destination, materialApply); + + RenderTexture.ReleaseTemporary( rtTempSrc ); + } + + + /// Helper function to do gradual adaptation to min/max luminances + private void CalculateAdaptation( Texture curTexture ) + { + int prevAdaptIndex = curAdaptIndex; + curAdaptIndex = (curAdaptIndex+1) % 2; + + // Adaptation speed is expressed in percents/frame, based on 30FPS. + // Calculate the adaptation lerp, based on current FPS. + float adaptLerp = 1.0f - Mathf.Pow( 1.0f - adaptationSpeed, 30.0f * Time.deltaTime ); + const float kMinAdaptLerp = 0.01f; + adaptLerp = Mathf.Clamp( adaptLerp, kMinAdaptLerp, 1 ); + + materialAdapt.SetTexture("_CurTex", curTexture ); + materialAdapt.SetVector("_AdaptParams", new Vector4( + adaptLerp, + limitMinimum, + limitMaximum, + 0.0f + )); + // clear destination RT so its contents don't need to be restored + Graphics.SetRenderTarget(adaptRenderTex[curAdaptIndex]); + GL.Clear(false, true, Color.black); + Graphics.Blit ( + adaptRenderTex[prevAdaptIndex], + adaptRenderTex[curAdaptIndex], + materialAdapt); + } +} diff --git a/Client/Assets/Scripts/PostEffect/ContrastStretchEffect.cs.meta b/Client/Assets/Scripts/PostEffect/ContrastStretchEffect.cs.meta new file mode 100644 index 00000000..25420eff --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/ContrastStretchEffect.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ec92b071d2d424aecb3e46f28eb63174 +MonoImporter: + serializedVersion: 2 + defaultReferences: + - shaderLum: {fileID: 4800000, guid: befbb4b9c320b4b18a08ef7afb93b6c9, type: 3} + - shaderReduce: {fileID: 4800000, guid: 57b33a14b6d5347c5a85c36f6cb3b280, type: 3} + - shaderAdapt: {fileID: 4800000, guid: 257bc83cbeb544540bd0e558aa9b1383, type: 3} + - shaderApply: {fileID: 4800000, guid: f4901f25d4e1542589348bbb89563d8e, type: 3} + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Client/Assets/Scripts/PostEffect/DOFHelper.cs b/Client/Assets/Scripts/PostEffect/DOFHelper.cs new file mode 100644 index 00000000..26188d28 --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/DOFHelper.cs @@ -0,0 +1,383 @@ +//Unity Scatter DOF (disk blur): 13ms +//Unity Scatter DOF (DX11): 6ms +//FxPro DOF with bokeh: 5.2ms +//FxPro DOF no bokeh: 3.9ms + +#define FXPRO_EFFECT +//#define DOFPRO_EFFECT + +#if FXPRO_EFFECT +#define BLOOMPRO_EFFECT +#define DOFPRO_EFFECT +#endif + +using System; +using UnityEngine; +using System.Collections.Generic; + +using Object = UnityEngine.Object; + +#if FXPRO_EFFECT +namespace FxProNS { +#elif DOFPRO_EFFECT +namespace DOFProNS { +#endif + [Serializable] + public class DOFHelperParams { + //Parameters coming from DOFPro + public bool UseUnityDepthBuffer = false; + public bool AutoFocus = true; + + public LayerMask AutoFocusLayerMask = -1; + + [Range( 2f, 8f )] + public float AutoFocusSpeed = 5f; + + [Range( .01f, 1f )] + public float FocalLengthMultiplier = .33f; + + public float FocalDistMultiplier = 1f; + + [Range( .5f, 2f )] + public float DOFBlurSize = 1f; + + public bool BokehEnabled = false; + + [Range( 2f, 8f )] + public float DepthCompression = 4f; + public Camera EffectCamera; + public Transform Target; + + [Range( 0f, 1f )] + public float BokehThreshold = .5f; + + [Range( .5f, 5f )] + public float BokehGain = 2f; + + [Range( 0f, 1f )] + public float BokehBias = .5f; + + public bool DoubleIntensityBlur = false; + } + + public class DOFHelper : Singleton, IDisposable + { + private static Material _mat; + + public static Material Mat + { + get + { + if (null == _mat) + { + Shader shader = XUtliPoolLib.ShaderManager.singleton.FindShader("DOFPro", "Hidden/DOFPro"); + _mat = new Material(shader) + { + hideFlags = HideFlags.HideAndDontSave + }; + } + + return _mat; + } + } + + private DOFHelperParams _p; + + public void SetParams(DOFHelperParams p) + { + _p = p; + } + + public void Init(bool searchForNonDepthmapAlphaObjects) + { + if (null == _p) + { + Debug.LogError("Call SetParams first"); + return; + } + + if (null == _p.EffectCamera) { + Debug.LogError("null == p.camera"); + return; + } + + if (null == Mat) + return; + + if (!_p.UseUnityDepthBuffer) + { + #if UNITY_EDITOR + if (searchForNonDepthmapAlphaObjects && GetNonDepthmapAlphaObjects().Length > 0) + { + Debug.LogError("Found non-alpha depthmapped shaders. Will be using Unity Depth Buffer instead. Warning: may be slow on mobile devices." + + + " Either make all shaders output depth value to alpha channel, or enable \"Use Unity Depth Buffer\" option."); + Debug.Break(); + _p.UseUnityDepthBuffer = true; + + if ( _p.EffectCamera.depthTextureMode != DepthTextureMode.DepthNormals) + _p.EffectCamera.depthTextureMode = DepthTextureMode.Depth; + + Mat.EnableKeyword("USE_CAMERA_DEPTH_TEXTURE"); + Mat.DisableKeyword("DONT_USE_CAMERA_DEPTH_TEXTURE"); + } + else + { + _p.EffectCamera.depthTextureMode = DepthTextureMode.None; + Mat.DisableKeyword("USE_CAMERA_DEPTH_TEXTURE"); + Mat.EnableKeyword("DONT_USE_CAMERA_DEPTH_TEXTURE"); + } + #else + _p.EffectCamera.depthTextureMode = DepthTextureMode.None; + Mat.DisableKeyword("USE_CAMERA_DEPTH_TEXTURE"); + Mat.EnableKeyword("DONT_USE_CAMERA_DEPTH_TEXTURE"); + #endif + } else { + if ( _p.EffectCamera.depthTextureMode != DepthTextureMode.DepthNormals ) + _p.EffectCamera.depthTextureMode = DepthTextureMode.Depth; + + Mat.EnableKeyword("USE_CAMERA_DEPTH_TEXTURE"); + Mat.DisableKeyword("DONT_USE_CAMERA_DEPTH_TEXTURE"); + } + + // Debug.Log( "p.useUnityDepthBuffer: " + p.useUnityDepthBuffer + "; p.camera.depthTextureMode: " + p.camera.depthTextureMode ); + + // UpdateQualitySettings(); + + // dofBoost = Mathf.Clamp(dofBoost, 1f, 10f); + _p.FocalLengthMultiplier = Mathf.Clamp(_p.FocalLengthMultiplier, .01f, .99f); + _p.DepthCompression = Mathf.Clamp(_p.DepthCompression, 1f, 10f); + + Shader.SetGlobalFloat("_OneOverDepthScale", _p.DepthCompression); + Shader.SetGlobalFloat("_OneOverDepthFar", 1f / (_p.EffectCamera.farClipPlane)); + + // mat.SetFloat("_DOFBoost", dofBoost); + + if ( _p.BokehEnabled ) + { + Mat.SetFloat( "_BokehThreshold", _p.BokehThreshold ); + Mat.SetFloat( "_BokehGain", _p.BokehGain ); + Mat.SetFloat( "_BokehBias", _p.BokehBias ); + } + } + + public void SetBlurRadius(int radius) + { + Shader.DisableKeyword("BLUR_RADIUS_10"); + Shader.DisableKeyword("BLUR_RADIUS_5"); + Shader.DisableKeyword("BLUR_RADIUS_3"); + Shader.DisableKeyword("BLUR_RADIUS_2"); + Shader.DisableKeyword("BLUR_RADIUS_1"); + + if (radius != 10 && radius != 5 && radius != 3 && radius != 2 && radius != 1) radius = 5; + + if ( radius < 3 ) radius = 3; + + //Debug.Log( "blur radius: " + radius ); + + Shader.EnableKeyword( "BLUR_RADIUS_" + radius ); + } + + private float _curAutoFocusDist = 0f; + + private void CalculateAndUpdateFocalDist() { + if (null == _p.EffectCamera) { + Debug.LogError("null == p.camera"); + return; + } + + float focalDist; + + if (!_p.AutoFocus && null != _p.Target) + { + Vector3 targetPosInViewportSpace = _p.EffectCamera.WorldToViewportPoint(_p.Target.position); + focalDist = targetPosInViewportSpace.z; + // float focalDist = (target.position - transform.position).magnitude / camera.farClipPlane; + } else + { + focalDist = _curAutoFocusDist = Mathf.Lerp(_curAutoFocusDist, CalculateAutoFocusDist(), Time.deltaTime * _p.AutoFocusSpeed); + // Debug.Log("focalDist: " + focalDist); + } + + focalDist /= _p.EffectCamera.farClipPlane; + + focalDist *= _p.FocalDistMultiplier * _p.DepthCompression; + + Mat.SetFloat("_FocalDist", focalDist); + + //Make sure that focalLength < focalDist + Mat.SetFloat("_FocalLength", focalDist * _p.FocalLengthMultiplier); + } + + private float CalculateAutoFocusDist() + { + if (null == _p.EffectCamera) return 0f; + + RaycastHit hitInfo; + + //Return farClipPlane if nothing was hit + + return Physics.Raycast( _p.EffectCamera.transform.position, _p.EffectCamera.transform.forward, out hitInfo, Mathf.Infinity, _p.AutoFocusLayerMask.value ) ? hitInfo.distance : _p.EffectCamera.farClipPlane; + } + + public void RenderCOCTexture(RenderTexture src, RenderTexture dest, float blurScale) + { + CalculateAndUpdateFocalDist(); + + if (null == _p.EffectCamera) { + Debug.LogError( "null == p.camera" ); + return; + } + + //Verify depth texture mode before rendering + if (_p.EffectCamera.depthTextureMode == DepthTextureMode.None) + _p.EffectCamera.depthTextureMode = DepthTextureMode.Depth; + + if (_p.DOFBlurSize > .001f) { + RenderTexture tempRt1 = RenderTextureManager.Instance.RequestRenderTexture( src.width, src.height, src.depth, src.format ); + RenderTexture tempRt2 = RenderTextureManager.Instance.RequestRenderTexture( src.width, src.height, src.depth, src.format ); + + Graphics.Blit( src, tempRt1, Mat, 0 ); + + //Blur COC texture + Mat.SetVector( "_SeparableBlurOffsets", new Vector4( blurScale, 0f, 0f, 0f ) ); + Graphics.Blit( tempRt1, tempRt2, Mat, 2 ); + Mat.SetVector( "_SeparableBlurOffsets", new Vector4( 0f, blurScale, 0f, 0f ) ); + Graphics.Blit( tempRt2, dest, Mat, 2 ); + + RenderTextureManager.Instance.ReleaseRenderTexture( tempRt1 ); + RenderTextureManager.Instance.ReleaseRenderTexture( tempRt2 ); + } + else { + Graphics.Blit( src, dest, Mat, 0 ); + } + } + + public void RenderDOFBlur( RenderTexture src, RenderTexture dest, RenderTexture cocTexture ) + { + //Graphics.Blit( src, dest ); + + if (null == cocTexture) { + Debug.LogError( "null == cocTexture" ); + return; + } + + Mat.SetTexture( "_COCTex", cocTexture ); + + // //Apply separable DOF + if ( _p.BokehEnabled ) + { + Mat.SetFloat( "_BlurIntensity", _p.DOFBlurSize ); + + Graphics.Blit( src, dest, Mat, 4 ); + } else { + RenderTexture tempRt = RenderTextureManager.Instance.RequestRenderTexture( src.width, src.height, src.depth, src.format ); + + Mat.SetVector( "_SeparableBlurOffsets", new Vector4( _p.DOFBlurSize, 0f, 0f, 0f ) ); + Graphics.Blit( src, tempRt, Mat, 1 ); + Mat.SetVector( "_SeparableBlurOffsets", new Vector4( 0f, _p.DOFBlurSize, 0f, 0f ) ); + Graphics.Blit( tempRt, dest, Mat, 1 ); + + RenderTextureManager.Instance.ReleaseRenderTexture( tempRt ); + } + } + + public void RenderEffect( RenderTexture src, RenderTexture dest ) { + RenderEffect( src, dest, false ); + } + + public void RenderEffect( RenderTexture src, RenderTexture dest, bool visualizeCOC ) + { + RenderTexture cocRenderTexture = RenderTextureManager.Instance.RequestRenderTexture( src.width, src.height, src.depth, src.format ); + RenderCOCTexture( src, cocRenderTexture, 0f ); + + //COC visualization + if (visualizeCOC) + { + Graphics.Blit(cocRenderTexture, dest); + RenderTextureManager.Instance.ReleaseRenderTexture(cocRenderTexture); + RenderTextureManager.Instance.ReleaseAllRenderTextures(); + return; + } + + RenderDOFBlur(src, dest, cocRenderTexture); + RenderTextureManager.Instance.ReleaseRenderTexture( cocRenderTexture ); + //RenderTextureManager.Instance.ReleaseAllRenderTextures(); + } + + public static GameObject[] GetNonDepthmapAlphaObjects() + { + if (!Application.isPlaying) + return new GameObject[0]; + + Renderer[] allRenderers = Object.FindObjectsOfType(); + + var selectedGOs = new List(); + var nonDepthMappedMaterial = new List(); + + foreach (Renderer rend in allRenderers) + { + if (null == rend.sharedMaterials) + continue; + + //Skip particle systems + if (null != rend.GetComponent()) + continue; + + foreach (Material mat in rend.sharedMaterials) + { + if (null == mat.shader) + continue; + + bool shouldFlagShader = null == mat.GetTag("RenderType", false); + + //Skip transparent materials + if (!shouldFlagShader && (mat.GetTag("RenderType", false).ToLower() == "transparent" || mat.GetTag("Queue", false).ToLower() == "transparent")) + continue; + + if (null == mat.GetTag("OUTPUT_DEPTH_TO_ALPHA", false) || mat.GetTag("OUTPUT_DEPTH_TO_ALPHA", false).ToLower() != "true") + { + // if (shouldLog) Debug.Log("OUTPUT_DEPTH_TO_ALPHA:" + mat.GetTag("OUTPUT_DEPTH_TO_ALPHA", false) ); + shouldFlagShader = true; + } + + // Debug.Log ("shouldFlagShader: " + shouldFlagShader); + + if (shouldFlagShader) + { + //Skip duplicates + if (nonDepthMappedMaterial.Contains(mat)) + continue; + + nonDepthMappedMaterial.Add(mat); + + Debug.Log( "Non-depthmapped: " + GetFullPath(rend.gameObject) ); + selectedGOs.Add(rend.gameObject); + } + } + } + + return selectedGOs.ToArray(); + } + + public static string GetFullPath(GameObject obj) + { + string path = "/" + obj.name; + while (obj.transform.parent != null) + { + obj = obj.transform.parent.gameObject; + path = "/" + obj.name + path; + } + return "'" + path + "'"; + } + + public void Dispose() + { + if (null != Mat) + Object.DestroyImmediate(Mat); + if (_p != null && _p.EffectCamera != null) + _p.EffectCamera.depthTextureMode = DepthTextureMode.None; + RenderTextureManager.Instance.Dispose(); + } + } +} \ No newline at end of file diff --git a/Client/Assets/Scripts/PostEffect/DOFHelper.cs.meta b/Client/Assets/Scripts/PostEffect/DOFHelper.cs.meta new file mode 100644 index 00000000..1c710777 --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/DOFHelper.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fae300c752ec1d746ae5db6d5c46e257 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Client/Assets/Scripts/PostEffect/FastBloom.cs b/Client/Assets/Scripts/PostEffect/FastBloom.cs new file mode 100644 index 00000000..dc1fc745 --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/FastBloom.cs @@ -0,0 +1,98 @@ +using UnityEngine; +using System.Collections; + +[ExecuteInEditMode] +[RequireComponent(typeof(Camera))] +public class FastBloom : PostEffectsBase +{ + public enum Resolution { + Low = 0, + High = 1, + } + + public enum BlurType { + Standard = 0, + Sgx = 1, + } + + [Range(0.0f, 1.5f)] + public float threshhold = 0.25f; + [Range(0.0f, 2.5f)] + public float intensity = 0.75f; + + [Range(0.25f, 5.5f)] + public float blurSize = 1.0f; + + Resolution resolution = Resolution.Low; + [Range(1, 4)] + public int blurIterations = 1; + + public BlurType blurType = BlurType.Standard; + + public Shader fastBloomShader; + private Material fastBloomMaterial = null; + + new bool CheckResources () + { + CheckSupport (false); + + fastBloomMaterial = CheckShaderAndCreateMaterial (fastBloomShader, fastBloomMaterial); + + if(!isSupported) + ReportAutoDisable (); + return isSupported; + } + + void OnDisable() { + if(fastBloomMaterial) + DestroyImmediate (fastBloomMaterial); + } + + void OnRenderImage (RenderTexture source, RenderTexture destination) + { + if(CheckResources() == false) { + Graphics.Blit (source, destination); + return; + } + + int divider = resolution == Resolution.Low ? 4 : 2; + float widthMod = resolution == Resolution.Low ? 0.5f : 1.0f; + + fastBloomMaterial.SetVector ("_Parameter",new Vector4 (blurSize * widthMod, 0.0f, threshhold, intensity)); + source.filterMode = FilterMode.Bilinear; + + var rtW = source.width/divider; + var rtH = source.height/divider; + + // downsample + RenderTexture rt = RenderTexture.GetTemporary (rtW, rtH, 0, source.format); + rt.filterMode = FilterMode.Bilinear; + Graphics.Blit (source, rt, fastBloomMaterial, 1); + + int passOffs = blurType == BlurType.Standard ? 0 : 2; + + for(int i = 0; i < blurIterations; i++) { + fastBloomMaterial.SetVector("_Parameter", new Vector4(blurSize * widthMod + (i * 1.0f), 0.0f, threshhold, intensity)); + + // vertical blur + RenderTexture rt2 = RenderTexture.GetTemporary (rtW, rtH, 0, source.format); + rt2.filterMode = FilterMode.Bilinear; + Graphics.Blit (rt, rt2, fastBloomMaterial, 2 + passOffs); + RenderTexture.ReleaseTemporary (rt); + rt = rt2; + + // horizontal blur + rt2 = RenderTexture.GetTemporary (rtW, rtH, 0, source.format); + rt2.filterMode = FilterMode.Bilinear; + Graphics.Blit (rt, rt2, fastBloomMaterial, 3 + passOffs); + RenderTexture.ReleaseTemporary (rt); + rt = rt2; + } + + fastBloomMaterial.SetTexture ("_Bloom", rt); + + Graphics.Blit (source, destination, fastBloomMaterial, 0); + + RenderTexture.ReleaseTemporary (rt); + } +} diff --git a/Client/Assets/Scripts/PostEffect/FastBloom.cs.meta b/Client/Assets/Scripts/PostEffect/FastBloom.cs.meta new file mode 100644 index 00000000..1481e663 --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/FastBloom.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 39c2cc4fdc1ebc44c8504cdaa40d51c6 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Client/Assets/Scripts/PostEffect/FxPro.cs b/Client/Assets/Scripts/PostEffect/FxPro.cs new file mode 100644 index 00000000..d53d3227 --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/FxPro.cs @@ -0,0 +1,699 @@ +#define FXPRO_EFFECT +//#define BLOOMPRO_EFFECT +//#define GLOWPRO_EFFECT +//#define DOFPRO_EFFECT + +#if FXPRO_EFFECT +#define GLOWPRO_EFFECT +#define BLOOMPRO_EFFECT +//#define DOFPRO_EFFECT +#define MOBILEDOFPRO_EFFECT +#endif + +using UnityEngine; + +using System.Collections.Generic; + +#if FXPRO_EFFECT +using FxProNS; +#elif BLOOMPRO_EFFECT +using BloomProNS; +#elif GLOWPRO_EFFECT +using GlowProNS; +#elif DOFPRO_EFFECT +using DOFProNS; +#elif MOBILEDOFPRO_EFFECT +using MobileDOFProNS; +#endif + +[ExecuteInEditMode] +[RequireComponent(typeof(Camera))] +#if FXPRO_EFFECT +[AddComponentMenu("Image Effects/FxPro™")] +public class FxPro : MonoBehaviour, XUtliPoolLib.IFxPro +#elif BLOOMPRO_EFFECT +[AddComponentMenu( "Image Effects/BloomPro™" )] +public class BloomPro : MonoBehaviour +#elif GLOWPRO_EFFECT +[AddComponentMenu( "Image Effects/GlowPro™" )] +public class GlowPro : MonoBehaviour +#elif DOFPRO_EFFECT +[AddComponentMenu( "Image Effects/DOF Pro™" )] +public class DOFPro : MonoBehaviour +#endif +{ + public EffectsQuality Quality = EffectsQuality.Normal; + + private static Material _mat; + + public static Material Mat + { + get + { + if (null == _mat) + { + Shader shader = XUtliPoolLib.ShaderManager.singleton.FindShader("FxPro", "Hidden/FxPro"); + _mat = new Material(shader) + { + hideFlags = HideFlags.HideAndDontSave + }; + } + //_mat = new Material( Shader.Find("Hidden/FxPro") ) { + // hideFlags = HideFlags.HideAndDontSave + // }; + + return _mat; + } + } + + private static Material _tapMat; + + private static Material TapMat + { + get + { + if ( null == _tapMat ) + { + Shader shader = XUtliPoolLib.ShaderManager.singleton.FindShader("FxProTap", "Hidden/FxProTap"); + _tapMat = new Material(shader) + { + hideFlags = HideFlags.HideAndDontSave + }; + } + + return _tapMat; + } + } + + //Bloom +#if BLOOMPRO_EFFECT + public bool BloomEnabled = true; + public BloomHelperParams BloomParams = new BloomHelperParams(); + public bool VisualizeBloom = false; +#endif + + public Texture2D LensDirtTexture = null; + + [Range(0f, 2f)] + public float LensDirtIntensity = 1f; + + + public bool ChromaticAberration = false; + public bool ChromaticAberrationPrecise = false; + + [Range(1f, 2.5f)] + public float ChromaticAberrationOffset = 1f; + + [Range( 0f, 1f )] + public float SCurveIntensity = .5f; + + + public bool LensCurvatureEnabled = false; + [Range( 1f, 2f )] + public float LensCurvaturePower = 1.1f; + public bool LensCurvaturePrecise = false; + + [Range( 0f, 1f )] + public float FilmGrainIntensity = .15f; + [Range( 1f, 10f )] + public float FilmGrainTiling = 4f; + + [Range( 0f, 1f )] + public float VignettingIntensity = .5f; + + //Depth of Field +#if DOFPRO_EFFECT + public bool DOFEnabled = false; + public bool BlurCOCTexture = true; + public DOFHelperParams DOFParams = new DOFHelperParams(); + + public bool VisualizeCOC = false; +#endif + +#if MOBILEDOFPRO_EFFECT + public bool MobileDOFEnabled = false; + [Range(0f, 1f)] + public float DOF_FadeInFadeOut = 1; + + //public bool MobileBlurCOCTexture = true; + public MobileDOFHelperParams MobileDOFParams = new MobileDOFHelperParams(); + + // public bool MobileVisualizeCOC = false; +#endif + + private const bool VisualizeLensCurvature = false; + //private Texture2D _gridTexture; + + private List _filmGrainTextures; + + //Color Grading + public bool ColorEffectsEnabled = true; + + public Texture2D colorGradingLut; + //[Range(0f, 1f)] + //public float Adapted_lum = 0.5f; +#if ((UNITY_EDITOR) || (UNITY_STANDALONE) || (UNITY_IOS)) + public void Start() + { + + + if (!SystemInfo.supportsImageEffects) + { + Debug.LogError("Image effects are not supported on this platform."); + enabled = false; + return; + } + + if ( VisualizeLensCurvature ) + { + //_gridTexture = Resources.Load( "lens_curvature_grid" ) as Texture2D; + + //if ( null == _gridTexture ) + // Debug.LogError( "null == _gridTexture" ); + +// Debug.Log( "loaded grid tex" ); + } + + _filmGrainTextures = new List(); + + for ( int i = 1; i <= 4; i++ ) + { + var resourceName = "filmgrain_0" + i; + + var curTex = Resources.Load( resourceName ) as Texture2D; + + if ( null == curTex ) + { + //Debug.LogError( "Unable to load grain texture '" + resourceName + "'" ); + continue; + } + + _filmGrainTextures.Add( curTex ); + } + } + + public void Init(bool searchForNonDepthmapAlphaObjects) { + Mat.SetFloat( "_DirtIntensity", Mathf.Exp( LensDirtIntensity ) - 1f ); + + if (null == LensDirtTexture || LensDirtIntensity <= 0f) { + Mat.DisableKeyword( "LENS_DIRT_ON" ); + Mat.EnableKeyword( "LENS_DIRT_OFF" ); + } else { + Mat.SetTexture( "_LensDirtTex", LensDirtTexture ); + Mat.EnableKeyword( "LENS_DIRT_ON" ); + Mat.DisableKeyword( "LENS_DIRT_OFF" ); + } + +#if BLOOMPRO_EFFECT + if ( ChromaticAberration ) + { + Mat.EnableKeyword( "CHROMATIC_ABERRATION_ON" ); + Mat.DisableKeyword( "CHROMATIC_ABERRATION_OFF" ); + } else + { + Mat.EnableKeyword( "CHROMATIC_ABERRATION_OFF" ); + Mat.DisableKeyword( "CHROMATIC_ABERRATION_ON" ); + } +#endif + + if (GetComponent().hdr) { + Shader.EnableKeyword( "FXPRO_HDR_ON" ); + } else { + Shader.EnableKeyword( "FXPRO_HDR_OFF" ); + } + + Mat.SetFloat( "_SCurveIntensity", SCurveIntensity ); + + // + //Depth of Field +#if DOFPRO_EFFECT + if (DOFEnabled) { + + if (null == DOFParams.EffectCamera) { + DOFParams.EffectCamera = GetComponent(); + } + + //Validating DOF parameters + DOFParams.DepthCompression = Mathf.Clamp( DOFParams.DepthCompression, 2f, 8f ); + + DOFHelper.Instance.SetParams( DOFParams ); + DOFHelper.Instance.Init( searchForNonDepthmapAlphaObjects ); + + Mat.DisableKeyword( "DOF_DISABLED" ); + Mat.EnableKeyword( "DOF_ENABLED" ); + + //Less blur when using fastest quality + if (!DOFParams.DoubleIntensityBlur) + DOFHelper.Instance.SetBlurRadius( (Quality == EffectsQuality.Fastest || Quality == EffectsQuality.Fast) ? 3 : 5 ); + else + DOFHelper.Instance.SetBlurRadius( (Quality == EffectsQuality.Fastest || Quality == EffectsQuality.Fast) ? 5 : 10 ); + } else { + Mat.EnableKeyword( "DOF_DISABLED" ); + Mat.DisableKeyword( "DOF_ENABLED" ); + } +#else + //Mat.EnableKeyword( "DOF_DISABLED" ); + //Mat.DisableKeyword( "DOF_ENABLED" ); +#endif + +#if MOBILEDOFPRO_EFFECT + + if (MobileDOFEnabled) + { + + if (null == MobileDOFParams.EffectCamera) + { + MobileDOFParams.EffectCamera = GetComponent(); + } + + //Validating DOF parameters + //MobileDOFParams.DepthCompression = Mathf.Clamp(MobileDOFParams.DepthCompression, 2f, 8f); + + MobileDOFHelper.Instance.SetParams(MobileDOFParams); + MobileDOFHelper.Instance.Init(searchForNonDepthmapAlphaObjects); + + Mat.DisableKeyword("MOBILEDOF_DISABLED"); + Mat.EnableKeyword("MOBILEDOF_ENABLED"); + + //Less blur when using fastest quality + //if (!MobileDOFParams.DoubleIntensityBlur) + MobileDOFHelper.Instance.SetBlurRadius((Quality == EffectsQuality.Fastest || Quality == EffectsQuality.Fast) ? 3 : 5); + //else + // MobileDOFHelper.Instance.SetBlurRadius((Quality == EffectsQuality.Fastest || Quality == EffectsQuality.Fast) ? 5 : 10); + } + else + { + + Mat.EnableKeyword("MOBILEDOF_DISABLED"); + Mat.DisableKeyword("MOBILEDOF_ENABLED"); + } +#endif + + // + //Bloom +#if BLOOMPRO_EFFECT + if (BloomEnabled) { + BloomParams.Quality = Quality; + BloomHelper.Instance.SetParams(BloomParams); + BloomHelper.Instance.Init(); + + Mat.DisableKeyword("BLOOM_DISABLED"); + Mat.EnableKeyword("BLOOM_ENABLED"); + } else { + Mat.EnableKeyword( "BLOOM_DISABLED" ); + Mat.DisableKeyword( "BLOOM_ENABLED" ); + } +#endif + + if ( LensCurvatureEnabled ) + { + UpdateLensCurvatureZoom(); + Mat.SetFloat( "_LensCurvatureBarrelPower", LensCurvaturePower ); + } + + if ( FilmGrainIntensity >= .001f ) + { + Mat.SetFloat( "_FilmGrainIntensity", FilmGrainIntensity ); + Mat.SetFloat( "_FilmGrainTiling", FilmGrainTiling ); + + Mat.EnableKeyword( "FILM_GRAIN_ON" ); + Mat.DisableKeyword( "FILM_GRAIN_OFF" ); + } else { + Mat.EnableKeyword( "FILM_GRAIN_OFF" ); + Mat.DisableKeyword( "FILM_GRAIN_ON" ); + } + + if ( VignettingIntensity <= 001f ) + { + Mat.SetFloat( "_VignettingIntensity", VignettingIntensity ); + + Mat.EnableKeyword( "VIGNETTING_ON" ); + Mat.DisableKeyword( "VIGNETTING_OFF" ); + } else + { + Mat.EnableKeyword( "VIGNETTING_OFF" ); + Mat.DisableKeyword( "VIGNETTING_ON" ); + } + Mat.SetFloat("_VignettingIntensity", VignettingIntensity); + //Mat.SetFloat("_adapted_lum", Adapted_lum); + + if ( ColorEffectsEnabled ) { + Mat.EnableKeyword( "COLOR_FX_ON" ); + Mat.DisableKeyword( "COLOR_FX_OFF" ); + + Mat.SetTexture("_RgbTex", colorGradingLut); + + } else { + Mat.EnableKeyword( "COLOR_FX_OFF" ); + Mat.DisableKeyword( "COLOR_FX_ON" ); + } + } + + public void OnEnable() { + Init( true ); + } + + public void OnDisable() + { + if(null != Mat) + DestroyImmediate(Mat); + + RenderTextureManager.Instance.Dispose(); + +#if DOFPRO_EFFECT + DOFHelper.Instance.Dispose(); +#endif + +#if MOBILEDOFPRO_EFFECT + MobileDOFHelper.Instance.Dispose(); +#endif + +#if BLOOMPRO_EFFECT + BloomHelper.Instance.Dispose(); + #endif + } + + // + //Settings: + // + //High: 10 blur, 5 samples + //Normal: 5 blur, 5 samples + //Fast: 5 blur, 3 samples + //Fastest: 5 blur, 3 samples, 2 pre-samples + + + + public void OnValidate() + { + if(this.enabled) + Init( false ); + } + + public static RenderTexture DownsampleTex( RenderTexture input, float downsampleBy ) { + RenderTexture tempRenderTex = RenderTextureManager.Instance.RequestRenderTexture( Mathf.RoundToInt( (float)input.width / downsampleBy ), Mathf.RoundToInt( (float)input.height / downsampleBy ), input.depth, input.format); + tempRenderTex.filterMode = FilterMode.Bilinear; + + //Downsample pass +// Graphics.Blit(input, tempRenderTex, _mat, 1); + + const float off = 1f; + Graphics.BlitMultiTap( input, tempRenderTex, TapMat, + new Vector2( -off, -off ), + new Vector2( -off, off ), + new Vector2( off, off ), + new Vector2( off, -off ) + ); + + return tempRenderTex; + } + + private RenderTexture ApplyColorEffects( RenderTexture input ) + { + if ( !ColorEffectsEnabled || colorGradingLut == null) + return input; + + RenderTexture tempRenderTex = RenderTextureManager.Instance.RequestRenderTexture( input.width, input.height, input.depth, input.format ); + + Graphics.Blit( input, tempRenderTex, Mat, 5 ); + + return tempRenderTex; + } + + private RenderTexture ApplyLensCurvature( RenderTexture input ) + { + if ( !LensCurvatureEnabled ) + return input; + + RenderTexture tempRenderTex = RenderTextureManager.Instance.RequestRenderTexture( input.width, input.height, input.depth, input.format ); + +// if ( VisualizeLensCurvature ) +// { +// Graphics.Blit( _gridTexture, destination, Mat, LensCurvaturePrecise ? 3 : 4 ); +// return; +// } + + Graphics.Blit( input, tempRenderTex, Mat, LensCurvaturePrecise ? 3 : 4 ); + + return tempRenderTex; + } + + private RenderTexture ApplyChromaticAberration( RenderTexture input ) + { + if (!ChromaticAberration) return null; + + RenderTexture tempRenderTex = RenderTextureManager.Instance.RequestRenderTexture( input.width, input.height, input.depth, input.format); + tempRenderTex.filterMode = FilterMode.Bilinear; + + //Chromatic aberration pass + Graphics.Blit(input, tempRenderTex, Mat, 2); + + Mat.SetTexture("_ChromAberrTex", tempRenderTex); //Chromatic abberation texture + + return tempRenderTex; + } + + Vector2 ApplyLensCurvature( Vector2 uv, float barrelPower, bool precise ) + { + uv = uv * 2f - Vector2.one; + + uv.x *= GetComponent().aspect * 2f; + + float theta = Mathf.Atan2( uv.y, uv.x ); + + //return float2(theta, theta); + + float radius = uv.magnitude; + + if ( precise ) + radius = Mathf.Pow( radius, barrelPower ); + else + radius = Mathf.Lerp( radius, radius * radius, Mathf.Clamp01( barrelPower - 1f ) ); + + uv.x = radius * Mathf.Cos( theta ); + uv.y = radius * Mathf.Sin( theta ); + + uv.x /= GetComponent().aspect * 2f; + + return 0.5f * (uv + Vector2.one); + } + + private void UpdateLensCurvatureZoom() + { + Vector2 cornerCoords = ApplyLensCurvature( new Vector2( 1f, 1f ), LensCurvaturePower, LensCurvaturePrecise ); + + //Debug.Log( "cornerCoords: " + cornerCoords ); + + float lensCurvatureZoom = 1f / cornerCoords.x; + + //lensCurvatureZoom /= camera.aspect; + + //Debug.Log( "lensCurvatureZoom: " + lensCurvatureZoom ); + + Mat.SetFloat( "_LensCurvatureZoom", lensCurvatureZoom ); + } + + private void UpdateFilmGrain() + { + if ( FilmGrainIntensity >= .001f ) + { + int curTex = Random.Range( 0, 3 ); + Mat.SetTexture( "_FilmGrainTex", _filmGrainTextures[curTex] ); + + //Debug.Log( "curTex: " + curTex ); + + int grainChannel = Random.Range( 0, 3 ); + + switch ( grainChannel ) + { + case 0: + Mat.SetVector( "_FilmGrainChannel", new Vector4(1f, 0f, 0f, 0f) ); + break; + + case 1: + Mat.SetVector( "_FilmGrainChannel", new Vector4( 0f, 1f, 0f, 0f ) ); + break; + + case 2: + Mat.SetVector( "_FilmGrainChannel", new Vector4( 0f, 0f, 1f, 0f ) ); + break; + + case 3: + Mat.SetVector( "_FilmGrainChannel", new Vector4( 0f, 0f, 0f, 1f ) ); + break; + } + } + } + + void RenderEffects(RenderTexture source, RenderTexture destination) + { + source.filterMode = FilterMode.Bilinear; + + //UpdateFilmGrain(); + + RenderTexture chromaticAberrationTex = source; + RenderTexture curRenderTex = source; + RenderTexture srcProcessed; + + srcProcessed = ApplyColorEffects(source); + + RenderTextureManager.Instance.SafeAssign( ref srcProcessed, ApplyLensCurvature(srcProcessed) ); + + //Render chromatic aberration at full res + if ( ChromaticAberrationPrecise ) + chromaticAberrationTex = ApplyChromaticAberration( srcProcessed ); + + //Optimization - render all at 1/2 resolution + RenderTextureManager.Instance.SafeAssign( ref curRenderTex, DownsampleTex( srcProcessed, 2f ) ); + + if (Quality == EffectsQuality.Fastest) + RenderTextureManager.Instance.SafeAssign( ref curRenderTex, DownsampleTex( curRenderTex, 2f ) ); + + // + //Depth of Field + // + //Optimization: being rendered at 1/2 resolution + // +#if DOFPRO_EFFECT + RenderTexture cocRenderTex = null, dofRenderTex = null; + if (DOFEnabled) { + if (null == DOFParams.EffectCamera) + { + Debug.LogError("null == DOFParams.camera"); + return; + } + + cocRenderTex = RenderTextureManager.Instance.RequestRenderTexture(curRenderTex.width, curRenderTex.height, curRenderTex.depth, curRenderTex.format); + + DOFHelper.Instance.RenderCOCTexture(curRenderTex, cocRenderTex, BlurCOCTexture ? 1.5f : 0f); + + if (VisualizeCOC) + { + Graphics.Blit(cocRenderTex, destination, DOFHelper.Mat, 3); + RenderTextureManager.Instance.ReleaseRenderTexture(cocRenderTex); + RenderTextureManager.Instance.ReleaseRenderTexture(curRenderTex); + return; + } + + dofRenderTex = RenderTextureManager.Instance.RequestRenderTexture(curRenderTex.width, curRenderTex.height, curRenderTex.depth, curRenderTex.format); + + DOFHelper.Instance.RenderDOFBlur(curRenderTex, dofRenderTex, cocRenderTex); + + Mat.SetTexture("_DOFTex", dofRenderTex); + Mat.SetTexture("_COCTex", cocRenderTex); + + //Make bloom DOF-based? + //RenderTextureManager.Instance.SafeAssign(ref curRenderTex, dofRenderTex); + //Graphics.Blit(dofRenderTex, destination); + + } + else + { + if (null != DOFParams.EffectCamera) + { + DOFParams.EffectCamera.depthTextureMode = DepthTextureMode.None; + } + } +#endif + +#if MOBILEDOFPRO_EFFECT + RenderTexture MobiledofRenderTex = null; + if (MobileDOFEnabled) + { + if (null == MobileDOFParams.EffectCamera) + { + Debug.LogError("null == MobileDOFParams.camera"); + return; + } + + MobiledofRenderTex = RenderTextureManager.Instance.RequestRenderTexture(curRenderTex.width, curRenderTex.height, curRenderTex.depth, curRenderTex.format); + MobileDOFHelper.Instance.RenderMobileDOFBlur(curRenderTex, MobiledofRenderTex); + Mat.SetTexture("_MobileDOFTex", MobiledofRenderTex); + DOF_FadeInFadeOut = Mathf.Clamp01(DOF_FadeInFadeOut); + Mat.SetFloat("_DOF_FadeInFadeOut", DOF_FadeInFadeOut); + Graphics.Blit(MobiledofRenderTex, destination); + } + else + { + if (null != MobileDOFParams.EffectCamera) + { + MobileDOFParams.EffectCamera.depthTextureMode = DepthTextureMode.None; + } + } +#endif + + //Render chromatic aberration at half res + if (!ChromaticAberrationPrecise) + chromaticAberrationTex = ApplyChromaticAberration( curRenderTex ); + + //Graphics.Blit( chromaticAberrationTex, destination ); + //return; + + //Render bloom +#if BLOOMPRO_EFFECT + if (BloomEnabled) { + RenderTexture bloomTexture = RenderTextureManager.Instance.RequestRenderTexture(curRenderTex.width, curRenderTex.height, curRenderTex.depth, curRenderTex.format); + BloomHelper.Instance.RenderBloomTexture(curRenderTex, bloomTexture); + + Mat.SetTexture("_BloomTex", bloomTexture); + + if ( VisualizeBloom ) + { + + Graphics.Blit( bloomTexture, destination ); + return; + } + } +#endif + //destination.DiscardContents(); + //Final composite pass + Graphics.Blit( srcProcessed, destination, Mat, 0 ); + +#if DOFPRO_EFFECT + RenderTextureManager.Instance.ReleaseRenderTexture( cocRenderTex ); + RenderTextureManager.Instance.ReleaseRenderTexture( dofRenderTex ); +#endif + +#if MOBILEDOFPRO_EFFECT + //RenderTextureManager.Instance.ReleaseRenderTexture(cocRenderTex); + RenderTextureManager.Instance.ReleaseRenderTexture(MobiledofRenderTex); +#endif + + RenderTextureManager.Instance.ReleaseRenderTexture( curRenderTex ); + RenderTextureManager.Instance.ReleaseRenderTexture( chromaticAberrationTex ); + } + + + [ImageEffectTransformsToLDR] + public void OnRenderImage( RenderTexture source, RenderTexture destination ) + { + RenderEffects(source, destination); + RenderTextureManager.Instance.ReleaseAllRenderTextures(); + } + + public void SetDofFade(float fade) + { + +#if MOBILEDOFPRO_EFFECT + //DOF_FadeInFadeOut = fade; +#endif + } +#else + public void SetDofFade(float fade) + { + } +#endif + public void Enable(bool enable) + { + this.enabled = enable; + } +} +//Bloom: +//full screen chromab: 6.7ms; without - 4.9ms; 1/4 screen chromab: 5.2ms +// +//5 samples: 4.3 ms; 3 samples :3.6ms +//2 pre-samples, 3 total: 3.1 ms +27% +// +//HQ: 4.8ms +//NQ: 4.3ms +//FQ: 3.9ms +//FSQ: 3.4ms \ No newline at end of file diff --git a/Client/Assets/Scripts/PostEffect/FxPro.cs.meta b/Client/Assets/Scripts/PostEffect/FxPro.cs.meta new file mode 100644 index 00000000..a265a261 --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/FxPro.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 72d1c7ad977e8074588fe29b01a5d2e2 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Client/Assets/Scripts/PostEffect/MobileBloom.cs b/Client/Assets/Scripts/PostEffect/MobileBloom.cs new file mode 100644 index 00000000..64681b87 --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/MobileBloom.cs @@ -0,0 +1,118 @@ +using UnityEngine; +using System.Collections; + +[RequireComponent(typeof(Camera))] +public class MobileBloom : MobilePostEffectsBase +{ + public enum Resolution { + Low = 0, + High = 1, + } + + public enum BlurType { + Standard = 0, + Sgx = 1, + } + public enum BlurDir + { + vertical = 0, + horizontal = 1, + both = 2 + } + [Range(0.0f, 1.5f)] + public float threshhold = 0.25f; + + [Range(0.0f, 2.5f)] + public float intensity = 0.75f; + + [Range(0.25f, 5.5f)] + public float blurSize = 1.0f; + + Resolution resolution = Resolution.Low; + [Range(1, 4)] + private int blurIterations = 1; + + private BlurType blurType = BlurType.Sgx; + + public BlurDir blurDir = BlurDir.vertical; + + public Shader fastBloomShader; + private Material fastBloomMaterial = null; + + new bool CheckResources () + { + CheckSupport (false); + + if(fastBloomShader==null) + fastBloomShader = Shader.Find("Hidden/FastBloom"); + if (fastBloomMaterial==null) + fastBloomMaterial = CheckShaderAndCreateMaterial (fastBloomShader, fastBloomMaterial); + + //if(!isSupported) + // ReportAutoDisable (); + return isSupported; + } + + void OnDisable() + { + if (fastBloomMaterial) + DestroyImmediate(fastBloomMaterial); + } + + void OnRenderImage (RenderTexture source,RenderTexture destination) + { + if(CheckResources() == false) + { + //Graphics.Blit (source, destination); + return; + } + + int divider = resolution == Resolution.Low ? 4 : 2; + float widthMod = resolution == Resolution.Low ? 0.5f : 1.0f; + + fastBloomMaterial.SetVector("_Parameter", new Vector4(blurSize * widthMod, 0.0f, threshhold, intensity)); + source.filterMode = FilterMode.Bilinear; + + int rtW = source.width / divider; + int rtH = source.height / divider; + + // downsample + RenderTexture rt = RenderTexture.GetTemporary (rtW, rtH, 0, source.format); + rt.filterMode = FilterMode.Bilinear; + Graphics.Blit (source, rt, fastBloomMaterial, 1); + + int passOffs = blurType == BlurType.Standard ? 0 : 2; + + for(int i = 0; i < blurIterations; i++) + { + fastBloomMaterial.SetVector ("_Parameter", new Vector4 (blurSize * widthMod + (i*1.0f), 0.0f, threshhold, intensity)); + RenderTexture rt2 = null; + if (blurDir == BlurDir.vertical || blurDir == BlurDir.both) + { + // vertical blur + rt2 = RenderTexture.GetTemporary(rtW, rtH, 0, source.format); + rt2.filterMode = FilterMode.Bilinear; + Graphics.Blit(rt, rt2, fastBloomMaterial, 2 + passOffs); + RenderTexture.ReleaseTemporary(rt); + rt = rt2; + } + + if (blurDir == BlurDir.horizontal || blurDir == BlurDir.both) + { + // horizontal blur + rt2 = RenderTexture.GetTemporary(rtW, rtH, 0, source.format); + rt2.filterMode = FilterMode.Bilinear; + Graphics.Blit(rt, rt2, fastBloomMaterial, 3 + passOffs); + RenderTexture.ReleaseTemporary(rt); + rt = rt2; + } + + } + + fastBloomMaterial.SetTexture("_Bloom", rt); + + Graphics.Blit(source, destination, fastBloomMaterial, 0); + + RenderTexture.ReleaseTemporary(rt); + } +} \ No newline at end of file diff --git a/Client/Assets/Scripts/PostEffect/MobileBloom.cs.meta b/Client/Assets/Scripts/PostEffect/MobileBloom.cs.meta new file mode 100644 index 00000000..4a789085 --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/MobileBloom.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 745a7cc06501e994cb3a4b049a703e84 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Client/Assets/Scripts/PostEffect/MobileDOFHelper.cs b/Client/Assets/Scripts/PostEffect/MobileDOFHelper.cs new file mode 100644 index 00000000..1f1725d0 --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/MobileDOFHelper.cs @@ -0,0 +1,158 @@ +using System; +using UnityEngine; +using System.Collections.Generic; + +using Object = UnityEngine.Object; + +namespace FxProNS +{ + [Serializable] + public class MobileDOFHelperParams + { + public Camera EffectCamera; + public Transform Target; + + [Range(.01f, 1f)] + public float FocalLengthMultiplier = .33f; + + + + [Range(.5f, 2f)] + public float DOFBlurSize = 1f; + + public float NonTargetFocalDist = 1f; + } + public class MobileDOFHelper : Singleton, IDisposable + { + private static Material _mat; + + public static Material Mat + { + get + { + if (null == _mat) + { + Shader shader = XUtliPoolLib.ShaderManager.singleton.FindShader("MobileDOFPro", "Hidden/MobileDOFPro"); + _mat = new Material(shader) + { + hideFlags = HideFlags.HideAndDontSave + }; + } + + return _mat; + } + } + + + private MobileDOFHelperParams _p; + + public void SetParams(MobileDOFHelperParams p) + { + _p = p; + } + + public void Init(bool searchForNonDepthmapAlphaObjects) + { + _p.FocalLengthMultiplier = Mathf.Clamp(_p.FocalLengthMultiplier, .01f, .99f); + if (_p.EffectCamera.depthTextureMode != DepthTextureMode.DepthNormals) + _p.EffectCamera.depthTextureMode = DepthTextureMode.Depth; + + Mat.EnableKeyword("USE_CAMERA_DEPTH_TEXTURE"); + Mat.DisableKeyword("DONT_USE_CAMERA_DEPTH_TEXTURE"); + } + + private void CalculateAndUpdateFocalDist() + { + if (null == _p.EffectCamera) + { + Debug.LogError("null == p.camera"); + return; + } + + float focalDist; + + if (null != _p.Target) + { + Vector3 targetPosInViewportSpace = _p.EffectCamera.WorldToViewportPoint(_p.Target.position); + focalDist = targetPosInViewportSpace.z; + // float focalDist = (target.position - transform.position).magnitude / camera.farClipPlane; + } + else + { + focalDist = _p.NonTargetFocalDist; + // Debug.Log("focalDist: " + focalDist); + } + + focalDist /= _p.EffectCamera.farClipPlane; + + //focalDist *= _p.FocalDistMultiplier ; + + Mat.SetFloat("_FocalDist", focalDist); + + //Make sure that focalLength < focalDist + Mat.SetFloat("_FocalLength", focalDist * _p.FocalLengthMultiplier); + } + + + public void RenderMobileDOFBlur(RenderTexture src, RenderTexture dest) + { + //Graphics.Blit( src, dest ); + + //if (null == cocTexture) + //{ + // Debug.LogError("null == cocTexture"); + // return; + //} + + //Mat.SetTexture("_COCTex", cocTexture); + + // //Apply separable DOF + + //Mat.SetFloat("", _p.FocalLengthMultiplier); + //Mat.SetFloat("", _p.FocalDistMultiplier); + + CalculateAndUpdateFocalDist(); + + RenderTexture tempRt = RenderTextureManager.Instance.RequestRenderTexture(src.width, src.height, src.depth, src.format); + + Mat.SetVector("_SeparableBlurOffsets", new Vector4(_p.DOFBlurSize, 0f, 0f, 0f)); + Graphics.Blit(src, tempRt, Mat, 0); + Mat.SetVector("_SeparableBlurOffsets", new Vector4(0f, _p.DOFBlurSize, 0f, 0f)); + Graphics.Blit(tempRt, dest, Mat, 0); + + RenderTextureManager.Instance.ReleaseRenderTexture(tempRt); + + } + + + public void SetBlurRadius(int radius) + { + Shader.DisableKeyword("BLUR_RADIUS_10"); + Shader.DisableKeyword("BLUR_RADIUS_5"); + Shader.DisableKeyword("BLUR_RADIUS_3"); + Shader.DisableKeyword("BLUR_RADIUS_2"); + Shader.DisableKeyword("BLUR_RADIUS_1"); + + if (radius != 10 && radius != 5 && radius != 3 && radius != 2 && radius != 1) radius = 5; + + if (radius < 3) radius = 3; + + //Debug.Log( "blur radius: " + radius ); + + Shader.EnableKeyword("BLUR_RADIUS_" + radius); + } + + + + + + public void Dispose() + { + if (null != Mat) + Object.DestroyImmediate(Mat); + if (_p != null && _p.EffectCamera != null) + _p.EffectCamera.depthTextureMode = DepthTextureMode.None; + RenderTextureManager.Instance.Dispose(); + } + } +} \ No newline at end of file diff --git a/Client/Assets/Scripts/PostEffect/MobileDOFHelper.cs.meta b/Client/Assets/Scripts/PostEffect/MobileDOFHelper.cs.meta new file mode 100644 index 00000000..df137416 --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/MobileDOFHelper.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 450ed0e9b20d370448b8882cf386c942 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Client/Assets/Scripts/PostEffect/MobilePostEffectsBase.cs b/Client/Assets/Scripts/PostEffect/MobilePostEffectsBase.cs new file mode 100644 index 00000000..43c5e905 --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/MobilePostEffectsBase.cs @@ -0,0 +1,214 @@ +using UnityEngine; +using System.Collections; + +[ExecuteInEditMode] +[RequireComponent(typeof(Camera))] +public class MobilePostEffectsBase : MonoBehaviour +{ + protected bool supportHDRTextures = false; + protected bool isSupported = true; + protected void NotSupported() + { + enabled = false; + isSupported = false; + return; + } + protected Material CheckShaderAndCreateMaterial(Shader s, Material m2Create) + { + if (!s) + { + Debug.Log("Missing shader in " + this.ToString()); + enabled = false; + return null; + } + + if (s.isSupported && m2Create && m2Create.shader == s) + return m2Create; + + if (!s.isSupported) + { + NotSupported(); + Debug.Log("The shader " + s.ToString() + " on effect " + this.ToString() + " is not supported on this platform!"); + return null; + } + else + { + m2Create = new Material(s); + m2Create.hideFlags = HideFlags.DontSave; + if (m2Create) + return m2Create; + else return null; + } + } + protected Material CreateMaterial(Shader s, Material m2Create) + { + if (!s) + { + Debug.Log("Missing shader in " + this.ToString()); + return null; + } + + if (m2Create && (m2Create.shader == s) && (s.isSupported)) + return m2Create; + + if (!s.isSupported) + { + return null; + } + else + { + m2Create = new Material(s); + m2Create.hideFlags = HideFlags.DontSave; + if (m2Create) + return m2Create; + else return null; + } + } + protected void OnEnable() + { + isSupported = true; + CheckResources(); + } + + protected bool CheckSupport() + { + return CheckSupport(false); + } + + protected virtual bool CheckResources() + { + Debug.LogWarning("CheckResources () for " + this.ToString() + " should be overwritten."); + return isSupported; + } + + protected bool CheckSupport(bool needDepth) + { + isSupported = true; + supportHDRTextures = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf); + + if (!SystemInfo.supportsImageEffects) { + NotSupported (); + return false; + } + + if(needDepth && !SystemInfo.SupportsRenderTextureFormat (RenderTextureFormat.Depth)) { + NotSupported (); + return false; + } + + if(needDepth) + GetComponent().depthTextureMode |= DepthTextureMode.Depth; + + return true; + } + + protected bool CheckSupport (bool needDepth,bool needHdr) + { + if(!CheckSupport(needDepth)) + return false; + + if(needHdr && !supportHDRTextures) { + NotSupported (); + return false; + } + return true; + } + + protected bool CheckShader(Shader s) + { + Debug.Log("The shader " + s.ToString() + " on effect " + this.ToString() + " is not part of the Unity 3.2+ effects suite anymore. For best performance and quality, please ensure you are using the latest Standard Assets Image Effects (Pro only) package."); + if (!s.isSupported) + { + NotSupported(); + return false; + } + else + { + return false; + } + } + + protected void DrawBorder (RenderTexture dest,Material material) + { + float x1; + float x2; + float y1; + float y2; + + RenderTexture.active = dest; + bool invertY = true; // source.texelSize.y < 0.0f; + // Set up the simple Matrix + GL.PushMatrix(); + GL.LoadOrtho(); + + for (int i = 0; i < material.passCount; i++) + { + material.SetPass(i); + + float y1_; + float y2_; + if (invertY) + { + y1_ = 1.0f; y2_ = 0.0f; + } + else + { + y1_ = 0.0f; y2_ = 1.0f; + } + + // left + x1 = 0.0f; + x2 = 0.0f + 1.0f/(dest.width*1.0f); + y1 = 0.0f; + y2 = 1.0f; + GL.Begin(GL.QUADS); + + GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f); + GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f); + GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f); + GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f); + + // right + x1 = 1.0f - 1.0f/(dest.width*1.0f); + x2 = 1.0f; + y1 = 0.0f; + y2 = 1.0f; + + GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f); + GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f); + GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f); + GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f); + + // top + x1 = 0.0f; + x2 = 1.0f; + y1 = 0.0f; + y2 = 0.0f + 1.0f/(dest.height*1.0f); + + GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f); + GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f); + GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f); + GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f); + + // bottom + x1 = 0.0f; + x2 = 1.0f; + y1 = 1.0f - 1.0f/(dest.height*1.0f); + y2 = 1.0f; + + GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f); + GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f); + GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f); + GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f); + + GL.End(); + } + + GL.PopMatrix(); + } + + // Use this for initialization + void Start () { + + } +} diff --git a/Client/Assets/Scripts/PostEffect/MobilePostEffectsBase.cs.meta b/Client/Assets/Scripts/PostEffect/MobilePostEffectsBase.cs.meta new file mode 100644 index 00000000..e2df78e8 --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/MobilePostEffectsBase.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5f4b2f323cdeba7488c25e12dc2c0056 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Client/Assets/Scripts/PostEffect/PostEffectsBase.cs b/Client/Assets/Scripts/PostEffect/PostEffectsBase.cs new file mode 100644 index 00000000..aa3d3ddc --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/PostEffectsBase.cs @@ -0,0 +1,214 @@ +using UnityEngine; +using System.Collections; + +[ExecuteInEditMode] +[RequireComponent(typeof(Camera))] +public class PostEffectsBase : MonoBehaviour { + + protected bool supportHDRTextures = false; + protected bool isSupported = true; + + protected Material CheckShaderAndCreateMaterial (Shader s,Material m2Create) + { + if (!s) { + //Debug.Log("Missing shader in " + this.ToString ()); + enabled = false; + return null; + } + + if (s.isSupported && m2Create && m2Create.shader == s) + return m2Create; + + if (!s.isSupported) { + NotSupported (); + //Debug.Log("The shader " + s.ToString() + " on effect "+this.ToString()+" is not supported on this platform!"); + return null; + } + else { + m2Create = new Material (s); + m2Create.hideFlags = HideFlags.DontSave; + if (m2Create) + return m2Create; + else return null; + } + } + + protected Material CreateMaterial (Shader s,Material m2Create) + { + if (!s) { + //Debug.Log ("Missing shader in " + this.ToString ()); + return null; + } + + if (m2Create && (m2Create.shader == s) && (s.isSupported)) + return m2Create; + + if (!s.isSupported) { + return null; + } + else { + m2Create = new Material (s); + m2Create.hideFlags = HideFlags.DontSave; + if (m2Create) + return m2Create; + else return null; + } + } + + protected void OnEnable() + { + isSupported = true; + } + + protected bool CheckSupport() + { + return CheckSupport (false); + } + + protected bool CheckResources() + { + //Debug.LogWarning ("CheckResources () for " + this.ToString() + " should be overwritten."); + return isSupported; + } + + void Start () { + CheckResources (); + } + + protected bool CheckSupport(bool needDepth) +{ + isSupported = true; + supportHDRTextures = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf); + //supportDX11 = SystemInfo.graphicsShaderLevel >= 50 && SystemInfo.supportsComputeShaders; + + if (!SystemInfo.supportsImageEffects) { + NotSupported (); + return false; + } + + if(needDepth && !SystemInfo.SupportsRenderTextureFormat (RenderTextureFormat.Depth)) { + NotSupported (); + return false; + } + + if(needDepth) + GetComponent().depthTextureMode |= DepthTextureMode.Depth; + + return true; + } + + protected bool CheckSupport(bool needDepth, bool needHdr) +{ + if(!CheckSupport(needDepth)) + return false; + + if(needHdr && !supportHDRTextures) { + NotSupported (); + return false; + } + + return true; + } + protected void ReportAutoDisable() + { + //Debug.LogWarning ("The image effect " + this.ToString() + " has been disabled as it's not supported on the current platform."); + } + + // deprecated but needed for old effects to survive upgrading + protected bool CheckShader(Shader s) + { + //Debug.Log("The shader " + s.ToString () + " on effect "+ this.ToString () + " is not part of the Unity 3.2+ effects suite anymore. For best performance and quality, please ensure you are using the latest Standard Assets Image Effects (Pro only) package."); + if (!s.isSupported) { + NotSupported (); + return false; + } + else { + return false; + } + } + + protected void NotSupported() + { + enabled = false; + isSupported = false; + return; + } + + protected void DrawBorder(RenderTexture dest, Material material) + { + float x1; + float x2; + float y1; + float y2; + + RenderTexture.active = dest; + bool invertY = true; // source.texelSize.y < 0.0f; + // Set up the simple Matrix + GL.PushMatrix(); + GL.LoadOrtho(); + + for (int i = 0; i < material.passCount; i++) + { + material.SetPass(i); + + float y1_; float y2_; + if (invertY) + { + y1_ = 1.0f; y2_ = 0.0f; + } + else + { + y1_ = 0.0f; y2_ = 1.0f; + } + + // left + x1 = 0.0f; + x2 = 0.0f + 1.0f/(dest.width*1.0f); + y1 = 0.0f; + y2 = 1.0f; + GL.Begin(GL.QUADS); + + GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f); + GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f); + GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f); + GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f); + + // right + x1 = 1.0f - 1.0f/(dest.width*1.0f); + x2 = 1.0f; + y1 = 0.0f; + y2 = 1.0f; + + GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f); + GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f); + GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f); + GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f); + + // top + x1 = 0.0f; + x2 = 1.0f; + y1 = 0.0f; + y2 = 0.0f + 1.0f/(dest.height*1.0f); + + GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f); + GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f); + GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f); + GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f); + + // bottom + x1 = 0.0f; + x2 = 1.0f; + y1 = 1.0f - 1.0f/(dest.height*1.0f); + y2 = 1.0f; + + GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f); + GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f); + GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f); + GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f); + + GL.End(); + } + + GL.PopMatrix(); + } +} diff --git a/Client/Assets/Scripts/PostEffect/PostEffectsBase.cs.meta b/Client/Assets/Scripts/PostEffect/PostEffectsBase.cs.meta new file mode 100644 index 00000000..e9f2b042 --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/PostEffectsBase.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ec31e384218b6464499b35bee88a1298 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Client/Assets/Scripts/PostEffect/RenderTextureManager.cs b/Client/Assets/Scripts/PostEffect/RenderTextureManager.cs new file mode 100644 index 00000000..24291e29 --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/RenderTextureManager.cs @@ -0,0 +1,232 @@ +#define FXPRO_EFFECT +//#define BLOOMPRO_EFFECT +//#define DOFPRO_EFFECT + +using System; +using UnityEngine; +using System.Collections; +using System.Collections.Generic; + +#if FXPRO_EFFECT +namespace FxProNS { +#elif BLOOMPRO_EFFECT +namespace BloomProNS { +#elif DOFPRO_EFFECT +namespace DOFProNS { +#endif + public enum EffectsQuality + { + High, + Normal, + Fast, + Fastest + } + + public abstract class Singleton + where T : class, new() { + + private static bool Compare( T x, T y ) + { + return x == y; + } + + #region Singleton + + private static T instance = default( T ); + + public static T Instance { + get { + if (Compare( default( T ), instance )) { + instance = new T(); + } + + return instance; + } + } + + #endregion + } + + public class RenderTextureManager : IDisposable + { + private static RenderTextureManager instance; + public static RenderTextureManager Instance + { + get + { + return instance ?? (instance = new RenderTextureManager()); + } + } + + private List allRenderTextures = null; + private List availableRenderTextures = null; + + // public RenderTexture RequestRenderTexture(int _width, int _height, int _depth, RenderTextureFormat _format) { + // return RenderTexture.GetTemporary( _width, _height, _depth, _format ); + // } + // + // public RenderTexture ReleaseRenderTexture( RenderTexture _tex ) { + // RenderTexture.ReleaseTemporary( _tex ); + // + // return null; + // } + + public RenderTexture RequestRenderTexture(int _width, int _height, int _depth, RenderTextureFormat _format) { + if (null == allRenderTextures) + allRenderTextures = new List(); + + if (null == availableRenderTextures) + availableRenderTextures = new List(); + + //First look for an available RenderTexture + RenderTexture tempTex = null; + for (int i = 0, imax = availableRenderTextures.Count; i < imax; ++i) + { + RenderTexture rt = availableRenderTextures[i]; + if (null == rt) + continue; + + if (rt.width == _width && rt.height == _height && rt.depth == _depth && rt.format == _format) + { + tempTex = rt; + } + } + + if (null != tempTex) + { + MakeRenderTextureNonAvailable(tempTex); + + // PrintRenderTextureStats(); + tempTex.DiscardContents(true, true); + return tempTex; + } + + //Create a new texture if it was not found. + tempTex = CreateNewTexture( _width, _height, _depth, _format ); + MakeRenderTextureNonAvailable( tempTex ); + // PrintRenderTextureStats(); + + return tempTex; + } + + public RenderTexture ReleaseRenderTexture( RenderTexture _tex ) { + // Debug.Log( "ReleaseRenderTexture: " + RenderTexToString(_tex) + "" ); + + if (null == _tex || null == availableRenderTextures) + return null; + + if ( availableRenderTextures.Contains( _tex ) ) { + // Debug.Log( "Already available" ); + return null; + } + + availableRenderTextures.Add( _tex ); + + return null; + } + + /// + /// Releases a, and then assigns b to a (a = b). + /// + /// + /// + public void SafeAssign( ref RenderTexture a, RenderTexture b ) + { + if ( a == b ) + return; + + ReleaseRenderTexture( a ); + a = b; + + //return b; + } + + public void MakeRenderTextureNonAvailable ( RenderTexture _tex ) { + // Debug.Log("MakeRenderTextureNonAvailable: " + RenderTexToString( _tex ) ); + if ( availableRenderTextures.Contains (_tex ) ) + availableRenderTextures.Remove( _tex ); + } + + + private RenderTexture CreateNewTexture( int _width, int _height, int _depth, RenderTextureFormat _format ) { + RenderTexture newTexture = new RenderTexture( _width, _height, _depth, _format ); + newTexture.Create(); + newTexture.DiscardContents(true, true); + allRenderTextures.Add( newTexture ); + availableRenderTextures.Add( newTexture ); + + // Debug.Log("CreateNewTexture: " + RenderTexToString(newTexture) + ""); + + return newTexture; + } + + public void PrintRenderTextureStats() { + string resString = "availableRenderTextures: " + availableRenderTextures.Count + "\n"; + for (int i = 0, imax = availableRenderTextures.Count; i < imax; ++i) + { + RenderTexture rt = availableRenderTextures[i]; + resString += "\t" + RenderTexToString(rt) + "\n"; + } + + Debug.Log(resString); + + resString = "allRenderTextures:" + allRenderTextures.Count + "\n"; + for (int i = 0, imax = allRenderTextures.Count; i < imax; ++i) + { + RenderTexture rt = allRenderTextures[i]; + resString += "\t" + RenderTexToString(rt) + "\n"; + } + + Debug.Log(resString); + } + + private string RenderTexToString( RenderTexture _rt ) { + if (null == _rt) + return "null"; + + return _rt.width + " x " + _rt.height + "\t" + _rt.depth + "\t" + _rt.format; + } + + private void PrintRenderTexturesCount(string _prefix = "") { + Debug.Log(_prefix + ": " + (allRenderTextures.Count - availableRenderTextures.Count) + "/" + allRenderTextures.Count); + } + + //Should be called every frame to make sure that we don't hold on to render textures that are no longer used. + public void ReleaseAllRenderTextures() { + if (null == allRenderTextures) + return; + for (int i = 0, imax = allRenderTextures.Count; i < imax; ++i) + { + RenderTexture rt = allRenderTextures[i]; + if (!availableRenderTextures.Contains(rt)) + { + //Debug.Log("RT not released: " + RenderTexToString(rt) + "" ); + ReleaseRenderTexture(rt); + } + } + } + + public void PrintBalance() + { + Debug.Log( "RenderTextures balance: " + (allRenderTextures.Count - availableRenderTextures.Count) + "/" + allRenderTextures.Count ); + } + + public void Dispose() { + // Debug.Log("Dispose"); + + if (null != allRenderTextures) { + for (int i = 0, imax = allRenderTextures.Count; i < imax; ++i) + { + RenderTexture rt = allRenderTextures[i]; + rt.Release(); + } + + allRenderTextures.Clear(); + } + + if (null != availableRenderTextures) { + availableRenderTextures.Clear(); + } + } + } +} \ No newline at end of file diff --git a/Client/Assets/Scripts/PostEffect/RenderTextureManager.cs.meta b/Client/Assets/Scripts/PostEffect/RenderTextureManager.cs.meta new file mode 100644 index 00000000..38e2d535 --- /dev/null +++ b/Client/Assets/Scripts/PostEffect/RenderTextureManager.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: aa405469bb1a9c146a6a19117b30890b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: -- cgit v1.1-26-g67d0