少年修仙传客户端代码仓库
client_Hale
2018-08-31 bd5250bad6e53291bd520e56942fa141d4a79c2b
Merge branch 'master' of http://192.168.0.87:10010/r/snxxz_scripts
11个文件已修改
2773 ■■■■ 已修改文件
Core/DynamicShadowProjector/ShadowTextureRenderer.cs 2312 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/Compose/New/ComposeTicketWin.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/Compose/New/ComposeToolsWin.cs 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/Compose/New/ComposeWinModel.cs 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/Compose/New/ComposeWingsWin.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/Dungeon/TargetBriefInfoWin.cs 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/FairyAu/FairyGrabBossHintWin.cs 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/FairyAu/FairyGrabBossModel.cs 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/FairyAu/FairyGrabBossWin.cs 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/KnapSack/Logic/ItemTipsModel.cs 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
System/Message/RichMoveEvent.cs 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Core/DynamicShadowProjector/ShadowTextureRenderer.cs
@@ -10,1134 +10,1298 @@
using UnityEngine.Rendering;
using System.Collections.Generic;
namespace DynamicShadowProjector {
    [ExecuteInEditMode]
    [DisallowMultipleComponent]
    [RequireComponent(typeof(Projector))]
    public class ShadowTextureRenderer : MonoBehaviour {
        public enum TextureMultiSample {
            x1 = 1,
            x2 = 2,
            x4 = 4,
            x8 = 8,
        }
        public enum TextureSuperSample {
            x1 = 1,
            x4 = 2,
            x16 = 4,
        }
        public enum MipmapFalloff {
            None = 0,
            Linear,
            Custom,
        }
        public enum BlurFilter {
            Uniform = 0,
            Gaussian,
        }
        // Serialize Fields
        [SerializeField]
        private TextureMultiSample m_multiSampling = TextureMultiSample.x4;
        [SerializeField]
        private TextureSuperSample m_superSampling = TextureSuperSample.x1;
        [SerializeField]
        private MipmapFalloff m_mipmapFalloff = MipmapFalloff.Linear;
        [SerializeField]
        private BlurFilter m_blurFilter = BlurFilter.Uniform;
        [SerializeField]
        private bool m_testViewClip = true;
        [SerializeField]
        private int m_textureWidth = 64;
        [SerializeField]
        private int m_textureHeight = 64;
        [SerializeField]
        private int m_mipLevel = 0;
        [SerializeField]
        private int m_blurLevel = 1;
        [SerializeField]
        private float m_blurSize = 3;
        [SerializeField]
        private float m_mipmapBlurSize = 0;
        [SerializeField]
        private bool m_singlePassMipmapBlur = false;
        [SerializeField]
        private Color m_shadowColor = new Color(0,0,0,1);
        [SerializeField]
        private Material m_blurShader;
        [SerializeField]
        private Material m_downsampleShader;
        [SerializeField]
        private Material m_copyMipmapShader;
        [SerializeField]
        private Material m_eraseShadowShader;
        [SerializeField]
        private float[] m_customMipmapFalloff;
        [SerializeField]
        private RenderTextureFormat[] m_preferredTextureFormats;
        [SerializeField]
        private Camera[] m_camerasForViewClipTest;
namespace DynamicShadowProjector
{
    [ExecuteInEditMode]
    [DisallowMultipleComponent]
    [RequireComponent(typeof(Projector))]
    public class ShadowTextureRenderer : MonoBehaviour
    {
        public enum TextureMultiSample
        {
            x1 = 1,
            x2 = 2,
            x4 = 4,
            x8 = 8,
        }
        public enum TextureSuperSample
        {
            x1 = 1,
            x4 = 2,
            x16 = 4,
        }
        public enum MipmapFalloff
        {
            None = 0,
            Linear,
            Custom,
        }
        public enum BlurFilter
        {
            Uniform = 0,
            Gaussian,
        }
        // Serialize Fields
        [SerializeField]
        private TextureMultiSample m_multiSampling = TextureMultiSample.x4;
        [SerializeField]
        private TextureSuperSample m_superSampling = TextureSuperSample.x1;
        [SerializeField]
        private MipmapFalloff m_mipmapFalloff = MipmapFalloff.Linear;
        [SerializeField]
        private BlurFilter m_blurFilter = BlurFilter.Uniform;
        [SerializeField]
        private bool m_testViewClip = true;
        [SerializeField]
        private int m_textureWidth = 64;
        [SerializeField]
        private int m_textureHeight = 64;
        [SerializeField]
        private int m_mipLevel = 0;
        [SerializeField]
        private int m_blurLevel = 1;
        [SerializeField]
        private float m_blurSize = 3;
        [SerializeField]
        private float m_mipmapBlurSize = 0;
        [SerializeField]
        private bool m_singlePassMipmapBlur = false;
        [SerializeField]
        private Color m_shadowColor = new Color(0, 0, 0, 1);
        [SerializeField]
        private Material m_blurShader;
        [SerializeField]
        private Material m_downsampleShader;
        [SerializeField]
        private Material m_copyMipmapShader;
        [SerializeField]
        private Material m_eraseShadowShader;
        [SerializeField]
        private float[] m_customMipmapFalloff;
        [SerializeField]
        private RenderTextureFormat[] m_preferredTextureFormats;
        [SerializeField]
        private Camera[] m_camerasForViewClipTest;
        // public properties
        public TextureMultiSample multiSampling
        {
            get { return m_multiSampling; }
            set {
                if (m_multiSampling != value) {
                    m_multiSampling = value;
                    SetTexturePropertyDirty();
                }
            }
        }
        public TextureSuperSample superSampling
        {
            get { return m_superSampling; }
            set {
                if (m_superSampling != value) {
                    bool b = useIntermediateTexture;
                    m_superSampling = value;
                    if (b != useIntermediateTexture && m_multiSampling != TextureMultiSample.x1) {
                        SetTexturePropertyDirty();
                    }
                }
            }
        }
        public int textureWidth
        {
            get { return m_textureWidth; }
            set {
                if (m_textureWidth != value) {
                    m_textureWidth = value;
                    SetTexturePropertyDirty();
                }
            }
        }
        public int textureHeight
        {
            get { return m_textureHeight; }
            set {
                if (m_textureHeight != value) {
                    m_textureHeight = value;
                    SetTexturePropertyDirty();
                }
            }
        }
        public int mipLevel
        {
            get { return m_mipLevel; }
            set {
                if (m_mipLevel != value) {
                    if (m_mipLevel == 0 || value == 0) {
                        SetTexturePropertyDirty();
                    }
                    m_mipLevel = value;
                }
            }
        }
        public int blurLevel
        {
            get { return m_blurLevel; }
            set
            {
                if (m_blurLevel != value) {
                    bool b = useIntermediateTexture;
                    m_blurLevel = value;
                    if (b != useIntermediateTexture && m_multiSampling != TextureMultiSample.x1) {
                        SetTexturePropertyDirty();
                    }
                }
            }
        }
        public float blurSize
        {
            get { return m_blurSize; }
            set { m_blurSize = value; }
        }
        public BlurFilter blurFilter
        {
            get { return m_blurFilter; }
            set { m_blurFilter = value; }
        }
        public float mipmapBlurSize
        {
            get { return m_mipmapBlurSize; }
            set
            {
                m_mipmapBlurSize = value;
            }
        }
        public bool singlePassMipmapBlur {
            get { return m_singlePassMipmapBlur; }
            set { m_singlePassMipmapBlur = value; }
        }
        public MipmapFalloff mipmapFalloff
        {
            get { return m_mipmapFalloff; }
            set
            {
                m_mipmapFalloff = value;
            }
        }
        public float[] customMipmapFalloff
        {
            get { return m_customMipmapFalloff; }
            set
            {
                m_customMipmapFalloff = value;
            }
        }
        public Color shadowColor
        {
            get { return m_shadowColor; }
            set {
                if (m_shadowColor != value) {
                    bool b = useIntermediateTexture;
                    m_shadowColor = value;
                    if (b != useIntermediateTexture && m_multiSampling != TextureMultiSample.x1) {
                        SetTexturePropertyDirty();
                    }
                }
            }
        }
        public Material blurShader
        {
            get { return m_blurShader; }
            set
            {
                m_blurShader = value;
            }
        }
        public Material downsampleShader
        {
            get { return m_downsampleShader; }
            set { m_downsampleShader = value; }
        }
        public Material copyMipmapShader
        {
            get { return m_copyMipmapShader; }
            set
            {
                m_copyMipmapShader = value;
            }
        }
        public Material eraseShadowShader
        {
            get { return m_eraseShadowShader; }
            set { m_eraseShadowShader = value; }
        }
        public RenderTexture shadowTexture
        {
            get { return m_shadowTexture; }
        }
        public bool testViewClip
        {
            get { return m_testViewClip; }
            set { m_testViewClip = value; }
        }
        public Camera[] camerasForViewClipTest
        {
            get { return m_camerasForViewClipTest; }
            set { m_camerasForViewClipTest = value; }
        }
        public float cameraNearClipPlane
        {
            get {
                if (m_camera == null) {
                    Initialize();
                }
                return m_camera.nearClipPlane;
            }
            set {
                if (m_camera == null) {
                    Initialize();
                }
                m_camera.nearClipPlane = value;
            }
        }
        public LayerMask cameraCullingMask
        {
            get {
                if (m_camera == null) {
                    Initialize();
                }
                return m_camera.cullingMask;
            }
            set {
                if (m_camera == null) {
                    Initialize();
                }
                m_camera.cullingMask = value;
            }
        }
        public void SetReplacementShader(Shader shader, string replacementTag)
        {
            if (m_camera == null) {
                Initialize();
            }
            if (shader != null) {
                m_camera.SetReplacementShader(shader, replacementTag);
            }
            else {
                m_camera.ResetReplacementShader();
            }
        }
        // public properties
        public TextureMultiSample multiSampling
        {
            get { return m_multiSampling; }
            set
            {
                if (m_multiSampling != value)
                {
                    m_multiSampling = value;
                    SetTexturePropertyDirty();
                }
            }
        }
        public TextureSuperSample superSampling
        {
            get { return m_superSampling; }
            set
            {
                if (m_superSampling != value)
                {
                    bool b = useIntermediateTexture;
                    m_superSampling = value;
                    if (b != useIntermediateTexture && m_multiSampling != TextureMultiSample.x1)
                    {
                        SetTexturePropertyDirty();
                    }
                }
            }
        }
        public int textureWidth
        {
            get { return m_textureWidth; }
            set
            {
                if (m_textureWidth != value)
                {
                    m_textureWidth = value;
                    SetTexturePropertyDirty();
                }
            }
        }
        public int textureHeight
        {
            get { return m_textureHeight; }
            set
            {
                if (m_textureHeight != value)
                {
                    m_textureHeight = value;
                    SetTexturePropertyDirty();
                }
            }
        }
        public int mipLevel
        {
            get { return m_mipLevel; }
            set
            {
                if (m_mipLevel != value)
                {
                    if (m_mipLevel == 0 || value == 0)
                    {
                        SetTexturePropertyDirty();
                    }
                    m_mipLevel = value;
                }
            }
        }
        public int blurLevel
        {
            get { return m_blurLevel; }
            set
            {
                if (m_blurLevel != value)
                {
                    bool b = useIntermediateTexture;
                    m_blurLevel = value;
                    if (b != useIntermediateTexture && m_multiSampling != TextureMultiSample.x1)
                    {
                        SetTexturePropertyDirty();
                    }
                }
            }
        }
        public float blurSize
        {
            get { return m_blurSize; }
            set { m_blurSize = value; }
        }
        public BlurFilter blurFilter
        {
            get { return m_blurFilter; }
            set { m_blurFilter = value; }
        }
        public float mipmapBlurSize
        {
            get { return m_mipmapBlurSize; }
            set
            {
                m_mipmapBlurSize = value;
            }
        }
        public bool singlePassMipmapBlur
        {
            get { return m_singlePassMipmapBlur; }
            set { m_singlePassMipmapBlur = value; }
        }
        public MipmapFalloff mipmapFalloff
        {
            get { return m_mipmapFalloff; }
            set
            {
                m_mipmapFalloff = value;
            }
        }
        public float[] customMipmapFalloff
        {
            get { return m_customMipmapFalloff; }
            set
            {
                m_customMipmapFalloff = value;
            }
        }
        public Color shadowColor
        {
            get { return m_shadowColor; }
            set
            {
                if (m_shadowColor != value)
                {
                    bool b = useIntermediateTexture;
                    m_shadowColor = value;
                    if (b != useIntermediateTexture && m_multiSampling != TextureMultiSample.x1)
                    {
                        SetTexturePropertyDirty();
                    }
                }
            }
        }
        public Material blurShader
        {
            get { return m_blurShader; }
            set
            {
                m_blurShader = value;
            }
        }
        public Material downsampleShader
        {
            get { return m_downsampleShader; }
            set { m_downsampleShader = value; }
        }
        public Material copyMipmapShader
        {
            get { return m_copyMipmapShader; }
            set
            {
                m_copyMipmapShader = value;
            }
        }
        public Material eraseShadowShader
        {
            get { return m_eraseShadowShader; }
            set { m_eraseShadowShader = value; }
        }
        public RenderTexture shadowTexture
        {
            get { return m_shadowTexture; }
        }
        public bool testViewClip
        {
            get { return m_testViewClip; }
            set { m_testViewClip = value; }
        }
        public Camera[] camerasForViewClipTest
        {
            get { return m_camerasForViewClipTest; }
            set { m_camerasForViewClipTest = value; }
        }
        public float cameraNearClipPlane
        {
            get
            {
                if (m_camera == null)
                {
                    Initialize();
                }
                return m_camera.nearClipPlane;
            }
            set
            {
                if (m_camera == null)
                {
                    Initialize();
                }
                m_camera.nearClipPlane = value;
            }
        }
        public LayerMask cameraCullingMask
        {
            get
            {
                if (m_camera == null)
                {
                    Initialize();
                }
                return m_camera.cullingMask;
            }
            set
            {
                if (m_camera == null)
                {
                    Initialize();
                }
                m_camera.cullingMask = value;
            }
        }
        public void SetReplacementShader(Shader shader, string replacementTag)
        {
            if (m_camera == null)
            {
                Initialize();
            }
            if (shader != null)
            {
                m_camera.SetReplacementShader(shader, replacementTag);
            }
            else
            {
                m_camera.ResetReplacementShader();
            }
        }
        private static int s_falloffParamID;
        private static int s_blurOffsetHParamID;
        private static int s_blurOffsetVParamID;
        private static int s_blurWeightHParamID;
        private static int s_blurWeightVParamID;
        private static int s_downSampleBlurOffset0ParamID;
        private static int s_downSampleBlurOffset1ParamID;
        private static int s_downSampleBlurOffset2ParamID;
        private static int s_downSampleBlurOffset3ParamID;
        private static int s_downSampleBlurWeightParamID;
        private Projector m_projector;
        private Material m_projectorMaterial;
        private CommandBuffer m_commandBuffer;
        private RenderTexture m_shadowTexture;
        [SerializeField][HideInInspector]
        private Camera m_camera;
        private bool m_isTexturePropertyChanged;
        private bool m_isVisible = false;
        private bool m_shadowTextureValid = false;
        private static int s_falloffParamID;
        private static int s_blurOffsetHParamID;
        private static int s_blurOffsetVParamID;
        private static int s_blurWeightHParamID;
        private static int s_blurWeightVParamID;
        private static int s_downSampleBlurOffset0ParamID;
        private static int s_downSampleBlurOffset1ParamID;
        private static int s_downSampleBlurOffset2ParamID;
        private static int s_downSampleBlurOffset3ParamID;
        private static int s_downSampleBlurWeightParamID;
        private Projector m_projector;
        private Material m_projectorMaterial;
        private CommandBuffer m_commandBuffer;
        private RenderTexture m_shadowTexture;
        [SerializeField]
        [HideInInspector]
        private Camera m_camera;
        private bool m_isTexturePropertyChanged;
        private bool m_isVisible = false;
        private bool m_shadowTextureValid = false;
        public bool isProjectorVisible
        {
            get { return m_isVisible; }
        }
        public bool isProjectorVisible
        {
            get { return m_isVisible; }
        }
        // Call SetCommandBufferDirty or UpdateCommandBuffer when child objects are added/deleted/disabled/enabled.
        public void SetTexturePropertyDirty()
        {
            m_isTexturePropertyChanged = true;
        }
        public void CreateRenderTexture()
        {
            if (m_textureWidth <= 0 || m_textureHeight <= 0 || m_projector == null) {
                return;
            }
            // choose a texture format
            RenderTextureFormat textureFormat = RenderTextureFormat.ARGB32;
            if (m_preferredTextureFormats != null && 0 < m_preferredTextureFormats.Length) {
                foreach (RenderTextureFormat format in m_preferredTextureFormats) {
                    if (SystemInfo.SupportsRenderTextureFormat(textureFormat)) {
                        textureFormat = format;
                    }
                }
            }
            // create texture
            if (m_shadowTexture != null) {
                if (m_camera != null) {
                    m_camera.targetTexture = null;
                }
                DestroyImmediate(m_shadowTexture);
            }
            m_shadowTexture = new RenderTexture(m_textureWidth, m_textureHeight, 0, textureFormat, RenderTextureReadWrite.Linear);
            if (useIntermediateTexture) {
                m_shadowTexture.antiAliasing = 1;
            }
            else {
                m_shadowTexture.antiAliasing = (int)m_multiSampling;
            }
            if (0 < m_mipLevel) {
                m_shadowTexture.useMipMap = true;
        // Call SetCommandBufferDirty or UpdateCommandBuffer when child objects are added/deleted/disabled/enabled.
        public void SetTexturePropertyDirty()
        {
            m_isTexturePropertyChanged = true;
        }
        public void CreateRenderTexture()
        {
            if (m_textureWidth <= 0 || m_textureHeight <= 0 || m_projector == null)
            {
                return;
            }
            // choose a texture format
            RenderTextureFormat textureFormat = RenderTextureFormat.ARGB32;
            if (m_preferredTextureFormats != null && 0 < m_preferredTextureFormats.Length)
            {
                foreach (RenderTextureFormat format in m_preferredTextureFormats)
                {
                    if (SystemInfo.SupportsRenderTextureFormat(textureFormat))
                    {
                        textureFormat = format;
                    }
                }
            }
            // create texture
            if (m_shadowTexture != null)
            {
                if (m_camera != null)
                {
                    m_camera.targetTexture = null;
                }
                DestroyImmediate(m_shadowTexture);
            }
            m_shadowTexture = new RenderTexture(m_textureWidth, m_textureHeight, 0, textureFormat, RenderTextureReadWrite.Linear);
            if (useIntermediateTexture)
            {
                m_shadowTexture.antiAliasing = 1;
            }
            else
            {
                m_shadowTexture.antiAliasing = (int)m_multiSampling;
            }
            if (0 < m_mipLevel)
            {
                m_shadowTexture.useMipMap = true;
#if UNITY_5_5_OR_NEWER
                m_shadowTexture.autoGenerateMips = false;
                m_shadowTexture.autoGenerateMips = false;
#else
                m_shadowTexture.generateMips = false;
#endif
                m_shadowTexture.mipMapBias = 0.0f;
                m_shadowTexture.filterMode = FilterMode.Trilinear;
            }
            else {
                m_shadowTexture.useMipMap = false;
                m_shadowTexture.filterMode = FilterMode.Bilinear;
            }
            m_shadowTexture.wrapMode = TextureWrapMode.Clamp;
            m_shadowTexture.Create();
            m_shadowTextureValid = false;
            if (m_projector.material != null) {
                m_projector.material.SetTexture("_ShadowTex", m_shadowTexture);
                m_projector.material.SetFloat("_DSPMipLevel", m_mipLevel);
            }
            if (m_camera != null) {
                m_camera.targetTexture = m_shadowTexture;
            }
            m_isTexturePropertyChanged = false;
        }
        public void AddCommandBuffer(CommandBuffer commandBuffer)
        {
            m_camera.RemoveCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, commandBuffer); // just in case
            m_camera.AddCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, commandBuffer);
        }
                m_shadowTexture.mipMapBias = 0.0f;
                m_shadowTexture.filterMode = FilterMode.Trilinear;
            }
            else
            {
                m_shadowTexture.useMipMap = false;
                m_shadowTexture.filterMode = FilterMode.Bilinear;
            }
            m_shadowTexture.wrapMode = TextureWrapMode.Clamp;
            m_shadowTexture.Create();
            m_shadowTextureValid = false;
            if (m_projector.material != null)
            {
                m_projector.material.SetTexture("_ShadowTex", m_shadowTexture);
                m_projector.material.SetFloat("_DSPMipLevel", m_mipLevel);
            }
            if (m_camera != null)
            {
                m_camera.targetTexture = m_shadowTexture;
            }
            m_isTexturePropertyChanged = false;
        }
        public void AddCommandBuffer(CommandBuffer commandBuffer)
        {
            m_camera.RemoveCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, commandBuffer); // just in case
            m_camera.AddCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, commandBuffer);
        }
        public void RemoveCommandBuffer(CommandBuffer commandBuffer)
        {
            m_camera.RemoveCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, commandBuffer);
        }
        public void RemoveCommandBuffer(CommandBuffer commandBuffer)
        {
            m_camera.RemoveCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, commandBuffer);
        }
        static void InitializeShaderPropertyIDs()
        {
            s_falloffParamID = Shader.PropertyToID("_Falloff");
            s_blurOffsetHParamID = Shader.PropertyToID("_OffsetH");
            s_blurOffsetVParamID = Shader.PropertyToID("_OffsetV");
            s_blurWeightHParamID = Shader.PropertyToID("_WeightH");
            s_blurWeightVParamID = Shader.PropertyToID("_WeightV");
            s_downSampleBlurOffset0ParamID = Shader.PropertyToID("_Offset0");
            s_downSampleBlurOffset1ParamID = Shader.PropertyToID("_Offset1");
            s_downSampleBlurOffset2ParamID = Shader.PropertyToID("_Offset2");
            s_downSampleBlurOffset3ParamID = Shader.PropertyToID("_Offset3");
            s_downSampleBlurWeightParamID = Shader.PropertyToID("_Weight");
        }
        static void InitializeShaderPropertyIDs()
        {
            s_falloffParamID = Shader.PropertyToID("_Falloff");
            s_blurOffsetHParamID = Shader.PropertyToID("_OffsetH");
            s_blurOffsetVParamID = Shader.PropertyToID("_OffsetV");
            s_blurWeightHParamID = Shader.PropertyToID("_WeightH");
            s_blurWeightVParamID = Shader.PropertyToID("_WeightV");
            s_downSampleBlurOffset0ParamID = Shader.PropertyToID("_Offset0");
            s_downSampleBlurOffset1ParamID = Shader.PropertyToID("_Offset1");
            s_downSampleBlurOffset2ParamID = Shader.PropertyToID("_Offset2");
            s_downSampleBlurOffset3ParamID = Shader.PropertyToID("_Offset3");
            s_downSampleBlurWeightParamID = Shader.PropertyToID("_Weight");
        }
        bool useIntermediateTexture
        {
            get {
                return m_superSampling != TextureSuperSample.x1 || 0 < m_blurLevel || HasShadowColor() || (0 < m_mipLevel && m_multiSampling != TextureMultiSample.x1);
            }
        }
        bool Initialize()
        {
            m_isVisible = false;
            if (IsInitialized()) {
                return true;
            }
            m_isTexturePropertyChanged = true;
            InitializeShaderPropertyIDs();
            m_projector = GetComponent<Projector>();
            CloneProjectorMaterialIfShared();
            if (m_camera == null) {
                m_camera = gameObject.GetComponent<Camera>();
                if (m_camera == null) {
                    m_camera = gameObject.AddComponent<Camera>();
                }
                m_camera.hideFlags = HideFlags.HideInInspector;
            }
            else {
                m_camera.RemoveAllCommandBuffers();
            }
            m_camera.depth = -100;
            m_camera.cullingMask = 0;
            m_camera.clearFlags = CameraClearFlags.Nothing;
            m_camera.backgroundColor = new Color(1,1,1,0);
            m_camera.useOcclusionCulling = false;
            m_camera.renderingPath = RenderingPath.Forward;
            m_camera.nearClipPlane = 0.01f;
        bool useIntermediateTexture
        {
            get
            {
                return m_superSampling != TextureSuperSample.x1 || 0 < m_blurLevel || HasShadowColor() || (0 < m_mipLevel && m_multiSampling != TextureMultiSample.x1);
            }
        }
        bool Initialize()
        {
            m_isVisible = false;
            if (IsInitialized())
            {
                return true;
            }
            m_isTexturePropertyChanged = true;
            InitializeShaderPropertyIDs();
            m_projector = GetComponent<Projector>();
            CloneProjectorMaterialIfShared();
            if (m_camera == null)
            {
                m_camera = gameObject.GetComponent<Camera>();
                if (m_camera == null)
                {
                    m_camera = gameObject.AddComponent<Camera>();
                }
                m_camera.hideFlags = HideFlags.HideInInspector;
            }
            else
            {
                m_camera.RemoveAllCommandBuffers();
            }
            m_camera.depth = -100;
            m_camera.cullingMask = 0;
            m_camera.clearFlags = CameraClearFlags.Nothing;
            m_camera.backgroundColor = new Color(1, 1, 1, 0);
            m_camera.useOcclusionCulling = false;
            m_camera.renderingPath = RenderingPath.Forward;
            m_camera.nearClipPlane = 0.01f;
#if UNITY_5_6_OR_NEWER
            m_camera.forceIntoRenderTexture = true;
            m_camera.forceIntoRenderTexture = true;
#endif
            m_camera.enabled = true;
            CreateRenderTexture();
            return true;
        }
            m_camera.enabled = true;
            CreateRenderTexture();
            return true;
        }
        bool IsInitialized()
        {
            return m_projector != null && m_camera != null;
        }
        bool IsInitialized()
        {
            return m_projector != null && m_camera != null;
        }
        void Awake()
        {
            Initialize();
        }
        void Awake()
        {
            Initialize();
        }
        void OnEnable()
        {
            if (m_camera != null) {
                m_camera.enabled = true;
            }
        }
        void OnEnable()
        {
            if (m_camera != null)
            {
                m_camera.enabled = true;
            }
        }
        void OnDisable()
        {
            if (m_camera != null) {
                m_camera.enabled = false;
            }
        }
        void OnDisable()
        {
            if (m_camera != null)
            {
                m_camera.enabled = false;
            }
        }
        void Start()
        {
        void Start()
        {
#if UNITY_EDITOR
            if (m_testViewClip && Application.isPlaying)
            if (m_testViewClip && Application.isPlaying)
#else
            if (m_testViewClip)
#endif
            {
                if (m_camerasForViewClipTest == null || m_camerasForViewClipTest.Length == 0) {
                    if (Camera.main != null) {
                        m_camerasForViewClipTest = new Camera[1] {Camera.main};
                    }
                }
            }
        }
            {
                if (m_camerasForViewClipTest == null || m_camerasForViewClipTest.Length == 0)
                {
                    if (Camera.main != null)
                    {
                        m_camerasForViewClipTest = new Camera[1] { Camera.main };
                    }
                }
            }
        }
        void OnValidate()
        {
            CreateRenderTexture();
            InitializeShaderPropertyIDs();
            // check custom mipmap falloff
            if (m_mipmapFalloff == MipmapFalloff.Custom && 0 < m_mipLevel) {
                if (m_customMipmapFalloff == null || m_customMipmapFalloff.Length == 0) {
                    m_customMipmapFalloff = new float[m_mipLevel];
                    for (int i = 0; i < m_mipLevel; ++i) {
                        m_customMipmapFalloff[i] = ((float)(m_mipLevel - i))/(float)(m_mipLevel + 1);
                    }
                }
                else if (m_mipLevel != m_customMipmapFalloff.Length) {
                    float[] customFalloff = new float[m_mipLevel];
                    for (int i = 0; i < m_mipLevel; ++i) {
                        float oldIndex = ((float)(m_customMipmapFalloff.Length + 1)*(i + 1))/(float)(m_mipLevel + 1);
                        int j = Mathf.FloorToInt(oldIndex);
                        float w = oldIndex - j;
                        float v0 = (j == 0 ? 1.0f : m_customMipmapFalloff[j - 1]);
                        float v1 = (j < m_customMipmapFalloff.Length) ? m_customMipmapFalloff[j] : 0.0f;
                        customFalloff[i] = Mathf.Lerp(v0, v1, w);
                    }
                    m_customMipmapFalloff = customFalloff;
                }
            }
        }
        private static HashSet<Material> s_sharedMaterials;
        const HideFlags CLONED_MATERIAL_HIDE_FLAGS = HideFlags.HideAndDontSave;
        void CloneProjectorMaterialIfShared()
        {
        void OnValidate()
        {
            CreateRenderTexture();
            InitializeShaderPropertyIDs();
            // check custom mipmap falloff
            if (m_mipmapFalloff == MipmapFalloff.Custom && 0 < m_mipLevel)
            {
                if (m_customMipmapFalloff == null || m_customMipmapFalloff.Length == 0)
                {
                    m_customMipmapFalloff = new float[m_mipLevel];
                    for (int i = 0; i < m_mipLevel; ++i)
                    {
                        m_customMipmapFalloff[i] = ((float)(m_mipLevel - i)) / (float)(m_mipLevel + 1);
                    }
                }
                else if (m_mipLevel != m_customMipmapFalloff.Length)
                {
                    float[] customFalloff = new float[m_mipLevel];
                    for (int i = 0; i < m_mipLevel; ++i)
                    {
                        float oldIndex = ((float)(m_customMipmapFalloff.Length + 1) * (i + 1)) / (float)(m_mipLevel + 1);
                        int j = Mathf.FloorToInt(oldIndex);
                        float w = oldIndex - j;
                        float v0 = (j == 0 ? 1.0f : m_customMipmapFalloff[j - 1]);
                        float v1 = (j < m_customMipmapFalloff.Length) ? m_customMipmapFalloff[j] : 0.0f;
                        customFalloff[i] = Mathf.Lerp(v0, v1, w);
                    }
                    m_customMipmapFalloff = customFalloff;
                }
            }
        }
        private static HashSet<Material> s_sharedMaterials;
        const HideFlags CLONED_MATERIAL_HIDE_FLAGS = HideFlags.HideAndDontSave;
        void CloneProjectorMaterialIfShared()
        {
#if UNITY_EDITOR
            if (!Application.isPlaying) {
                return;
            }
            if (!Application.isPlaying)
            {
                return;
            }
#endif
            if (m_projector.material == null || (m_projector.material.hideFlags == CLONED_MATERIAL_HIDE_FLAGS && m_projector.material == m_projectorMaterial)) {
                return;
            }
            if (m_projectorMaterial != null && m_projectorMaterial.hideFlags == CLONED_MATERIAL_HIDE_FLAGS) {
                DestroyImmediate(m_projectorMaterial);
            }
            if (s_sharedMaterials == null) {
                s_sharedMaterials = new HashSet<Material>();
            }
            if (s_sharedMaterials.Contains(m_projector.material)) {
                m_projector.material = new Material(m_projector.material);
                m_projector.material.hideFlags = CLONED_MATERIAL_HIDE_FLAGS;
            }
            else {
                s_sharedMaterials.Add(m_projector.material);
            }
            m_projectorMaterial = m_projector.material;
        }
            if (m_projector.material == null || (m_projector.material.hideFlags == CLONED_MATERIAL_HIDE_FLAGS && m_projector.material == m_projectorMaterial))
            {
                return;
            }
            if (m_projectorMaterial != null && m_projectorMaterial.hideFlags == CLONED_MATERIAL_HIDE_FLAGS)
            {
                DestroyImmediate(m_projectorMaterial);
            }
            if (s_sharedMaterials == null)
            {
                s_sharedMaterials = new HashSet<Material>();
            }
            if (s_sharedMaterials.Contains(m_projector.material))
            {
                m_projector.material = new Material(m_projector.material);
                m_projector.material.hideFlags = CLONED_MATERIAL_HIDE_FLAGS;
            }
            else
            {
                s_sharedMaterials.Add(m_projector.material);
            }
            m_projectorMaterial = m_projector.material;
        }
        void OnDestroy()
        {
            if (m_projectorMaterial != null) {
                if (s_sharedMaterials != null && s_sharedMaterials.Contains(m_projectorMaterial)) {
                    s_sharedMaterials.Remove(m_projectorMaterial);
                }
                if (m_projectorMaterial.hideFlags == CLONED_MATERIAL_HIDE_FLAGS) {
                    if (m_projector.material == m_projectorMaterial) {
                        m_projector.material = null;
                    }
                    DestroyImmediate(m_projectorMaterial);
                }
            }
            if (m_shadowTexture != null) {
                if (m_camera != null) {
                    m_camera.targetTexture = null;
                }
                DestroyImmediate(m_shadowTexture);
                m_shadowTexture = null;
            }
            if (m_camera != null) {
                m_camera.RemoveAllCommandBuffers();
            }
            m_isVisible = false;
        }
        void OnDestroy()
        {
            if (m_projectorMaterial != null)
            {
                if (s_sharedMaterials != null && s_sharedMaterials.Contains(m_projectorMaterial))
                {
                    s_sharedMaterials.Remove(m_projectorMaterial);
                }
                if (m_projectorMaterial.hideFlags == CLONED_MATERIAL_HIDE_FLAGS)
                {
                    if (m_projector.material == m_projectorMaterial)
                    {
                        m_projector.material = null;
                    }
                    DestroyImmediate(m_projectorMaterial);
                }
            }
            if (m_shadowTexture != null)
            {
                if (m_camera != null)
                {
                    m_camera.targetTexture = null;
                }
                DestroyImmediate(m_shadowTexture);
                m_shadowTexture = null;
            }
            if (m_camera != null)
            {
                m_camera.RemoveAllCommandBuffers();
            }
            m_isVisible = false;
        }
        bool IsReadyToExecute()
        {
            if (m_textureWidth <= 0 || m_textureHeight <= 0 || m_eraseShadowShader == null) {
                return false;
            }
            if (0 < m_mipLevel || m_superSampling != TextureSuperSample.x1) {
                if (m_downsampleShader == null) {
                    return false;
                }
            }
            if (0 < m_blurLevel || (0.0f < m_mipmapBlurSize && 0 < m_mipLevel)) {
                if (m_blurShader == null) {
                    return false;
                }
            }
            if (0 < m_mipLevel && (m_copyMipmapShader == null || m_downsampleShader == null)) {
                return false;
            }
            return true;
        }
        bool IsReadyToExecute()
        {
            if (m_textureWidth <= 0 || m_textureHeight <= 0 || m_eraseShadowShader == null)
            {
                return false;
            }
            if (0 < m_mipLevel || m_superSampling != TextureSuperSample.x1)
            {
                if (m_downsampleShader == null)
                {
                    return false;
                }
            }
            if (0 < m_blurLevel || (0.0f < m_mipmapBlurSize && 0 < m_mipLevel))
            {
                if (m_blurShader == null)
                {
                    return false;
                }
            }
            if (0 < m_mipLevel && (m_copyMipmapShader == null || m_downsampleShader == null))
            {
                return false;
            }
            return true;
        }
        void SetVisible(bool isVisible)
        {
            m_isVisible = isVisible;
            SendMessage("OnVisibilityChanged", isVisible);
        }
        void SetVisible(bool isVisible)
        {
            m_isVisible = isVisible;
            SendMessage("OnVisibilityChanged", isVisible);
        }
#if UNITY_EDITOR
        private bool m_isRenderingFromUpdate = false;
        public void ForceRenderTexture()
        {
            m_isRenderingFromUpdate = true;
            // it is necessary to set camera parameters before Render, because render events will not be invoked if the volume of the view frustum is zero,
            // and there is no chance to fix the camera parameters in OnPreCull function.
            m_camera.orthographic = m_projector.orthographic;
            m_camera.orthographicSize = m_projector.orthographicSize;
            m_camera.fieldOfView = m_projector.fieldOfView;
            m_camera.aspect = m_projector.aspectRatio;
            m_camera.farClipPlane = m_projector.farClipPlane;
        private bool m_isRenderingFromUpdate = false;
        public void ForceRenderTexture()
        {
            m_isRenderingFromUpdate = true;
            // it is necessary to set camera parameters before Render, because render events will not be invoked if the volume of the view frustum is zero,
            // and there is no chance to fix the camera parameters in OnPreCull function.
            m_camera.orthographic = m_projector.orthographic;
            m_camera.orthographicSize = m_projector.orthographicSize;
            m_camera.fieldOfView = m_projector.fieldOfView;
            m_camera.aspect = m_projector.aspectRatio;
            m_camera.farClipPlane = m_projector.farClipPlane;
#if UNITY_5_6
            // workaround for Unity 5.6
            // Unity 5.6 has a bug whereby a temporary render texture does not work if m_camera.targetTexture != null. This bug is fixed in Unity 2017.
            m_camera.targetTexture = null;
            // workaround for Unity 5.6
            // Unity 5.6 has a bug whereby a temporary render texture does not work if m_camera.targetTexture != null. This bug is fixed in Unity 2017.
            m_camera.targetTexture = null;
#endif
            m_camera.Render();
            m_isRenderingFromUpdate = false;
        }
            m_camera.Render();
            m_isRenderingFromUpdate = false;
        }
#endif
        void Update()
        {
        void Update()
        {
#if UNITY_EDITOR
            if (!Application.isPlaying
                && (!m_shadowTextureValid
                    || m_camera.orthographic != m_projector.orthographic
                    || m_camera.orthographicSize != m_projector.orthographicSize
                    || m_camera.fieldOfView != m_projector.fieldOfView
                    || m_camera.aspect != m_projector.aspectRatio
                    || m_camera.farClipPlane != m_projector.farClipPlane)
            ) {
                ForceRenderTexture();
            }
            if (!Application.isPlaying
                && (!m_shadowTextureValid
                    || m_camera.orthographic != m_projector.orthographic
                    || m_camera.orthographicSize != m_projector.orthographicSize
                    || m_camera.fieldOfView != m_projector.fieldOfView
                    || m_camera.aspect != m_projector.aspectRatio
                    || m_camera.farClipPlane != m_projector.farClipPlane)
            )
            {
                ForceRenderTexture();
            }
#endif
            if (m_camera != null && !m_camera.enabled) {
                m_camera.enabled = true;
            }
        }
            if (m_camera != null && !m_camera.enabled)
            {
                m_camera.enabled = true;
            }
        }
        void OnPreCull()
        {
            if (m_projector.material != m_projectorMaterial) {
                // projector material changed.
                CloneProjectorMaterialIfShared();
                m_projector.material.SetTexture("_ShadowTex", m_shadowTexture);
                m_projector.material.SetFloat("_DSPMipLevel", m_mipLevel);
            }
        void OnPreCull()
        {
            if (m_projector.material != m_projectorMaterial)
            {
                // projector material changed.
                CloneProjectorMaterialIfShared();
                m_projector.material.SetTexture("_ShadowTex", m_shadowTexture);
                m_projector.material.SetFloat("_DSPMipLevel", m_mipLevel);
            }
#if UNITY_EDITOR
            if (!(Application.isPlaying || m_isRenderingFromUpdate)) {
                m_camera.enabled = false;
                return;
            }
            if (!IsReadyToExecute()) {
                m_camera.enabled = false;
                return;
            }
            if (!IsInitialized() && !Initialize()) {
                m_camera.enabled = false;
                return;
            }
            if (m_projector.material == null) {
                if (m_isVisible) {
                    SetVisible(false);
                }
                m_camera.enabled = false;
                return;
            }
            m_projector.material.SetTexture("_ShadowTex", m_shadowTexture);
            m_projector.material.SetFloat("_DSPMipLevel", m_mipLevel);
            if (!(Application.isPlaying || m_isRenderingFromUpdate))
            {
                m_camera.enabled = false;
                return;
            }
            if (!IsReadyToExecute())
            {
                m_camera.enabled = false;
                return;
            }
            if (!IsInitialized() && !Initialize())
            {
                m_camera.enabled = false;
                return;
            }
            if (m_projector.material == null)
            {
                if (m_isVisible)
                {
                    SetVisible(false);
                }
                m_camera.enabled = false;
                return;
            }
            m_projector.material.SetTexture("_ShadowTex", m_shadowTexture);
            m_projector.material.SetFloat("_DSPMipLevel", m_mipLevel);
#endif
            if (m_isTexturePropertyChanged) {
                CreateRenderTexture();
            }
            m_camera.orthographic = m_projector.orthographic;
            m_camera.orthographicSize = m_projector.orthographicSize;
            m_camera.fieldOfView = m_projector.fieldOfView;
            m_camera.aspect = m_projector.aspectRatio;
            m_camera.farClipPlane = m_projector.farClipPlane;
            // view clip test
            bool isVisible = true;
            if (!m_projector.enabled) {
                isVisible = false;
            }
            if (m_isTexturePropertyChanged)
            {
                CreateRenderTexture();
            }
            m_camera.orthographic = m_projector.orthographic;
            m_camera.orthographicSize = m_projector.orthographicSize;
            m_camera.fieldOfView = m_projector.fieldOfView;
            m_camera.aspect = m_projector.aspectRatio;
            m_camera.farClipPlane = m_projector.farClipPlane;
            // view clip test
            bool isVisible = true;
            if (!m_projector.enabled)
            {
                isVisible = false;
            }
#if UNITY_EDITOR
            else if (m_testViewClip && Application.isPlaying)
            else if (m_testViewClip && Application.isPlaying)
#else
            else if (m_testViewClip)
#endif
            {
                if (m_camerasForViewClipTest == null || m_camerasForViewClipTest.Length == 0) {
                    if (Camera.main != null) {
                        m_camerasForViewClipTest = new Camera[1] {Camera.main};
                    }
                }
                if (m_camerasForViewClipTest != null && 0 < m_camerasForViewClipTest.Length) {
                    Vector3 v0 = m_camera.ViewportToWorldPoint(new Vector3(0,0,m_camera.nearClipPlane));
                    Vector3 v1 = m_camera.ViewportToWorldPoint(new Vector3(1,0,m_camera.nearClipPlane));
                    Vector3 v2 = m_camera.ViewportToWorldPoint(new Vector3(0,1,m_camera.nearClipPlane));
                    Vector3 v3 = m_camera.ViewportToWorldPoint(new Vector3(1,1,m_camera.nearClipPlane));
                    Vector3 v4 = m_camera.ViewportToWorldPoint(new Vector3(0,0,m_camera.farClipPlane));
                    Vector3 v5 = m_camera.ViewportToWorldPoint(new Vector3(1,0,m_camera.farClipPlane));
                    Vector3 v6 = m_camera.ViewportToWorldPoint(new Vector3(0,1,m_camera.farClipPlane));
                    Vector3 v7 = m_camera.ViewportToWorldPoint(new Vector3(1,1,m_camera.farClipPlane));
                    isVisible = false;
                    for (int i = 0; i < m_camerasForViewClipTest.Length; ++i) {
                        Camera cam = m_camerasForViewClipTest[i];
                        Vector3 min = cam.WorldToViewportPoint(v0);
                        if (min.z < 0.0f) { min.x = -min.x; min.y = -min.y; }
                        Vector3 max = min;
                        Vector3 v = cam.WorldToViewportPoint(v1);
                        if (v.z < 0.0f) { v.x = -v.x; v.y = -v.y; }
                        min.x = Mathf.Min(min.x, v.x); min.y = Mathf.Min(min.y, v.y); min.z = Mathf.Min(min.z, v.z);
                        max.x = Mathf.Max(max.x, v.x); max.y = Mathf.Max(max.y, v.y); max.z = Mathf.Max(max.z, v.z);
                        v = cam.WorldToViewportPoint(v2);
                        if (v.z < 0.0f) { v.x = -v.x; v.y = -v.y; }
                        min.x = Mathf.Min(min.x, v.x); min.y = Mathf.Min(min.y, v.y); min.z = Mathf.Min(min.z, v.z);
                        max.x = Mathf.Max(max.x, v.x); max.y = Mathf.Max(max.y, v.y); max.z = Mathf.Max(max.z, v.z);
                        v = cam.WorldToViewportPoint(v3);
                        if (v.z < 0.0f) { v.x = -v.x; v.y = -v.y; }
                        min.x = Mathf.Min(min.x, v.x); min.y = Mathf.Min(min.y, v.y); min.z = Mathf.Min(min.z, v.z);
                        max.x = Mathf.Max(max.x, v.x); max.y = Mathf.Max(max.y, v.y); max.z = Mathf.Max(max.z, v.z);
                        v = cam.WorldToViewportPoint(v4);
                        if (v.z < 0.0f) { v.x = -v.x; v.y = -v.y; }
                        min.x = Mathf.Min(min.x, v.x); min.y = Mathf.Min(min.y, v.y); min.z = Mathf.Min(min.z, v.z);
                        max.x = Mathf.Max(max.x, v.x); max.y = Mathf.Max(max.y, v.y); max.z = Mathf.Max(max.z, v.z);
                        v = cam.WorldToViewportPoint(v5);
                        if (v.z < 0.0f) { v.x = -v.x; v.y = -v.y; }
                        min.x = Mathf.Min(min.x, v.x); min.y = Mathf.Min(min.y, v.y); min.z = Mathf.Min(min.z, v.z);
                        max.x = Mathf.Max(max.x, v.x); max.y = Mathf.Max(max.y, v.y); max.z = Mathf.Max(max.z, v.z);
                        v = cam.WorldToViewportPoint(v6);
                        if (v.z < 0.0f) { v.x = -v.x; v.y = -v.y; }
                        min.x = Mathf.Min(min.x, v.x); min.y = Mathf.Min(min.y, v.y); min.z = Mathf.Min(min.z, v.z);
                        max.x = Mathf.Max(max.x, v.x); max.y = Mathf.Max(max.y, v.y); max.z = Mathf.Max(max.z, v.z);
                        v = cam.WorldToViewportPoint(v7);
                        if (v.z < 0.0f) { v.x = -v.x; v.y = -v.y; }
                        min.x = Mathf.Min(min.x, v.x); min.y = Mathf.Min(min.y, v.y); min.z = Mathf.Min(min.z, v.z);
                        max.x = Mathf.Max(max.x, v.x); max.y = Mathf.Max(max.y, v.y); max.z = Mathf.Max(max.z, v.z);
                        if (0.0f < max.x && min.x < 1.0f && 0.0f < max.y && min.y < 1.0f && cam.nearClipPlane < max.z && min.z < cam.farClipPlane) {
                            isVisible = true;
                            break;
                        }
                    }
                }
            }
            if (isVisible != m_isVisible) {
                SetVisible(isVisible);
            }
            if (!isVisible) {
                if (m_camera != null) {
                    m_camera.enabled = false;
                }
                if (m_shadowTexture != null && !m_shadowTextureValid) {
                    RenderTexture currentRT = RenderTexture.active;
                    RenderTexture.active = m_shadowTexture;
                    GL.Clear(false, true, new Color(1,1,1,0));
                    m_shadowTextureValid = true;
                    RenderTexture.active = currentRT;
                }
            }
        }
            {
                if (m_camerasForViewClipTest == null || m_camerasForViewClipTest.Length == 0)
                {
                    if (Camera.main != null)
                    {
                        m_camerasForViewClipTest = new Camera[1] { Camera.main };
                    }
                }
                if (m_camerasForViewClipTest != null && 0 < m_camerasForViewClipTest.Length)
                {
                    Vector3 v0 = m_camera.ViewportToWorldPoint(new Vector3(0, 0, m_camera.nearClipPlane));
                    Vector3 v1 = m_camera.ViewportToWorldPoint(new Vector3(1, 0, m_camera.nearClipPlane));
                    Vector3 v2 = m_camera.ViewportToWorldPoint(new Vector3(0, 1, m_camera.nearClipPlane));
                    Vector3 v3 = m_camera.ViewportToWorldPoint(new Vector3(1, 1, m_camera.nearClipPlane));
                    Vector3 v4 = m_camera.ViewportToWorldPoint(new Vector3(0, 0, m_camera.farClipPlane));
                    Vector3 v5 = m_camera.ViewportToWorldPoint(new Vector3(1, 0, m_camera.farClipPlane));
                    Vector3 v6 = m_camera.ViewportToWorldPoint(new Vector3(0, 1, m_camera.farClipPlane));
                    Vector3 v7 = m_camera.ViewportToWorldPoint(new Vector3(1, 1, m_camera.farClipPlane));
                    isVisible = false;
                    for (int i = 0; i < m_camerasForViewClipTest.Length; ++i)
                    {
                        Camera cam = m_camerasForViewClipTest[i];
                        Vector3 min = cam.WorldToViewportPoint(v0);
                        if (min.z < 0.0f) { min.x = -min.x; min.y = -min.y; }
                        Vector3 max = min;
                        Vector3 v = cam.WorldToViewportPoint(v1);
                        if (v.z < 0.0f) { v.x = -v.x; v.y = -v.y; }
                        min.x = Mathf.Min(min.x, v.x); min.y = Mathf.Min(min.y, v.y); min.z = Mathf.Min(min.z, v.z);
                        max.x = Mathf.Max(max.x, v.x); max.y = Mathf.Max(max.y, v.y); max.z = Mathf.Max(max.z, v.z);
                        v = cam.WorldToViewportPoint(v2);
                        if (v.z < 0.0f) { v.x = -v.x; v.y = -v.y; }
                        min.x = Mathf.Min(min.x, v.x); min.y = Mathf.Min(min.y, v.y); min.z = Mathf.Min(min.z, v.z);
                        max.x = Mathf.Max(max.x, v.x); max.y = Mathf.Max(max.y, v.y); max.z = Mathf.Max(max.z, v.z);
                        v = cam.WorldToViewportPoint(v3);
                        if (v.z < 0.0f) { v.x = -v.x; v.y = -v.y; }
                        min.x = Mathf.Min(min.x, v.x); min.y = Mathf.Min(min.y, v.y); min.z = Mathf.Min(min.z, v.z);
                        max.x = Mathf.Max(max.x, v.x); max.y = Mathf.Max(max.y, v.y); max.z = Mathf.Max(max.z, v.z);
                        v = cam.WorldToViewportPoint(v4);
                        if (v.z < 0.0f) { v.x = -v.x; v.y = -v.y; }
                        min.x = Mathf.Min(min.x, v.x); min.y = Mathf.Min(min.y, v.y); min.z = Mathf.Min(min.z, v.z);
                        max.x = Mathf.Max(max.x, v.x); max.y = Mathf.Max(max.y, v.y); max.z = Mathf.Max(max.z, v.z);
                        v = cam.WorldToViewportPoint(v5);
                        if (v.z < 0.0f) { v.x = -v.x; v.y = -v.y; }
                        min.x = Mathf.Min(min.x, v.x); min.y = Mathf.Min(min.y, v.y); min.z = Mathf.Min(min.z, v.z);
                        max.x = Mathf.Max(max.x, v.x); max.y = Mathf.Max(max.y, v.y); max.z = Mathf.Max(max.z, v.z);
                        v = cam.WorldToViewportPoint(v6);
                        if (v.z < 0.0f) { v.x = -v.x; v.y = -v.y; }
                        min.x = Mathf.Min(min.x, v.x); min.y = Mathf.Min(min.y, v.y); min.z = Mathf.Min(min.z, v.z);
                        max.x = Mathf.Max(max.x, v.x); max.y = Mathf.Max(max.y, v.y); max.z = Mathf.Max(max.z, v.z);
                        v = cam.WorldToViewportPoint(v7);
                        if (v.z < 0.0f) { v.x = -v.x; v.y = -v.y; }
                        min.x = Mathf.Min(min.x, v.x); min.y = Mathf.Min(min.y, v.y); min.z = Mathf.Min(min.z, v.z);
                        max.x = Mathf.Max(max.x, v.x); max.y = Mathf.Max(max.y, v.y); max.z = Mathf.Max(max.z, v.z);
                        if (0.0f < max.x && min.x < 1.0f && 0.0f < max.y && min.y < 1.0f && cam.nearClipPlane < max.z && min.z < cam.farClipPlane)
                        {
                            isVisible = true;
                            break;
                        }
                    }
                }
            }
            if (isVisible != m_isVisible)
            {
                SetVisible(isVisible);
            }
            if (!isVisible)
            {
                if (m_camera != null)
                {
                    m_camera.enabled = false;
                }
                if (m_shadowTexture != null && !m_shadowTextureValid)
                {
                    RenderTexture currentRT = RenderTexture.active;
                    RenderTexture.active = m_shadowTexture;
                    GL.Clear(false, true, new Color(1, 1, 1, 0));
                    m_shadowTextureValid = true;
                    RenderTexture.active = currentRT;
                }
            }
        }
        bool HasShadowColor()
        {
            return m_shadowColor.a != 1 || (m_shadowColor.r + shadowColor.g + shadowColor.b) != 0;
        }
        bool HasShadowColor()
        {
            return m_shadowColor.a != 1 || (m_shadowColor.r + shadowColor.g + shadowColor.b) != 0;
        }
        void OnPreRender()
        {
        void OnPreRender()
        {
#if UNITY_EDITOR
            if (!(Application.isPlaying || m_isRenderingFromUpdate)) {
                return;
            }
            if (!(Application.isPlaying || m_isRenderingFromUpdate))
            {
                return;
            }
#endif
            if (!m_isVisible) {
                return;
            }
            m_shadowTexture.DiscardContents();
            if (useIntermediateTexture) {
                int width = m_textureWidth * (int)m_superSampling;
                int height = m_textureHeight * (int)m_superSampling;
                m_camera.targetTexture = RenderTexture.GetTemporary(width, height, 0, m_shadowTexture.format, RenderTextureReadWrite.Linear, (int)m_multiSampling);
                m_camera.targetTexture.filterMode = FilterMode.Bilinear;
            }
            else {
                m_camera.targetTexture = m_shadowTexture;
            }
            m_camera.clearFlags = CameraClearFlags.SolidColor;
        }
        private const int MAX_BLUR_TAP_SIZE = 7;
        private static float[] s_blurWeights = new float[MAX_BLUR_TAP_SIZE];
        struct BlurParam {
            public int tap;
            public Vector4 offset;
            public Vector4 weight;
        };
        static BlurParam GetBlurParam(float blurSize, BlurFilter filter)
        {
            BlurParam param = new BlurParam();
            if (!m_isVisible)
            {
                return;
            }
            m_shadowTexture.DiscardContents();
            if (useIntermediateTexture)
            {
                int width = m_textureWidth * (int)m_superSampling;
                int height = m_textureHeight * (int)m_superSampling;
                m_camera.targetTexture = RenderTexture.GetTemporary(width, height, 0, m_shadowTexture.format, RenderTextureReadWrite.Linear, (int)m_multiSampling);
                m_camera.targetTexture.filterMode = FilterMode.Bilinear;
            }
            else
            {
                m_camera.targetTexture = m_shadowTexture;
            }
            m_camera.clearFlags = CameraClearFlags.SolidColor;
        }
        private const int MAX_BLUR_TAP_SIZE = 7;
        private static float[] s_blurWeights = new float[MAX_BLUR_TAP_SIZE];
        struct BlurParam
        {
            public int tap;
            public Vector4 offset;
            public Vector4 weight;
        };
        static BlurParam GetBlurParam(float blurSize, BlurFilter filter)
        {
            BlurParam param = new BlurParam();
            if (blurSize < 0.1f) {
                param.tap = 3;
                param.offset.x = 0.0f;
                param.offset.y = 0.0f;
                param.offset.z = 0.0f;
                param.offset.w = 0.0f;
                param.weight.x = 1.0f;
                param.weight.y = 0.0f;
                param.weight.z = 0.0f;
                param.weight.w = 0.0f;
                return param;
            }
            // calculate weights
            if (filter == BlurFilter.Gaussian) {
                // gaussian filter
                float a = 1.0f/(2.0f*blurSize*blurSize);
                float totalWeight = 1.0f;
                s_blurWeights[0] = 1.0f;
                for (int i = 1; i < s_blurWeights.Length; ++i) {
                    s_blurWeights[i] = Mathf.Exp(-i*i*a);
                    totalWeight += 2.0f*s_blurWeights[i];
                }
                float w = 1.0f/totalWeight;
                for (int i = 0; i < s_blurWeights.Length; ++i) {
                    s_blurWeights[i] *= w;
                }
            }
            else {
                // uniform filter
                float a = 0.5f/(0.5f + blurSize);
                for (int i = 0; i < s_blurWeights.Length; ++i) {
                    if (i <= blurSize) {
                        s_blurWeights[i] = a;
                    }
                    else if (i - 1 < blurSize) {
                        s_blurWeights[i] = a * (blurSize - (i - 1));
                    }
                    else {
                        s_blurWeights[i] = 0.0f;
                    }
                }
            }
            param.offset.x = 1.0f + s_blurWeights[2]/(s_blurWeights[1] + s_blurWeights[2]);
            param.offset.y = 3.0f + s_blurWeights[4]/(s_blurWeights[3] + s_blurWeights[4]);
            param.offset.z = 5.0f + s_blurWeights[6]/(s_blurWeights[5] + s_blurWeights[6]);
            param.offset.w = 0.0f;
            if (blurSize < 0.1f)
            {
                param.tap = 3;
                param.offset.x = 0.0f;
                param.offset.y = 0.0f;
                param.offset.z = 0.0f;
                param.offset.w = 0.0f;
                param.weight.x = 1.0f;
                param.weight.y = 0.0f;
                param.weight.z = 0.0f;
                param.weight.w = 0.0f;
                return param;
            }
            // calculate weights
            if (filter == BlurFilter.Gaussian)
            {
                // gaussian filter
                float a = 1.0f / (2.0f * blurSize * blurSize);
                float totalWeight = 1.0f;
                s_blurWeights[0] = 1.0f;
                for (int i = 1; i < s_blurWeights.Length; ++i)
                {
                    s_blurWeights[i] = Mathf.Exp(-i * i * a);
                    totalWeight += 2.0f * s_blurWeights[i];
                }
                float w = 1.0f / totalWeight;
                for (int i = 0; i < s_blurWeights.Length; ++i)
                {
                    s_blurWeights[i] *= w;
                }
            }
            else
            {
                // uniform filter
                float a = 0.5f / (0.5f + blurSize);
                for (int i = 0; i < s_blurWeights.Length; ++i)
                {
                    if (i <= blurSize)
                    {
                        s_blurWeights[i] = a;
                    }
                    else if (i - 1 < blurSize)
                    {
                        s_blurWeights[i] = a * (blurSize - (i - 1));
                    }
                    else
                    {
                        s_blurWeights[i] = 0.0f;
                    }
                }
            }
            param.offset.x = 1.0f + s_blurWeights[2] / (s_blurWeights[1] + s_blurWeights[2]);
            param.offset.y = 3.0f + s_blurWeights[4] / (s_blurWeights[3] + s_blurWeights[4]);
            param.offset.z = 5.0f + s_blurWeights[6] / (s_blurWeights[5] + s_blurWeights[6]);
            param.offset.w = 0.0f;
            if (s_blurWeights[3] < 0.02f) {
                param.tap = 3;
                float a = 0.5f/(0.5f*s_blurWeights[0] + s_blurWeights[1] + s_blurWeights[2]);
                param.weight.x = Mathf.Round(255*a*s_blurWeights[0])/255.0f;
                param.weight.y = 0.5f - 0.5f*param.weight.x;
                param.weight.z = 0.0f;
                param.weight.w = 0.0f;
            }
            else if (s_blurWeights[5] < 0.02f) {
                param.tap = 5;
                float a = 0.5f/(0.5f*s_blurWeights[0] + s_blurWeights[1] + s_blurWeights[2] + s_blurWeights[3] + s_blurWeights[4]);
                param.weight.x = Mathf.Round(255*a*s_blurWeights[0])/255.0f;
                param.weight.y = Mathf.Round(255*a*(s_blurWeights[1] + s_blurWeights[2]))/255.0f;
                param.weight.z = 0.5f - (0.5f*param.weight.x + param.weight.y);
                param.weight.w = 0.0f;
            }
            else {
                param.tap = 7;
                param.weight.x = Mathf.Round(255*s_blurWeights[0])/255.0f;
                param.weight.y = Mathf.Round(255*(s_blurWeights[1] + s_blurWeights[2]))/255.0f;
                param.weight.z = Mathf.Round(255*(s_blurWeights[3] + s_blurWeights[4]))/255.0f;
                param.weight.w = 0.5f - (0.5f*param.weight.x + param.weight.y + param.weight.z);
            }
            return param;
        }
        static BlurParam GetDownsampleBlurParam(float blurSize, BlurFilter filter)
        {
            BlurParam param = new BlurParam();
            param.tap = 4;
            if (blurSize < 0.1f) {
                param.offset.x = 0.0f;
                param.offset.y = 0.0f;
                param.offset.z = 0.0f;
                param.offset.w = 0.0f;
                param.weight.x = 1.0f;
                param.weight.y = 0.0f;
                param.weight.z = 0.0f;
                param.weight.w = 0.0f;
                return param;
            }
            // calculate weights
            if (filter == BlurFilter.Gaussian) {
                // gaussian filter
                float a = 1.0f/(2.0f*blurSize*blurSize);
                float totalWeight = 0.0f;
                for (int i = 0; i < param.tap; ++i) {
                    float x = i + 0.5f;
                    s_blurWeights[i] = Mathf.Exp(-x*x*a);
                    totalWeight += 2.0f*s_blurWeights[i];
                }
                float w = 1.0f/totalWeight;
                for (int i = 0; i < param.tap; ++i) {
                    s_blurWeights[i] *= w;
                }
            }
            else {
                // uniform filter
                float a = 0.5f/blurSize;
                for (int i = 0; i < param.tap; ++i) {
                    if (i + 1 <= blurSize) {
                        s_blurWeights[i] = a;
                    }
                    else if (i < blurSize) {
                        s_blurWeights[i] = a * (blurSize - i);
                    }
                    else {
                        s_blurWeights[i] = 0.0f;
                    }
                }
            }
            param.offset.x = 0.5f + s_blurWeights[1]/(s_blurWeights[0] + s_blurWeights[1]);
            param.offset.y = 2.5f + s_blurWeights[3]/(s_blurWeights[2] + s_blurWeights[3]);
            param.offset.z = 0.0f;
            param.offset.w = 0.0f;
            param.weight.x = s_blurWeights[0] + s_blurWeights[1];
            param.weight.y = s_blurWeights[2] + s_blurWeights[3];
            param.weight.z = 0.0f;
            param.weight.w = 0.0f;
            if (s_blurWeights[3] < 0.02f)
            {
                param.tap = 3;
                float a = 0.5f / (0.5f * s_blurWeights[0] + s_blurWeights[1] + s_blurWeights[2]);
                param.weight.x = Mathf.Round(255 * a * s_blurWeights[0]) / 255.0f;
                param.weight.y = 0.5f - 0.5f * param.weight.x;
                param.weight.z = 0.0f;
                param.weight.w = 0.0f;
            }
            else if (s_blurWeights[5] < 0.02f)
            {
                param.tap = 5;
                float a = 0.5f / (0.5f * s_blurWeights[0] + s_blurWeights[1] + s_blurWeights[2] + s_blurWeights[3] + s_blurWeights[4]);
                param.weight.x = Mathf.Round(255 * a * s_blurWeights[0]) / 255.0f;
                param.weight.y = Mathf.Round(255 * a * (s_blurWeights[1] + s_blurWeights[2])) / 255.0f;
                param.weight.z = 0.5f - (0.5f * param.weight.x + param.weight.y);
                param.weight.w = 0.0f;
            }
            else
            {
                param.tap = 7;
                param.weight.x = Mathf.Round(255 * s_blurWeights[0]) / 255.0f;
                param.weight.y = Mathf.Round(255 * (s_blurWeights[1] + s_blurWeights[2])) / 255.0f;
                param.weight.z = Mathf.Round(255 * (s_blurWeights[3] + s_blurWeights[4])) / 255.0f;
                param.weight.w = 0.5f - (0.5f * param.weight.x + param.weight.y + param.weight.z);
            }
            return param;
        }
        static BlurParam GetDownsampleBlurParam(float blurSize, BlurFilter filter)
        {
            BlurParam param = new BlurParam();
            param.tap = 4;
            if (blurSize < 0.1f)
            {
                param.offset.x = 0.0f;
                param.offset.y = 0.0f;
                param.offset.z = 0.0f;
                param.offset.w = 0.0f;
                param.weight.x = 1.0f;
                param.weight.y = 0.0f;
                param.weight.z = 0.0f;
                param.weight.w = 0.0f;
                return param;
            }
            // calculate weights
            if (filter == BlurFilter.Gaussian)
            {
                // gaussian filter
                float a = 1.0f / (2.0f * blurSize * blurSize);
                float totalWeight = 0.0f;
                for (int i = 0; i < param.tap; ++i)
                {
                    float x = i + 0.5f;
                    s_blurWeights[i] = Mathf.Exp(-x * x * a);
                    totalWeight += 2.0f * s_blurWeights[i];
                }
                float w = 1.0f / totalWeight;
                for (int i = 0; i < param.tap; ++i)
                {
                    s_blurWeights[i] *= w;
                }
            }
            else
            {
                // uniform filter
                float a = 0.5f / blurSize;
                for (int i = 0; i < param.tap; ++i)
                {
                    if (i + 1 <= blurSize)
                    {
                        s_blurWeights[i] = a;
                    }
                    else if (i < blurSize)
                    {
                        s_blurWeights[i] = a * (blurSize - i);
                    }
                    else
                    {
                        s_blurWeights[i] = 0.0f;
                    }
                }
            }
            param.offset.x = 0.5f + s_blurWeights[1] / (s_blurWeights[0] + s_blurWeights[1]);
            param.offset.y = 2.5f + s_blurWeights[3] / (s_blurWeights[2] + s_blurWeights[3]);
            param.offset.z = 0.0f;
            param.offset.w = 0.0f;
            return param;
        }
        void OnPostRender()
        {
            param.weight.x = s_blurWeights[0] + s_blurWeights[1];
            param.weight.y = s_blurWeights[2] + s_blurWeights[3];
            param.weight.z = 0.0f;
            param.weight.w = 0.0f;
            return param;
        }
        void OnPostRender()
        {
#if UNITY_EDITOR
            if (!(Application.isPlaying || m_isRenderingFromUpdate)) {
                return;
            }
            if (!(Application.isPlaying || m_isRenderingFromUpdate))
            {
                return;
            }
#endif
            m_camera.clearFlags = CameraClearFlags.Nothing;
            if (!m_isVisible) {
                return;
            }
            RenderTexture srcRT = m_camera.targetTexture;
            m_camera.clearFlags = CameraClearFlags.Nothing;
            if (!m_isVisible)
            {
                return;
            }
            RenderTexture srcRT = m_camera.targetTexture;
#if UNITY_5_6
            // workaround for Unity 5.6
            // Unity 5.6 has a bug whereby a temporary render texture does not work if m_camera.targetTexture != null. This bug is fixed in Unity 2017.
            // However, this workaround might conflict with VR support. If you have a problem with VR SDK, please let us know via e-mail (support@nyahoon.com).
            if (srcRT != m_shadowTexture) {
                m_camera.targetTexture = null;
            }
            // workaround for Unity 5.6
            // Unity 5.6 has a bug whereby a temporary render texture does not work if m_camera.targetTexture != null. This bug is fixed in Unity 2017.
            // However, this workaround might conflict with VR support. If you have a problem with VR SDK, please let us know via e-mail (support@nyahoon.com).
            if (srcRT != m_shadowTexture)
            {
                m_camera.targetTexture = null;
            }
#else
            m_camera.targetTexture = m_shadowTexture;
#endif
            if (m_superSampling != TextureSuperSample.x1 || HasShadowColor()) {
                m_downsampleShader.color = m_shadowColor;
                // downsample
                RenderTexture dstRT;
                if (0 < m_blurLevel) {
                    dstRT = RenderTexture.GetTemporary(m_textureWidth, m_textureHeight, 0, m_shadowTexture.format, RenderTextureReadWrite.Linear);
                    dstRT.filterMode = FilterMode.Bilinear;
                }
                else {
                    dstRT = m_shadowTexture;
                }
                Graphics.SetRenderTarget(dstRT);
                int pass = m_superSampling == TextureSuperSample.x16 ? 0 : 2;
                Graphics.Blit(srcRT, dstRT, m_downsampleShader, HasShadowColor() ? pass + 1 : pass);
                RenderTexture.ReleaseTemporary(srcRT);
                srcRT = dstRT;
            }
            if (0 < m_blurLevel) {
                // adjust blur size according to texel aspect
                float texelAspect = (m_projector.aspectRatio * m_textureHeight)/(float)m_textureWidth;
                float blurSizeH = m_blurSize;
                float blurSizeV = m_blurSize;
                if (texelAspect < 1.0f) {
                    blurSizeV *= texelAspect;
                }
                else {
                    blurSizeH /= texelAspect;
                }
                // blur parameters
                BlurParam blurH = GetBlurParam(blurSizeH, m_blurFilter);
                BlurParam blurV = GetBlurParam(blurSizeV, m_blurFilter);
                blurH.tap = (blurH.tap - 3); // index of pass
                blurV.tap = (blurV.tap - 3) + 1; // index of pass
                m_blurShader.SetVector(s_blurOffsetHParamID, blurH.offset);
                m_blurShader.SetVector(s_blurOffsetVParamID, blurV.offset);
                m_blurShader.SetVector(s_blurWeightHParamID, blurH.weight);
                m_blurShader.SetVector(s_blurWeightVParamID, blurV.weight);
            if (m_superSampling != TextureSuperSample.x1 || HasShadowColor())
            {
                m_downsampleShader.color = m_shadowColor;
                // downsample
                RenderTexture dstRT;
                if (0 < m_blurLevel)
                {
                    dstRT = RenderTexture.GetTemporary(m_textureWidth, m_textureHeight, 0, m_shadowTexture.format, RenderTextureReadWrite.Linear);
                    dstRT.filterMode = FilterMode.Bilinear;
                }
                else
                {
                    dstRT = m_shadowTexture;
                }
                Graphics.SetRenderTarget(dstRT);
                int pass = m_superSampling == TextureSuperSample.x16 ? 0 : 2;
                Graphics.Blit(srcRT, dstRT, m_downsampleShader, HasShadowColor() ? pass + 1 : pass);
                RenderTexture.ReleaseTemporary(srcRT);
                srcRT = dstRT;
            }
            if (0 < m_blurLevel)
            {
                // adjust blur size according to texel aspect
                float texelAspect = (m_projector.aspectRatio * m_textureHeight) / (float)m_textureWidth;
                float blurSizeH = m_blurSize;
                float blurSizeV = m_blurSize;
                if (texelAspect < 1.0f)
                {
                    blurSizeV *= texelAspect;
                }
                else
                {
                    blurSizeH /= texelAspect;
                }
                // blur parameters
                BlurParam blurH = GetBlurParam(blurSizeH, m_blurFilter);
                BlurParam blurV = GetBlurParam(blurSizeV, m_blurFilter);
                blurH.tap = (blurH.tap - 3); // index of pass
                blurV.tap = (blurV.tap - 3) + 1; // index of pass
                m_blurShader.SetVector(s_blurOffsetHParamID, blurH.offset);
                m_blurShader.SetVector(s_blurOffsetVParamID, blurV.offset);
                m_blurShader.SetVector(s_blurWeightHParamID, blurH.weight);
                m_blurShader.SetVector(s_blurWeightVParamID, blurV.weight);
                RenderTexture dstRT = RenderTexture.GetTemporary(m_textureWidth, m_textureHeight, 0, m_shadowTexture.format, RenderTextureReadWrite.Linear);
                dstRT.filterMode = FilterMode.Bilinear;
                srcRT.wrapMode = TextureWrapMode.Clamp;
                dstRT.wrapMode = TextureWrapMode.Clamp;
                Graphics.Blit(srcRT, dstRT, m_blurShader, blurH.tap);
                if (1 < srcRT.antiAliasing) {
                    RenderTexture.ReleaseTemporary(srcRT);
                    srcRT = RenderTexture.GetTemporary(m_textureWidth, m_textureHeight, 0, m_shadowTexture.format, RenderTextureReadWrite.Linear);
                }
                else {
                    srcRT.DiscardContents();
                }
                for (int i = 1; i < m_blurLevel - 1; ++i) {
                    Graphics.Blit(dstRT, srcRT, m_blurShader, blurV.tap);
                    dstRT.DiscardContents();
                    Graphics.Blit(srcRT, dstRT, m_blurShader, blurH.tap);
                    srcRT.DiscardContents();
                }
                RenderTexture.ReleaseTemporary(srcRT);
                srcRT = m_shadowTexture;
                Graphics.Blit(dstRT, srcRT, m_blurShader, blurV.tap);
                RenderTexture.ReleaseTemporary(dstRT);
            }
            Graphics.SetRenderTarget(m_shadowTexture);
            if (srcRT != m_shadowTexture) {
                Graphics.Blit(srcRT, m_downsampleShader, 2);
                if (m_mipLevel == 0) {
                    RenderTexture.ReleaseTemporary(srcRT);
                }
            }
            EraseShadowOnBoarder(m_textureWidth, m_textureHeight);
            if (0 < m_mipLevel) {
                // setup blur parameters
                BlurParam blurH = new BlurParam(), blurV = new BlurParam();
                if (0.1f < m_mipmapBlurSize) {
                    // adjust blur size according to texel aspect
                    float texelAspect = (m_projector.aspectRatio * m_textureHeight)/(float)m_textureWidth;
                    float blurSizeH = m_mipmapBlurSize;
                    float blurSizeV = m_mipmapBlurSize;
                    if (texelAspect < 1.0f) {
                        blurSizeV *= texelAspect;
                    }
                    else {
                        blurSizeH /= texelAspect;
                    }
                    // blur parameters
                    if (m_singlePassMipmapBlur) {
                        blurH = GetDownsampleBlurParam(2.0f + 2.0f*blurSizeH, m_blurFilter);
                        blurV = GetDownsampleBlurParam(2.0f + 2.0f*blurSizeV, m_blurFilter);
                        Vector4 weight = new Vector4(blurH.weight.x * blurV.weight.x, blurH.weight.x * blurV.weight.y, blurH.weight.y * blurV.weight.x, blurH.weight.y * blurV.weight.y);
                        float a = 0.25f/(weight.x + weight.y + weight.z + weight.w);
                        weight.x = Mathf.Round(255*a*weight.x)/255.0f;
                        weight.y = Mathf.Round(255*a*weight.y)/255.0f;
                        weight.z = Mathf.Round(255*a*weight.z)/255.0f;
                        weight.w = 0.25f - weight.x - weight.y - weight.z;
                        m_downsampleShader.SetVector(s_downSampleBlurWeightParamID, weight);
                    }
                    else {
                        blurH = GetBlurParam(blurSizeH, m_blurFilter);
                        blurV = GetBlurParam(blurSizeV, m_blurFilter);
                        blurH.tap = (blurH.tap - 3); // index of pass
                        blurV.tap = (blurV.tap - 3) + 1; // index of pass
                        m_blurShader.SetVector(s_blurOffsetHParamID, blurH.offset);
                        m_blurShader.SetVector(s_blurOffsetVParamID, blurV.offset);
                        m_blurShader.SetVector(s_blurWeightHParamID, blurH.weight);
                        m_blurShader.SetVector(s_blurWeightVParamID, blurV.weight);
                    }
                }
                int w = m_textureWidth >> 1;
                int h = m_textureHeight >> 1;
                RenderTexture tempRT = RenderTexture.GetTemporary(w, h, 0, m_shadowTexture.format, RenderTextureReadWrite.Linear);
                tempRT.filterMode = FilterMode.Bilinear;
                bool downSampleWithBlur = m_singlePassMipmapBlur && 0.1f < m_mipmapBlurSize;
                if (downSampleWithBlur) {
                    SetDownsampleBlurOffsetParams(blurH, blurV, w, h);
                }
                if (srcRT == m_shadowTexture) {
                    if (downSampleWithBlur) {
                        Graphics.Blit(srcRT, tempRT, m_downsampleShader, 5);
                    }
                    else {
                        Graphics.Blit(srcRT, tempRT, m_copyMipmapShader, 1);
                    }
                }
                else {
                    Graphics.Blit(srcRT, tempRT, m_downsampleShader, downSampleWithBlur ? 4 : 0);
                    RenderTexture.ReleaseTemporary(srcRT);
                }
                srcRT = tempRT;
                int i = 0;
                float falloff = 1.0f;
                for ( ; ; ) {
                    if (0.1f < m_mipmapBlurSize && !m_singlePassMipmapBlur) {
                        tempRT = RenderTexture.GetTemporary(w, h, 0, m_shadowTexture.format, RenderTextureReadWrite.Linear);
                        tempRT.filterMode = FilterMode.Bilinear;
                        tempRT.wrapMode = TextureWrapMode.Clamp;
                        srcRT.wrapMode = TextureWrapMode.Clamp;
                        Graphics.Blit(srcRT, tempRT, m_blurShader, blurH.tap);
                        srcRT.DiscardContents();
                        Graphics.Blit(tempRT, srcRT, m_blurShader, blurV.tap);
                        RenderTexture.ReleaseTemporary(tempRT);
                    }
                    if (m_mipmapFalloff == MipmapFalloff.Linear) {
                        falloff = ((float)(m_mipLevel - i))/(m_mipLevel + 1.0f);
                    }
                    else if (m_mipmapFalloff == MipmapFalloff.Custom && m_customMipmapFalloff != null && 0 < m_customMipmapFalloff.Length) {
                        falloff = m_customMipmapFalloff[Mathf.Min(i, m_customMipmapFalloff.Length-1)];
                    }
                    m_copyMipmapShader.SetFloat(s_falloffParamID, falloff);
                    m_copyMipmapShader.SetFloat(s_falloffParamID, falloff);
                    m_shadowTexture.DiscardContents(); // To avoid Tiled GPU perf warning. It just tells GPU not to copy back the rendered image to a tile buffer. It won't destroy the rendered image.
                    ++i;
                    Graphics.SetRenderTarget(m_shadowTexture, i);
                    Graphics.Blit(srcRT, m_copyMipmapShader, 0);
                    EraseShadowOnBoarder(w, h);
                    w = Mathf.Max(1, w >> 1);
                    h = Mathf.Max(1, h >> 1);
                    if (i == m_mipLevel || w <= 4 || h <= 4) {
                        RenderTexture.ReleaseTemporary(srcRT);
                        break;
                    }
                    tempRT = RenderTexture.GetTemporary(w, h, 0, m_shadowTexture.format, RenderTextureReadWrite.Linear);
                    tempRT.filterMode = FilterMode.Bilinear;
                    if (downSampleWithBlur) {
                        SetDownsampleBlurOffsetParams(blurH, blurV, w, h);
                        Graphics.Blit(srcRT, tempRT, m_downsampleShader, 4);
                    }
                    else {
                        Graphics.Blit(srcRT, tempRT, m_downsampleShader, 0);
                    }
                    RenderTexture.ReleaseTemporary(srcRT);
                    srcRT = tempRT;
                }
                while (1 <= w || 1 <= h) {
                    ++i;
                    Graphics.SetRenderTarget(m_shadowTexture, i);
                    GL.Clear(false, true, new Color(1,1,1,0));
                    w = w >> 1;
                    h = h >> 1;
                }
            }
            m_shadowTextureValid = true;
        }
        void EraseShadowOnBoarder(int w, int h)
        {
            float x = 1.0f - 1.0f/w;
            float y = 1.0f - 1.0f/h;
            m_eraseShadowShader.SetPass(0);
            GL.Begin(GL.LINES);
            GL.Vertex3(-x,-y,0);
            GL.Vertex3( x,-y,0);
            GL.Vertex3( x,-y,0);
            GL.Vertex3( x, y,0);
            GL.Vertex3( x, y,0);
            GL.Vertex3(-x, y,0);
            GL.Vertex3(-x, y,0);
            GL.Vertex3(-x,-y,0);
            GL.End();
        }
        void SetDownsampleBlurOffsetParams(BlurParam blurH, BlurParam blurV, int w, int h)
        {
            float invW = 0.5f/w;
            float invH = 0.5f/h;
            float offsetX0 = invW * blurH.offset.x;
            float offsetX1 = invW * blurH.offset.y;
            float offsetY0 = invH * blurV.offset.x;
            float offsetY1 = invH * blurV.offset.y;
            m_downsampleShader.SetVector(s_downSampleBlurOffset0ParamID, new Vector4(offsetX0, offsetY0, -offsetX0, -offsetY0));
            m_downsampleShader.SetVector(s_downSampleBlurOffset1ParamID, new Vector4(offsetX0, offsetY1, -offsetX0, -offsetY1));
            m_downsampleShader.SetVector(s_downSampleBlurOffset2ParamID, new Vector4(offsetX1, offsetY0, -offsetX1, -offsetY0));
            m_downsampleShader.SetVector(s_downSampleBlurOffset3ParamID, new Vector4(offsetX1, offsetY1, -offsetX1, -offsetY1));
        }
    }
                RenderTexture dstRT = RenderTexture.GetTemporary(m_textureWidth, m_textureHeight, 0, m_shadowTexture.format, RenderTextureReadWrite.Linear);
                dstRT.filterMode = FilterMode.Bilinear;
                srcRT.wrapMode = TextureWrapMode.Clamp;
                dstRT.wrapMode = TextureWrapMode.Clamp;
                Graphics.Blit(srcRT, dstRT, m_blurShader, blurH.tap);
                if (1 < srcRT.antiAliasing)
                {
                    RenderTexture.ReleaseTemporary(srcRT);
                    srcRT = RenderTexture.GetTemporary(m_textureWidth, m_textureHeight, 0, m_shadowTexture.format, RenderTextureReadWrite.Linear);
                }
                else
                {
                    srcRT.DiscardContents();
                }
                for (int i = 1; i < m_blurLevel - 1; ++i)
                {
                    Graphics.Blit(dstRT, srcRT, m_blurShader, blurV.tap);
                    dstRT.DiscardContents();
                    Graphics.Blit(srcRT, dstRT, m_blurShader, blurH.tap);
                    srcRT.DiscardContents();
                }
                RenderTexture.ReleaseTemporary(srcRT);
                srcRT = m_shadowTexture;
                Graphics.Blit(dstRT, srcRT, m_blurShader, blurV.tap);
                RenderTexture.ReleaseTemporary(dstRT);
            }
            Graphics.SetRenderTarget(m_shadowTexture);
            if (srcRT != m_shadowTexture)
            {
                Graphics.Blit(srcRT, m_downsampleShader, 2);
                if (m_mipLevel == 0)
                {
                    RenderTexture.ReleaseTemporary(srcRT);
                }
            }
            EraseShadowOnBoarder(m_textureWidth, m_textureHeight);
            if (0 < m_mipLevel)
            {
                // setup blur parameters
                BlurParam blurH = new BlurParam(), blurV = new BlurParam();
                if (0.1f < m_mipmapBlurSize)
                {
                    // adjust blur size according to texel aspect
                    float texelAspect = (m_projector.aspectRatio * m_textureHeight) / (float)m_textureWidth;
                    float blurSizeH = m_mipmapBlurSize;
                    float blurSizeV = m_mipmapBlurSize;
                    if (texelAspect < 1.0f)
                    {
                        blurSizeV *= texelAspect;
                    }
                    else
                    {
                        blurSizeH /= texelAspect;
                    }
                    // blur parameters
                    if (m_singlePassMipmapBlur)
                    {
                        blurH = GetDownsampleBlurParam(2.0f + 2.0f * blurSizeH, m_blurFilter);
                        blurV = GetDownsampleBlurParam(2.0f + 2.0f * blurSizeV, m_blurFilter);
                        Vector4 weight = new Vector4(blurH.weight.x * blurV.weight.x, blurH.weight.x * blurV.weight.y, blurH.weight.y * blurV.weight.x, blurH.weight.y * blurV.weight.y);
                        float a = 0.25f / (weight.x + weight.y + weight.z + weight.w);
                        weight.x = Mathf.Round(255 * a * weight.x) / 255.0f;
                        weight.y = Mathf.Round(255 * a * weight.y) / 255.0f;
                        weight.z = Mathf.Round(255 * a * weight.z) / 255.0f;
                        weight.w = 0.25f - weight.x - weight.y - weight.z;
                        m_downsampleShader.SetVector(s_downSampleBlurWeightParamID, weight);
                    }
                    else
                    {
                        blurH = GetBlurParam(blurSizeH, m_blurFilter);
                        blurV = GetBlurParam(blurSizeV, m_blurFilter);
                        blurH.tap = (blurH.tap - 3); // index of pass
                        blurV.tap = (blurV.tap - 3) + 1; // index of pass
                        m_blurShader.SetVector(s_blurOffsetHParamID, blurH.offset);
                        m_blurShader.SetVector(s_blurOffsetVParamID, blurV.offset);
                        m_blurShader.SetVector(s_blurWeightHParamID, blurH.weight);
                        m_blurShader.SetVector(s_blurWeightVParamID, blurV.weight);
                    }
                }
                int w = m_textureWidth >> 1;
                int h = m_textureHeight >> 1;
                RenderTexture tempRT = RenderTexture.GetTemporary(w, h, 0, m_shadowTexture.format, RenderTextureReadWrite.Linear);
                tempRT.filterMode = FilterMode.Bilinear;
                bool downSampleWithBlur = m_singlePassMipmapBlur && 0.1f < m_mipmapBlurSize;
                if (downSampleWithBlur)
                {
                    SetDownsampleBlurOffsetParams(blurH, blurV, w, h);
                }
                if (srcRT == m_shadowTexture)
                {
                    if (downSampleWithBlur)
                    {
                        Graphics.Blit(srcRT, tempRT, m_downsampleShader, 5);
                    }
                    else
                    {
                        Graphics.Blit(srcRT, tempRT, m_copyMipmapShader, 1);
                    }
                }
                else
                {
                    Graphics.Blit(srcRT, tempRT, m_downsampleShader, downSampleWithBlur ? 4 : 0);
                    RenderTexture.ReleaseTemporary(srcRT);
                }
                srcRT = tempRT;
                int i = 0;
                float falloff = 1.0f;
                for (; ; )
                {
                    if (0.1f < m_mipmapBlurSize && !m_singlePassMipmapBlur)
                    {
                        tempRT = RenderTexture.GetTemporary(w, h, 0, m_shadowTexture.format, RenderTextureReadWrite.Linear);
                        tempRT.filterMode = FilterMode.Bilinear;
                        tempRT.wrapMode = TextureWrapMode.Clamp;
                        srcRT.wrapMode = TextureWrapMode.Clamp;
                        Graphics.Blit(srcRT, tempRT, m_blurShader, blurH.tap);
                        srcRT.DiscardContents();
                        Graphics.Blit(tempRT, srcRT, m_blurShader, blurV.tap);
                        RenderTexture.ReleaseTemporary(tempRT);
                    }
                    if (m_mipmapFalloff == MipmapFalloff.Linear)
                    {
                        falloff = ((float)(m_mipLevel - i)) / (m_mipLevel + 1.0f);
                    }
                    else if (m_mipmapFalloff == MipmapFalloff.Custom && m_customMipmapFalloff != null && 0 < m_customMipmapFalloff.Length)
                    {
                        falloff = m_customMipmapFalloff[Mathf.Min(i, m_customMipmapFalloff.Length - 1)];
                    }
                    m_copyMipmapShader.SetFloat(s_falloffParamID, falloff);
                    m_copyMipmapShader.SetFloat(s_falloffParamID, falloff);
                    m_shadowTexture.DiscardContents(); // To avoid Tiled GPU perf warning. It just tells GPU not to copy back the rendered image to a tile buffer. It won't destroy the rendered image.
                    ++i;
                    Graphics.SetRenderTarget(m_shadowTexture, i);
                    Graphics.Blit(srcRT, m_copyMipmapShader, 0);
                    EraseShadowOnBoarder(w, h);
                    w = Mathf.Max(1, w >> 1);
                    h = Mathf.Max(1, h >> 1);
                    if (i == m_mipLevel || w <= 4 || h <= 4)
                    {
                        RenderTexture.ReleaseTemporary(srcRT);
                        break;
                    }
                    tempRT = RenderTexture.GetTemporary(w, h, 0, m_shadowTexture.format, RenderTextureReadWrite.Linear);
                    tempRT.filterMode = FilterMode.Bilinear;
                    if (downSampleWithBlur)
                    {
                        SetDownsampleBlurOffsetParams(blurH, blurV, w, h);
                        Graphics.Blit(srcRT, tempRT, m_downsampleShader, 4);
                    }
                    else
                    {
                        Graphics.Blit(srcRT, tempRT, m_downsampleShader, 0);
                    }
                    RenderTexture.ReleaseTemporary(srcRT);
                    srcRT = tempRT;
                }
                while (1 <= w || 1 <= h)
                {
                    ++i;
                    Graphics.SetRenderTarget(m_shadowTexture, i);
                    GL.Clear(false, true, new Color(1, 1, 1, 0));
                    w = w >> 1;
                    h = h >> 1;
                }
            }
            m_shadowTextureValid = true;
        }
        void EraseShadowOnBoarder(int w, int h)
        {
            float x = 1.0f - 1.0f / w;
            float y = 1.0f - 1.0f / h;
            if (m_eraseShadowShader != null)
            {
                m_eraseShadowShader.SetPass(0);
            }
            GL.Begin(GL.LINES);
            GL.Vertex3(-x, -y, 0);
            GL.Vertex3(x, -y, 0);
            GL.Vertex3(x, -y, 0);
            GL.Vertex3(x, y, 0);
            GL.Vertex3(x, y, 0);
            GL.Vertex3(-x, y, 0);
            GL.Vertex3(-x, y, 0);
            GL.Vertex3(-x, -y, 0);
            GL.End();
        }
        void SetDownsampleBlurOffsetParams(BlurParam blurH, BlurParam blurV, int w, int h)
        {
            float invW = 0.5f / w;
            float invH = 0.5f / h;
            float offsetX0 = invW * blurH.offset.x;
            float offsetX1 = invW * blurH.offset.y;
            float offsetY0 = invH * blurV.offset.x;
            float offsetY1 = invH * blurV.offset.y;
            m_downsampleShader.SetVector(s_downSampleBlurOffset0ParamID, new Vector4(offsetX0, offsetY0, -offsetX0, -offsetY0));
            m_downsampleShader.SetVector(s_downSampleBlurOffset1ParamID, new Vector4(offsetX0, offsetY1, -offsetX0, -offsetY1));
            m_downsampleShader.SetVector(s_downSampleBlurOffset2ParamID, new Vector4(offsetX1, offsetY0, -offsetX1, -offsetY0));
            m_downsampleShader.SetVector(s_downSampleBlurOffset3ParamID, new Vector4(offsetX1, offsetY1, -offsetX1, -offsetY1));
        }
    }
}
System/Compose/New/ComposeTicketWin.cs
@@ -219,8 +219,7 @@
            if (secondTypeDict != null)
            {
                if (secondTypeDict.Count >= 1 && curSecondType != 0
                    && curThirdType == 0)
                if (secondTypeDict.Count >= 1 && curSecondType != 0)
                {
                    cellCtrl.JumpIndex(curSecondType - 1);
                }
@@ -253,6 +252,7 @@
                        name.text = compoundModel.secondTypeName;
                        if (curSecondType == cell.index)
                        {
                            preSecondType = curSecondType;
                            arrowIcon.transform.localRotation = Quaternion.Euler(0, 0, -90);
                            icon.SetSprite("ComposeFirstClassChoosebtn");
                            secondTypeDict = composeWinModel.GetSecondTypeModel((int)ComposeFuncType.Ticket, curSecondType);
@@ -334,8 +334,7 @@
        private void OnClickThirdType(int thirdType)
        {
            curThirdType = thirdType;
            CreateCell();
            //RefreshUI(thirdTypelist[0]);
            cellCtrl.m_Scorller.RefreshActiveCellViews();
        }
        private void RefreshUI(ItemCompoundConfig compoundModel)
System/Compose/New/ComposeToolsWin.cs
@@ -242,8 +242,7 @@
            if (secondTypeDict != null)
            {
                if (secondTypeDict.Count >= 1 && curSecondType != 0
                    && curThirdType == 0)
                if (secondTypeDict.Count >= 1 && curSecondType != 0)
                {
                    cellCtrl.JumpIndex(curSecondType - 1);
                }
@@ -277,6 +276,7 @@
                        name.text = compoundModel.secondTypeName;
                        if (curSecondType == cell.index)
                        {
                            preSecondType = curSecondType;
                            arrowIcon.transform.localRotation = Quaternion.Euler(0, 0, -90);
                            icon.SetSprite("ComposeFirstClassChoosebtn");
                            secondTypeDict = composeWinModel.GetSecondTypeModel((int)ComposeFuncType.Item, curSecondType);
@@ -326,7 +326,6 @@
            {
                if (thirdType != 0)
                {
                    if (preSecondType == curSecondType)
                    {
                        curSecondType = 0;
@@ -369,8 +368,7 @@
        private void OnClickThirdType(int thirdType)
        {
            curThirdType = thirdType;
            CreateCell();
            //RefreshUI(thirdTypelist[0]);
            cellCtrl.m_Scorller.RefreshActiveCellViews();
        }
        private void RefreshUI(ItemCompoundConfig compoundModel)
System/Compose/New/ComposeWinModel.cs
@@ -11,7 +11,6 @@
    private Dictionary<int, Dictionary<int, List<ItemCompoundConfig>>> firstTypeDict = null;
    private Dictionary<int, List<ItemCompoundConfig>> secondTypeDict = null;
    private Dictionary<int, List<int>> composeJobLimitDict = new Dictionary<int, List<int>>();
    public ComposeFuncType funcType = ComposeFuncType.Wings;
    private FuncConfigConfig addonsFormulaModel;
    public event Action ResetModelEvent;
    SelectEquipModel _selectModel;
@@ -796,57 +795,50 @@
    #region 处理跳转界面数据
    public bool CheckComposeItemById(int itemId)
    public bool CheckComposeItemById(int itemId,out int jumpId)
    {
        jumpId = 0;
        ItemConfig itemConfig = Config.Instance.Get<ItemConfig>(itemId);
        if (itemConfig == null) return false;
        switch(itemConfig.Type)
        ItemCompoundConfig itemCompound = Config.Instance.Get<ItemCompoundConfig>(itemConfig.ComposeID);
        if(itemCompound.levelNeed <= PlayerDatas.Instance.baseData.LV)
        {
            case 25:
            case 35:
                funcType = ComposeFuncType.Item;
                break;
            case 39:
                funcType = ComposeFuncType.Wings;
                break;
            case 44:
                funcType = ComposeFuncType.Ticket;
                break;
        }
        firstTypeDict = ItemCompoundConfig.GetAllFirstComposeTypeDict((int)funcType);
        if (firstTypeDict != null)
        {
            foreach (var secondType in firstTypeDict.Keys)
            switch (itemCompound.firstType)
            {
                Dictionary<int, List<ItemCompoundConfig>> secondTypeDict = firstTypeDict[secondType];
                foreach(var thirdType in secondTypeDict.Keys)
                {
                    for(int i = 0; i < secondTypeDict[thirdType].Count; i++)
                    {
                        ItemCompoundConfig compoundConfig = secondTypeDict[thirdType][i];
                        int[] fixedIds = ConfigParse.GetMultipleStr<int>(compoundConfig.itemID);
                        if(fixedIds.Contains(itemId))
                        {
                            if(compoundConfig.levelNeed <= PlayerDatas.Instance.baseData.LV)
                            {
                                this.secondType = secondType;
                                this.thirdType = thirdType;
                                return true;
                            }
                            else
                            {
                                SysNotifyMgr.Instance.ShowTip("TicketComposeUnlock",compoundConfig.levelNeed,compoundConfig.secondTypeName);
                                return false;
                            }
                        }
                    }
                }
                case 1:
                    jumpId = (int)JumpUIType.ComposeFunc1;
                    break;
                case 2:
                    jumpId = (int)JumpUIType.ComposeFunc2;
                    break;
                case 3:
                    jumpId = (int)JumpUIType.ComposeFunc3;
                    break;
                case 4:
                    jumpId = (int)JumpUIType.ComposeFunc4;
                    break;
                case 5:
                    jumpId = (int)JumpUIType.ComposeFunc5;
                    break;
            }
        }
            this.secondType = itemCompound.secondType;
        return false;
            if(itemConfig.ComposeID == 223)
            {
                this.thirdType = PlayerDatas.Instance.baseData.Job;
            }
            else
            {
                this.thirdType = itemCompound.thirdType;
            }
            return true;
        }
        else
        {
            SysNotifyMgr.Instance.ShowTip("TicketComposeUnlock", itemCompound.levelNeed, itemCompound.secondTypeName);
            return false;
        }
    }
    public int secondType { get; private set; }
@@ -855,7 +847,6 @@
    {
        this.secondType = secondType;
        this.thirdType = thirdType;
        funcType = type;
        GetFirstTypeModel((int)type);
        Dictionary<int, List<ItemCompoundConfig>> dict = GetSecondTypeModel((int)type,secondType);
        if(dict == null)
System/Compose/New/ComposeWingsWin.cs
@@ -224,8 +224,7 @@
            if(secondTypeDict != null)
            {
                if (secondTypeDict.Count >= 1 && curSecondType != 0
                    && curThirdType == 0)
                if (secondTypeDict.Count >= 1 && curSecondType != 0)
                {
                    cellCtrl.JumpIndex(curSecondType - 1);
                }
@@ -257,6 +256,7 @@
                        name.text = compoundModel.secondTypeName;
                        if (curSecondType == cell.index)
                        {
                            preSecondType = curSecondType;
                            icon.SetSprite("ComposeFirstClassChoosebtn");
                            arrowIcon.transform.localRotation = Quaternion.Euler(0,0,-90);
                            secondTypeDict = composeWinModel.GetSecondTypeModel((int)ComposeFuncType.Wings, curSecondType);
@@ -345,8 +345,7 @@
        private void OnClickThirdType(int thirdType)
        {
            curThirdType = thirdType;
            CreateCell();
            //RefreshUI(thirdTypelist[0]);
            cellCtrl.m_Scorller.RefreshActiveCellViews();
            selectModel.ClearSelectModel();
        }
System/Dungeon/TargetBriefInfoWin.cs
@@ -27,8 +27,9 @@
    static void OnShowBossLifeBar(uint _instanceId, int _npcId, bool _show)
    {
        int mapId = PlayerDatas.Instance.baseData.MapID;
        if (ModelCenter.Instance.GetModel<DungeonModel>().GetDungeonDataIdByMapId(mapId) == DemonJarModel.DEMONJAR_MAPID)
        var mapId = PlayerDatas.Instance.baseData.MapID;
        var dataMapId = ModelCenter.Instance.GetModel<DungeonModel>().GetDungeonDataIdByMapId(mapId);
        if (dataMapId == DemonJarModel.DEMONJAR_MAPID)
        {
            if (_show)
            {
@@ -64,8 +65,9 @@
    static void OnRefreshBossLifeBar(uint _instanceId, int _npcId, ulong _hp, ulong _maxHp)
    {
        int mapId = PlayerDatas.Instance.baseData.MapID;
        if (ModelCenter.Instance.GetModel<DungeonModel>().GetDungeonDataIdByMapId(mapId) == DemonJarModel.DEMONJAR_MAPID)
        var mapId = PlayerDatas.Instance.baseData.MapID;
        var dataMapId = ModelCenter.Instance.GetModel<DungeonModel>().GetDungeonDataIdByMapId(mapId);
        if (dataMapId == DemonJarModel.DEMONJAR_MAPID)
        {
            DemonJarBossLifeBarWin win;
            if (!WindowCenter.Instance.CheckOpen<DemonJarBossLifeBarWin>())
@@ -81,29 +83,24 @@
        }
        else
        {
            if (PlayerDatas.Instance.hero != null && PlayerDatas.Instance.hero.SelectTarget != null
            && PlayerDatas.Instance.hero.SelectTarget.ServerInstID == TargetBriefInfoWin.currentBossInstanceId)
            {
                TargetBriefInfoWin win;
                if (!WindowCenter.Instance.CheckOpen<TargetBriefInfoWin>())
                {
                    win = WindowCenter.Instance.Open<TargetBriefInfoWin>(true);
                }
                else
                {
                    win = WindowCenter.Instance.Get<TargetBriefInfoWin>();
                }
            TargetBriefInfoWin win;
            if (!WindowCenter.Instance.CheckOpen<TargetBriefInfoWin>())
            {
                win = WindowCenter.Instance.Open<TargetBriefInfoWin>(true);
            }
            else
            {
                win = WindowCenter.Instance.Get<TargetBriefInfoWin>();
                win.RefreshBossLifeBar(_instanceId, _npcId, _hp, _maxHp);
            }
            win.RefreshBossLifeBar(_instanceId, _npcId, _hp, _maxHp);
        }
    }
    static void OnHideBossLifeBar(uint _instanceId, int _npcId)
    {
        var win = WindowCenter.Instance.Get<TargetBriefInfoWin>();
        if (win != null)
        {
            win.HideBossLifeBar(_instanceId, _npcId);
        }
    }
    static void OnShowPlayerLifeBar(uint _instanceId, bool _show)
@@ -142,8 +139,8 @@
        [SerializeField] Transform m_ContainerPlayer;
        [SerializeField] PlayerLifeBar m_PlayerLifeBar;
        uint currentBossInstanceId = 0;
        uint currentPlayerInstanceId = 0;
        public static uint currentBossInstanceId = 0;
        public static uint currentPlayerInstanceId = 0;
        #region Built-in
        protected override void BindController()
@@ -216,17 +213,6 @@
            }
            m_BossLifeBar.Show(_hp, _maxHp);
        }
        public void HideBossLifeBar(uint _instanceId, int _npcId)
        {
            if (_instanceId != currentBossInstanceId)
            {
                return;
            }
            currentBossInstanceId = 0;
            m_ContainerBoss.gameObject.SetActive(false);
        }
        public void ShowPlayerLifeBar(uint _instanceId, bool _show)
System/FairyAu/FairyGrabBossHintWin.cs
@@ -28,6 +28,9 @@
        int bossId = 0;
        uint objId = 0;
        ulong currentHp = 0;
        ulong totalHp = 0;
        FairyGrabBossModel model { get { return ModelCenter.Instance.GetModel<FairyGrabBossModel>(); } }
        #region Built-in
        protected override void BindController()
@@ -52,6 +55,8 @@
                    {
                        bossId = bossActor.NpcConfig.NPCID;
                        objId = bossActor.ServerInstID;
                        currentHp = bossActor.ActorInfo.RealHp;
                        totalHp = bossActor.ActorInfo.RealMaxHp;
                        break;
                    }
                }
@@ -59,10 +64,9 @@
            if (bossId != 0)
            {
                model.QueryGrabBossHurt(bossId, 0, objId);
                model.QueryGrabBossProgress(true);
                GlobalTimeEvent.Instance.secondEvent += SecondEvent;
                model.bossProgressUpdate += BossProgressUpdate;
                model.bossHurtUpdate += BossHurtUpdate;
                GA_NpcFightBoss.s_HpRefresh += HpRefresh;
                DisplayAreaInfo();
                DisplayTimer();
                DisplayProgress();
@@ -82,8 +86,8 @@
        protected override void OnPreClose()
        {
            GlobalTimeEvent.Instance.secondEvent -= SecondEvent;
            model.bossProgressUpdate -= BossProgressUpdate;
            model.bossHurtUpdate -= BossHurtUpdate;
            GA_NpcFightBoss.s_HpRefresh -= HpRefresh;
        }
        protected override void OnAfterClose()
@@ -98,7 +102,6 @@
            {
                m_Timer = 0f;
                model.QueryGrabBossHurt(bossId, 0, objId);
                model.QueryGrabBossProgress();
            }
        }
        #endregion
@@ -117,14 +120,9 @@
        void DisplayProgress()
        {
            FairyGrabBossModel.BossProgressInfo bossProgress;
            bool killed = false;
            if (model.TryGetBossProgress(bossId, out bossProgress))
            {
                var progress = 1 - (float)bossProgress.currentHp / bossProgress.totalHp;
                m_Progress.text = StringUtility.Contact((int)(progress * 100), "%");
                killed = progress >= 1;
            }
            var progress = 1 - (float)currentHp / totalHp;
            m_Progress.text = StringUtility.Contact((int)(progress * 100), "%");
            bool killed = progress >= 1;
            m_ContainerKilling.gameObject.SetActive(!killed);
            m_ContainerKilled.gameObject.SetActive(killed);
        }
@@ -132,17 +130,15 @@
        void DisplayRanks()
        {
            FairyGrabBossModel.FairyGrabBossInfo fairyGrabBossInfo;
            FairyGrabBossModel.BossProgressInfo bossProgress;
            var index = 0;
            if (model.TryGetBossHurt(bossId, 0, out fairyGrabBossInfo)
                && model.TryGetBossProgress(bossId, out bossProgress))
            if (model.TryGetBossHurt(bossId, 0, out fairyGrabBossInfo))
            {
                for (int i = 0; i < m_RankBehaviours.Length; i++)
                {
                    if (i < fairyGrabBossInfo.hurtInfos.Count)
                    {
                        var hurtInfo = fairyGrabBossInfo.hurtInfos[i];
                        var percent = (int)(((float)hurtInfo.totalHurt / bossProgress.totalHp) * 100);
                        var percent = (int)(((float)hurtInfo.totalHurt / totalHp) * 100);
                        m_RankBehaviours[i].Display(hurtInfo.HurtName, percent);
                        index++;
                    }
@@ -167,15 +163,6 @@
            }
        }
        private void BossProgressUpdate(int _id)
        {
            if (_id == bossId)
            {
                DisplayProgress();
                DisplayRanks();
            }
        }
        private void BossHurtUpdate(int id, int type)
        {
            if (id == bossId && type == 0)
@@ -184,6 +171,16 @@
            }
        }
        private void HpRefresh(uint arg0, int npcId, ulong hp, ulong _totalHp)
        {
            if (npcId == bossId)
            {
                currentHp = hp;
                totalHp = _totalHp;
                DisplayProgress();
            }
        }
        private void SecondEvent()
        {
            DisplayTimer();
System/FairyAu/FairyGrabBossModel.cs
@@ -77,7 +77,7 @@
        public int callMemberSeconds { get; private set; }
        private bool serverInited = false;
        private DateTime lastQueryProgressTime = DateTime.Now;
        //private DateTime lastQueryProgressTime = DateTime.Now;
        public event Action stateUpdate;
        public event Action<int> bossSelectedEvent;
@@ -86,6 +86,9 @@
        public event Action bossGrabHintEvent;
        DailyQuestModel dailyQuestModel { get { return ModelCenter.Instance.GetModel<DailyQuestModel>(); } }
        DungeonModel dungeonModel { get { return ModelCenter.Instance.GetModel<DungeonModel>(); } }
        MapModel mapModel { get { return ModelCenter.Instance.GetModel<MapModel>(); } }
        BossHomeModel bossHomeModel { get { return ModelCenter.Instance.GetModel<BossHomeModel>(); } }
        public override void Init()
        {
@@ -318,13 +321,13 @@
            }
        }
        public void QueryGrabBossProgress(bool force = false)
        public void QueryGrabBossProgress()
        {
            if (!force && (DateTime.Now - lastQueryProgressTime).TotalSeconds < 10)
            {
                return;
            }
            lastQueryProgressTime = DateTime.Now;
            //if (!force && (DateTime.Now - lastQueryProgressTime).TotalSeconds < 10)
            //{
            //    return;
            //}
            //lastQueryProgressTime = DateTime.Now;
            CAC04_tagCGQueryAllFamilyBossHurt pak = new CAC04_tagCGQueryAllFamilyBossHurt();
            GameNetSystem.Instance.SendInfo(pak);
        }
@@ -385,6 +388,114 @@
            return false;
        }
        public bool TestEnterDungeon(int bossId, out int _error)
        {
            if (!InActivityTime)
            {
                _error = 3;
                return false;
            }
            if (!PlayerDatas.Instance.fairyData.HasFairy)
            {
                _error = 1;
                return false;
            }
            if (!FuncOpen.Instance.IsFuncOpen(139))
            {
                _error = 2;
                return false;
            }
            var config = Config.Instance.Get<BossInfoConfig>(bossId);
            if (config != null)
            {
                if (!mapModel.IsMapUnLocked(config.MapID))
                {
                    _error = 6;
                    return false;
                }
            }
            var mapId = PlayerDatas.Instance.baseData.MapID;
            var mapConfig = Config.Instance.Get<MapConfig>(mapId);
            if (mapConfig.MapFBType != (int)MapType.OpenCountry)
            {
                _error = 5;
                return false;
            }
            var dataMapId = dungeonModel.GetDungeonDataIdByMapId(mapId);
            if (dataMapId == BossHomeModel.BOSSHOME_MAPID || dataMapId == ElderGodAreaModel.ELDERGODAREA_MAPID)
            {
                _error = 4;
                return false;
            }
            _error = 0;
            return true;
        }
        public void DisplayErrorTip(int error)
        {
            switch (error)
            {
                case 1:
                    SysNotifyMgr.Instance.ShowTip("FairyGrabBossNoFairy");
                    break;
                case 3:
                    SysNotifyMgr.Instance.ShowTip("FairyGrabBossUnOpen");
                    break;
                case 2:
                    FuncOpen.Instance.ProcessorFuncErrorTip(139);
                    break;
                case 4:
                    var dataMapId = dungeonModel.GetDungeonDataIdByMapId(PlayerDatas.Instance.baseData.MapID);
                    var config = Config.Instance.Get<DungeonOpenTimeConfig>(dataMapId);
                    var tip = string.Empty;
                    if (dataMapId == BossHomeModel.BOSSHOME_MAPID)
                    {
                        var vipLevel = PlayerDatas.Instance.baseData.VIPLv;
                        var vipNeed = bossHomeModel.GetFloorVipRequirement(PlayerDatas.Instance.baseData.dungeonLineId + 1);
                        if (vipLevel < vipNeed)
                        {
                            var moneyNeed = bossHomeModel.GetVipLackCost(PlayerDatas.Instance.baseData.dungeonLineId + 1);
                            var dungeonId = dungeonModel.DungeonMap(BossHomeModel.BOSSHOME_MAPID, PlayerDatas.Instance.baseData.dungeonLineId);
                            var dungeonConfig = Config.Instance.Get<DungeonConfig>(dungeonId);
                            tip = Language.Get("QuitRemindBossHome", dungeonConfig.FBName, vipNeed, moneyNeed);
                        }
                        else
                        {
                            tip = Language.Get(config.ExitDescription);
                        }
                    }
                    else
                    {
                        tip = Language.Get(config.ExitDescription);
                    }
                    ConfirmCancel.ShowPopConfirm(
                        Language.Get("Mail101"),
                        tip,
                        (bool _ok) =>
                        {
                            if (_ok)
                            {
                                WindowCenter.Instance.Close<LootPreciousFrameWin>();
                                MapTransferUtility.Instance.MoveToNPC(selectBoss);
                            }
                        }
                        );
                    break;
                case 5:
                    SysNotifyMgr.Instance.ShowTip("InDungeon_CantGo");
                    break;
                case 6:
                    SysNotifyMgr.Instance.ShowTip("Map_Delivery");
                    break;
            }
        }
        public class FairyGrabBossInfo
        {
            public int npcId { get; private set; }
System/FairyAu/FairyGrabBossWin.cs
@@ -48,7 +48,7 @@
            DisplaySurplusTime();
            DisplayBossInfo();
            DisplayHighestFairy();
            model.QueryGrabBossProgress(true);
            model.QueryGrabBossProgress();
            GlobalTimeEvent.Instance.secondEvent += SecondEvent;
            model.bossSelectedEvent += BossSelectedEvent;
            model.bossProgressUpdate += BossProgressUpdate;
@@ -171,7 +171,7 @@
        private void Goto()
        {
            var error = 0;
            if (TestEnterDungeon(out error))
            if (model.TestEnterDungeon(model.selectBoss, out error))
            {
                WindowJumpMgr.Instance.ClearJumpData();
                WindowCenter.Instance.Close<LootPreciousFrameWin>();
@@ -179,98 +179,8 @@
            }
            else
            {
                switch (error)
                {
                    case 1:
                        SysNotifyMgr.Instance.ShowTip("FairyGrabBossNoFairy");
                        break;
                    case 3:
                        SysNotifyMgr.Instance.ShowTip("FairyGrabBossUnOpen");
                        break;
                    case 2:
                        FuncOpen.Instance.ProcessorFuncErrorTip(139);
                        break;
                    case 4:
                        var dataMapId = dungeonModel.GetDungeonDataIdByMapId(PlayerDatas.Instance.baseData.MapID);
                        var config = Config.Instance.Get<DungeonOpenTimeConfig>(dataMapId);
                        var tip = string.Empty;
                        if (dataMapId == BossHomeModel.BOSSHOME_MAPID)
                        {
                            var vipLevel = PlayerDatas.Instance.baseData.VIPLv;
                            var vipNeed = bossHomeModel.GetFloorVipRequirement(PlayerDatas.Instance.baseData.dungeonLineId + 1);
                            if (vipLevel < vipNeed)
                            {
                                var moneyNeed = bossHomeModel.GetVipLackCost(PlayerDatas.Instance.baseData.dungeonLineId + 1);
                                var dungeonId = dungeonModel.DungeonMap(BossHomeModel.BOSSHOME_MAPID, PlayerDatas.Instance.baseData.dungeonLineId);
                                var dungeonConfig = Config.Instance.Get<DungeonConfig>(dungeonId);
                                tip = Language.Get("QuitRemindBossHome", dungeonConfig.FBName, vipNeed, moneyNeed);
                            }
                            else
                            {
                                tip = Language.Get(config.ExitDescription);
                            }
                        }
                        else
                        {
                            tip = Language.Get(config.ExitDescription);
                        }
                        ConfirmCancel.ShowPopConfirm(
                            Language.Get("Mail101"),
                            tip,
                            (bool _ok) =>
                            {
                                if (_ok)
                                {
                                    WindowCenter.Instance.Close<LootPreciousFrameWin>();
                                    MapTransferUtility.Instance.MoveToNPC(model.selectBoss);
                                }
                            }
                            );
                        break;
                    case 5:
                        SysNotifyMgr.Instance.ShowTip("InDungeon_CantGo");
                        break;
                }
                model.DisplayErrorTip(error);
            }
        }
        private bool TestEnterDungeon(out int _error)
        {
            if (!model.InActivityTime)
            {
                _error = 3;
                return false;
            }
            if (!PlayerDatas.Instance.fairyData.HasFairy)
            {
                _error = 1;
                return false;
            }
            if (!FuncOpen.Instance.IsFuncOpen(139))
            {
                _error = 2;
                return false;
            }
            var mapId = PlayerDatas.Instance.baseData.MapID;
            var dataMapId = dungeonModel.GetDungeonDataIdByMapId(mapId);
            if (dataMapId == BossHomeModel.BOSSHOME_MAPID || dataMapId == ElderGodAreaModel.ELDERGODAREA_MAPID)
            {
                _error = 4;
                return false;
            }
            var mapConfig = Config.Instance.Get<MapConfig>(mapId);
            if (mapConfig.MapFBType != (int)MapType.OpenCountry)
            {
                _error = 5;
                return false;
            }
            _error = 0;
            return true;
        }
        private void KillRecord()
System/KnapSack/Logic/ItemTipsModel.cs
@@ -14,11 +14,8 @@
        FuncConfigConfig exhaustedFunc;
        public Dictionary<int, List<int>> equipLegendAttrTypeDict { get; private set; }
        public Dictionary<int, Dictionary<int, string>> wingsLegendAttrColorDict { get; private set; }
        private Dictionary<int, int> itemComposeTypeDict;
        public int[] NotComposeIds { get; private set;}
        public Dictionary<string, Dictionary<LegendAttrType, int>> legendAttrCntPreviewDict { get; private set; } // key 品质+星级  value 属性条目数
        public Dictionary<int, Dictionary<LegendAttrType, List<int>>> legendAttrIDPreviewDict { get; private set; } // key 装备位 value 属性类型,属性ID
        public Dictionary<int, Dictionary<int, int>> legendAttrColorValuePreviewDict { get; private set; } // key 属性ID value 装备品质,属性数值
@@ -115,10 +112,6 @@
                    }
                }
            }
            FuncConfigConfig itemComposeTypeFunc = Config.Instance.Get<FuncConfigConfig>("BagCompound");
            itemComposeTypeDict = ConfigParse.GetDic<int, int>(itemComposeTypeFunc.Numerical1);
            NotComposeIds = ConfigParse.GetMultipleStr<int>(itemComposeTypeFunc.Numerical2);
            FuncConfigConfig legendAttrCountPreview = Config.Instance.Get<FuncConfigConfig>("LegendAttrCountPreview");
            JsonData legendAttrCntData = JsonMapper.ToObject(legendAttrCountPreview.Numerical1);
@@ -621,13 +614,14 @@
            if (!isOverdue)
            {
                if (itemComposeTypeDict.ContainsKey(attrData.itemConfig.Type) && !NotComposeIds.Contains(attrData.itemId))
                if(attrData.itemConfig.ComposeID != 0)
                {
                    attrData.SetTipsFuncBtn(ItemWinBtnType.compose, (ItemWinBtnType, ItemAttrData) => {
                        bool isUnlock = ModelCenter.Instance.GetModel<ComposeWinModel>().CheckComposeItemById(attrData.itemId);
                        int jumpId = 0;
                        bool isUnlock = ModelCenter.Instance.GetModel<ComposeWinModel>().CheckComposeItemById(attrData.itemId,out jumpId);
                        if (isUnlock)
                        {
                            PackSendQuestMgr.Instance.ClickComposeBtn(ItemWinBtnType.compose, itemComposeTypeDict[attrData.itemConfig.Type]);
                            PackSendQuestMgr.Instance.ClickComposeBtn(ItemWinBtnType.compose,jumpId);
                        }
                    });
                }
System/Message/RichMoveEvent.cs
@@ -46,7 +46,7 @@
                {
                    int id = int.Parse(href.mSplits["movenpc"]);
                    var error = 0;
                    if (MoveNpcLimit(id, out error))
                    if (!TestMoveNpc(id, out error))
                    {
                        ProcessMoveNpcError(error);
                        return false;
@@ -224,26 +224,20 @@
        _hero.MoveToPosition(pos);
    }
    private bool MoveNpcLimit(int npcId, out int error)
    private bool TestMoveNpc(int npcId, out int error)
    {
        error = 0;
        var _fairyGrabBossModel = ModelCenter.Instance.GetModel<FairyGrabBossModel>();
        if (_fairyGrabBossModel.bosses.Contains(npcId)
            && !_fairyGrabBossModel.InActivityTime)
        if (_fairyGrabBossModel.bosses.Contains(npcId))
        {
            error = 1;
            return true;
            return _fairyGrabBossModel.TestEnterDungeon(npcId, out error);
        }
        return false;
        return true;
    }
    void ProcessMoveNpcError(int error)
    {
        switch (error)
        {
            case 1:
                SysNotifyMgr.Instance.ShowTip("FairyGrabBossUnOpen");
                break;
        }
        var _fairyGrabBossModel = ModelCenter.Instance.GetModel<FairyGrabBossModel>();
        _fairyGrabBossModel.DisplayErrorTip(error);
    }
}