private void Update()
        {
            ShadowMaterial.SetMatrix("_ObstacleCameraViewMatrix", ObstacleCamera.worldToCameraMatrix);
            ShadowMaterial.SetMatrix("_ObstacleCameraProjMatrix", ObstacleCamera.projectionMatrix);

            ShadowMaterial.SetVector("_CenterWorldPos", transform.position);
            ShadowMaterial.SetColor("_Color", m_ShadowColor);
            ShadowMaterial.SetFloat("_Radius", m_Radius);
            ShadowMaterial.SetInt("_StepCount", m_StepCount);

            // if the m_Radius, m_Angle field is changed, UpdateShadowMesh() need to be called to re-build mesh
            m_obstacleCamera.orthographicSize = m_Radius;
        }
    void Update()
    {
        if (Application.isEditor)
        {
            RegenerateCurve();
        }

        shadowMapSize = Mathf.NextPowerOfTwo(shadowMapSize);
        shadowMapSize = Mathf.Clamp(shadowMapSize, 8, 2048);

        if (OutputTexture.width != shadowMapSize)
        {
            DestroySafe(_texTarget);
            MaterialCopy.SetTexture("_MainTex", OutputTexture);
        }

        var shadowMap = PushRenderTexture(shadowMapSize, shadowMapSize);

        ShadowCamera.targetTexture = shadowMap;
        ShadowCamera.rect          = new Rect(0, 0, 1, 1);
        ShadowCamera.Render();

        if (highQualityPenumbras)
        {
            ShadowMaterial.EnableKeyword("ULTRA_QUALITY");
            ShadowMaterial.DisableKeyword("NORMAL_QUALITY");
        }
        else
        {
            ShadowMaterial.EnableKeyword("NORMAL_QUALITY");
            ShadowMaterial.DisableKeyword("ULTRA_QUALITY");
        }

        ShadowMaterial.SetTexture("_FallOffTex", _fallOffTexture);
        ShadowMaterial.SetFloat("_BlurSize", blurSize * ((float)shadowMapSize / 512));
        ShadowMaterial.SetFloat("_ShadowOffset", shadowBias);

        // Calculate the distance between the light and  centre
        var texLightDistance = PushRenderTexture(shadowMapSize, shadowMapSize);

        Graphics.Blit(shadowMap, texLightDistance, ShadowMaterial, 0);

        // Stretch it into a dual parabaloid
        var texStretched = PushRenderTexture(shadowMapSize, shadowMapSize);

        Graphics.Blit(texLightDistance, texStretched, ShadowMaterial, 1);

        // Here we compress it into a 1D distance map
        var texDownSampled = texStretched;
        var width          = shadowMapSize;

        while (width > 2)
        {
            width /= 2;
            var texDownSampleTemp = PushRenderTexture(width, shadowMapSize);
            Graphics.Blit(texDownSampled, texDownSampleTemp, ShadowMaterial, 2);
            texDownSampled = texDownSampleTemp;
        }

        // Finally do a distance compare and shadow map
        Graphics.Blit(texDownSampled, OutputTexture, ShadowMaterial, 3);

        // Blur the results
        if (blurIterations > 0)
        {
            var pingPong = RenderTexture.GetTemporary(shadowMapSize, shadowMapSize, 0);
            for (int i = 0; i < blurIterations; i++)
            {
                Graphics.Blit(OutputTexture, pingPong, ShadowMaterial, 5);
                Graphics.Blit(pingPong, OutputTexture, ShadowMaterial, 4);
            }
            RenderTexture.ReleaseTemporary(pingPong);
        }

        ReleaseAllRenderTextures();
        transform.localScale = Vector3.one * _shadowCamera.orthographicSize * 2;
        Graphics.DrawMesh(_lightmesh, transform.localToWorldMatrix, _materialInstance, gameObject.layer);
    }