void OnGUI()
    {
        Undo.RecordObject(this, "Lens Bokeh Texture Generator");

        GUILayout.Label("SETTINGS", EditorStyles.boldLabel);

        m_DestinationTexture = (Texture2D)EditorGUILayout.ObjectField("Destination Texture", m_DestinationTexture, typeof(Texture2D), false);

        if (m_DestinationTexture == null)
        {
            GUILayout.Label("Please set or create a destination texture.");
            GUILayout.BeginHorizontal();
            m_Width  = Mathf.Clamp(EditorGUILayout.IntField("Width", m_Width), 10, 4096);
            m_Height = Mathf.Clamp(EditorGUILayout.IntField("Height", m_Height), 10, 4096);
            GUILayout.EndHorizontal();
            if (GUILayout.Button("Create and set Texture"))
            {
                CreateAndSetTexture();
            }
        }
        else
        {
            m_PassCount = Mathf.Clamp(EditorGUILayout.IntField("Layer Count", m_PassCount), 1, 5);
            GUILayout.Space(20.0f);
            GUILayout.Label("LAYERS", EditorStyles.boldLabel);
            m_ScrollPos = GUILayout.BeginScrollView(m_ScrollPos);
            for (int i = 0; i < m_PassCount; ++i)
            {
                GUILayout.BeginVertical(i % 2 == 0 ? m_Background3 : m_Background1);
                BokehGenerationPass p = m_BokehPasses[i];
                p.m_BokehTexture        = (Texture2D)EditorGUILayout.ObjectField("Sprite Texture", p.m_BokehTexture, typeof(Texture2D), false);
                p.m_MinimumSize         = DoSlider("Minimum Size", p.m_MinimumSize, 20.0f, 400.0f);
                p.m_MaximumSize         = DoSlider("Maximum Size", p.m_MaximumSize, 20.0f, 400.0f);
                p.m_BlurRadius          = DoSlider("Blur Radius", p.m_BlurRadius, 0.0f, 10.0f);
                p.m_VignettePower       = DoSlider("Vignette Power", p.m_VignettePower, 0.0f, 10.0f);
                p.m_HueVariation        = DoSlider("Hue Variation", p.m_HueVariation, 0.0f, 0.8f);
                p.m_MinIntensity        = DoSlider("Minimum Intensity", p.m_MinIntensity, 0.0f, 1.0f);
                p.m_MaxIntensity        = DoSlider("Maximum Intensity", p.m_MaxIntensity, 0.0f, 1.0f);
                p.m_Density             = DoSlider("Density", p.m_Density, 0.0f, 1.0f);
                p.m_ChromaticAberration = DoSlider("Chromatic Aberration", p.m_ChromaticAberration, 0.0f, 50.0f);
                p.m_RandomRotation      = EditorGUILayout.Toggle("Random Rotation", p.m_RandomRotation);
                GUILayout.Space(20.0f);
                GUILayout.EndVertical();
            }
            GUILayout.EndScrollView();



            if (GUILayout.Button("Generate Bokeh Texture"))
            {
                GenerateTexture();
            }

            if (m_DestinationTexture != null)
            {
                GUILayout.BeginVertical(m_Background4);

                float w = m_DestinationTexture.width;
                if (m_DestinationTexture.width > 300.0f)
                {
                    w = 300.0f;
                }

                float h = ((float)m_DestinationTexture.height / (float)m_DestinationTexture.width) * w;

                Rect r = GUILayoutUtility.GetRect(w, h);


                r.position = new Vector2(r.width * 0.5f - w * 0.5f, r.position.y);

                r.height = h;
                r.width  = w;

                //Debug.Log("r=" + h);
                EditorGUI.DrawPreviewTexture(r, m_DestinationTexture);

                GUILayout.EndVertical();
            }
        }



        if (GUI.changed)
        {
            EditorUtility.SetDirty(this);
        }
    }
    private RenderTexture GenerateTexture(int idx, Material material, Material blurMaterial, Material miscMaterial, int width, int height, BokehGenerationPass p)
    {
        RenderTexture rtA = RenderTexture.GetTemporary(width, height);

        //RenderTexture lastActive = RenderTexture.active;

        material.mainTexture = p.m_BokehTexture;

        RenderTexture.active = rtA;
        GL.Clear(true, true, Color.black);


        //GL.LoadPixelMatrix(0,width,0,height);
        //GL.LoadPixelMatrix(0, width, 0, height);
        Matrix4x4 proj = Matrix4x4.Ortho(0, width, 0, height, -1.0f, 1.0f);

        material.SetMatrix("_MeshProjectionMatrix", proj);

        int nbPixel = width * height;
        int nbQuad  = (int)(p.m_Density * 0.0004f * nbPixel);

        material.SetFloat("_Intensity", UnityEngine.Random.Range(p.m_MinIntensity, p.m_MaxIntensity));

        float cellSize = Mathf.Max(Mathf.Sqrt(nbQuad), 0.1f);

        float xStep = (float)width / cellSize;
        float yStep = (float)height / cellSize;

        for (float i = 0; i < width; i += xStep)
        {
            for (float j = 0; j < height; j += yStep)
            {
                Color tint = new Color(UnityEngine.Random.Range(1.0f - p.m_HueVariation, 1.0f), UnityEngine.Random.Range(1.0f - p.m_HueVariation, 1.0f), UnityEngine.Random.Range(1.0f - p.m_HueVariation, 1.0f));
                material.SetColor("_Tint", tint);
                material.SetPass(0);
                float size = UnityEngine.Random.Range(p.m_MinimumSize, p.m_MaximumSize);

                //float x = UnityEngine.Random.Range(-1f, 1f);
                //float y = UnityEngine.Random.Range(-1f, 1f);


                float x = (i + UnityEngine.Random.Range(0, xStep)) / width * 2.0f - 1.0f;
                float y = (j + UnityEngine.Random.Range(0, yStep)) / height * 2.0f - 1.0f;

                float dist    = new Vector2(x, y).magnitude;
                float sizeMul = Mathf.Min(Mathf.Pow(dist, p.m_VignettePower), 1.0f);


                float   s     = sizeMul > 0.5f ? size * sizeMul : 0.0f;
                float   angle = UnityEngine.Random.Range(0.0f, p.m_RandomRotation ? 360.0f : 0.0f);
                Vector3 nDiv  = new Vector3(1.0f / width, 1.0f / height, 0.0f);
                Vector3 tl    = RotateZ(new Vector3(-s, -s, 0.0f), angle);
                Vector3 tr    = RotateZ(new Vector3(s, -s, 0f), angle);
                Vector3 br    = RotateZ(new Vector3(s, s, 0f), angle);
                Vector3 bl    = RotateZ(new Vector3(-s, s, 0f), angle);

                tl = new Vector3(tl.x * nDiv.x, tl.y * nDiv.y, 0.0f);
                tr = new Vector3(tr.x * nDiv.x, tr.y * nDiv.y, 0.0f);
                br = new Vector3(br.x * nDiv.x, br.y * nDiv.y, 0.0f);
                bl = new Vector3(bl.x * nDiv.x, bl.y * nDiv.y, 0.0f);


                DrawQuad(x, y, tl, tr, br, bl);
            }
        }

        if (material.SetPass(0))
        {
            /*for (int i = 0; i < nbQuad; ++i)
             * {
             *  Color tint = new Color(UnityEngine.Random.Range(1.0f - p.m_HueVariation, 1.0f), UnityEngine.Random.Range(1.0f - p.m_HueVariation, 1.0f), UnityEngine.Random.Range(1.0f - p.m_HueVariation, 1.0f));
             *  material.SetColor("_Tint", tint);
             *  material.SetPass(0);
             *  float size = UnityEngine.Random.Range(p.m_MinimumSize, p.m_MaximumSize);
             *
             *  //float x = UnityEngine.Random.Range(-1f, 1f);
             *  //float y = UnityEngine.Random.Range(-1f, 1f);
             *
             *  Vector3 pos = PickPosition(idx);
             *  float x = pos.x;
             *  float y = pos.y;
             *
             *  float dist = new Vector2(x, y).magnitude;
             *  float sizeMul = Mathf.Min(Mathf.Pow(dist, p.m_VignettePower), 1.0f);
             *
             *
             *  float s = sizeMul > 0.5f ? size * sizeMul : 0.0f;
             *  float angle = UnityEngine.Random.Range(0.0f, p.m_RandomRotation? 360.0f : 0.0f);
             *  Vector3 nDiv = new Vector3(1.0f / width, 1.0f / height, 0.0f);
             *  Vector3 tl = RotateZ(new Vector3(-s, -s, 0.0f), angle);
             *  Vector3 tr = RotateZ(new Vector3(s, -s, 0f), angle);
             *  Vector3 br = RotateZ(new Vector3(s, s, 0f), angle);
             *  Vector3 bl = RotateZ(new Vector3(-s, s, 0f), angle);
             *
             *  tl = new Vector3(tl.x * nDiv.x, tl.y * nDiv.y, 0.0f);
             *  tr = new Vector3(tr.x * nDiv.x, tr.y * nDiv.y, 0.0f);
             *  br = new Vector3(br.x * nDiv.x, br.y * nDiv.y, 0.0f);
             *  bl = new Vector3(bl.x * nDiv.x, bl.y * nDiv.y, 0.0f);
             *
             *
             *  DrawQuad(x, y, tl , tr , br , bl );
             * }*/
        }

        RenderTexture rtB = RenderTexture.GetTemporary(width, height);

        for (int i = 0; i < 1; ++i)
        {
            RenderTexture.active = rtB;
            blurMaterial.SetTexture("_AdditiveTexture", Texture2D.blackTexture);
            blurMaterial.SetVector("_OffsetInfos", new Vector4(1.0f / width * p.m_BlurRadius, 0, 0, 0));
            blurMaterial.SetVector("_Tint", Color.white);
            blurMaterial.SetFloat("_Intensity", 1.0f);
            Graphics.Blit(rtA, rtB, blurMaterial, 2);

            blurMaterial.SetVector("_OffsetInfos", new Vector4(0, 1.0f / height * p.m_BlurRadius, 0, 0));
            Graphics.Blit(rtB, rtA, blurMaterial, 4);
        }

        // Chromatic Aberration
        miscMaterial.SetFloat("_ChromaticAberration", p.m_ChromaticAberration);
        Graphics.Blit(rtA, rtB, miscMaterial, 0);

        /*RenderTexture.active = rtB;
         * Texture2D texture = new Texture2D(width, height);
         * texture.ReadPixels(new Rect(0, 0, width, height), 0, 0);
         * texture.Apply();*/

        RenderTexture.ReleaseTemporary(rtA);
        //RenderTexture.ReleaseTemporary(rtB);
        //RenderTexture.active = lastActive;

        return(rtB);
    }