private void SetupSpotLight(Nigiri renderer, Matrix4x4 viewProj)
    {
        _commandBuffer.Clear();

        int pass = 1;

        if (!IsCameraInSpotLightBounds())
        {
            pass = 3;
        }

        Mesh mesh = Nigiri.GetSpotLightMesh();

        float scale      = _light.range;
        float angleScale = Mathf.Tan((_light.spotAngle + 1) * 0.5f * Mathf.Deg2Rad) * _light.range;

        Matrix4x4 world = Matrix4x4.TRS(transform.position, transform.rotation, new Vector3(angleScale, angleScale, scale));

        Matrix4x4 view = Matrix4x4.TRS(_light.transform.position, _light.transform.rotation, Vector3.one).inverse;

        Matrix4x4 clip = Matrix4x4.TRS(new Vector3(0.5f, 0.5f, 0.0f), Quaternion.identity, new Vector3(-0.5f, -0.5f, 1.0f));
        Matrix4x4 proj = Matrix4x4.Perspective(_light.spotAngle, 1, 0, 1);

        _material.SetMatrix("_MyLightMatrix0", clip * proj * view);

        _material.SetMatrix("_WorldViewProj", viewProj * world);

        _material.SetVector("_LightPos", new Vector4(_light.transform.position.x, _light.transform.position.y, _light.transform.position.z, 1.0f / (_light.range * _light.range)));
        _material.SetVector("_LightColor", _light.color * _light.intensity);


        Vector3 apex = transform.position;
        Vector3 axis = transform.forward;
        // plane equation ax + by + cz + d = 0; precompute d here to lighten the shader
        Vector3 center = apex + axis * _light.range;
        float   d      = -Vector3.Dot(center, axis);

        // update material
        _material.SetFloat("_PlaneD", d);
        _material.SetFloat("_CosAngle", Mathf.Cos((_light.spotAngle + 1) * 0.5f * Mathf.Deg2Rad));

        _material.SetVector("_ConeApex", new Vector4(apex.x, apex.y, apex.z));
        _material.SetVector("_ConeAxis", new Vector4(axis.x, axis.y, axis.z));

        _material.EnableKeyword("SPOT");

        if (Noise)
        {
            _material.EnableKeyword("NOISE");
        }
        else
        {
            _material.DisableKeyword("NOISE");
        }

        if (_light.cookie == null)
        {
            _material.SetTexture("_LightTexture0", Nigiri.GetDefaultSpotCookie());
        }
        else
        {
            _material.SetTexture("_LightTexture0", _light.cookie);
        }

        bool forceShadowsOff = false;

        if ((_light.transform.position - Camera.current.transform.position).magnitude >= QualitySettings.shadowDistance)
        {
            forceShadowsOff = true;
        }

        if (_light.shadows != LightShadows.None && forceShadowsOff == false)
        {
            clip = Matrix4x4.TRS(new Vector3(0.5f, 0.5f, 0.5f), Quaternion.identity, new Vector3(0.5f, 0.5f, 0.5f));

            if (_reversedZ)
            {
                proj = Matrix4x4.Perspective(_light.spotAngle, 1, _light.range, _light.shadowNearPlane);
            }
            else
            {
                proj = Matrix4x4.Perspective(_light.spotAngle, 1, _light.shadowNearPlane, _light.range);
            }

            Matrix4x4 m = clip * proj;
            m[0, 2] *= -1;
            m[1, 2] *= -1;
            m[2, 2] *= -1;
            m[3, 2] *= -1;

            //view = _light.transform.worldToLocalMatrix;
            _material.SetMatrix("_MyWorld2Shadow", m * view);
            _material.SetMatrix("_WorldView", m * view);

            _material.EnableKeyword("SHADOWS_DEPTH");
            _commandBuffer.SetGlobalTexture("_ShadowMapTexture", BuiltinRenderTextureType.CurrentActive);
            _commandBuffer.SetRenderTarget(renderer.GetVolumeLightBuffer());

            _commandBuffer.DrawMesh(mesh, world, _material, 0, pass);

            if (CustomRenderEvent != null)
            {
                CustomRenderEvent(renderer, this, _commandBuffer, viewProj);
            }
        }
        else
        {
            _material.DisableKeyword("SHADOWS_DEPTH");
            renderer.GlobalCommandBuffer.DrawMesh(mesh, world, _material, 0, pass);

            if (CustomRenderEvent != null)
            {
                CustomRenderEvent(renderer, this, renderer.GlobalCommandBuffer, viewProj);
            }
        }
    }
    private void SetupDirectionalLight(Nigiri renderer, Matrix4x4 viewProj)
    {
        if (_commandBuffer == null)
        {
            Start();
        }

        _commandBuffer.Clear();

        int pass = 4;

        _material.SetPass(pass);

        if (Noise)
        {
            _material.EnableKeyword("NOISE");
        }
        else
        {
            _material.DisableKeyword("NOISE");
        }

        _material.SetVector("_LightDir", new Vector4(_light.transform.forward.x, _light.transform.forward.y, _light.transform.forward.z, 1.0f / (_light.range * _light.range)));
        _material.SetVector("_LightColor", _light.color * _light.intensity);
        _material.SetFloat("_MaxRayLength", MaxRayLength);

        if (_light.cookie == null)
        {
            _material.EnableKeyword("DIRECTIONAL");
            _material.DisableKeyword("DIRECTIONAL_COOKIE");
        }
        else
        {
            _material.EnableKeyword("DIRECTIONAL_COOKIE");
            _material.DisableKeyword("DIRECTIONAL");

            _material.SetTexture("_LightTexture0", _light.cookie);
        }

        Texture nullTexture = null;

        if (_light.shadows != LightShadows.None)
        {
            _material.EnableKeyword("SHADOWS_DEPTH");
            _commandBuffer.Blit(nullTexture, renderer.GetVolumeLightBuffer(), _material, pass);

            if (CustomRenderEvent != null)
            {
                CustomRenderEvent(renderer, this, _commandBuffer, viewProj);
            }
        }
        else
        {
            _material.DisableKeyword("SHADOWS_DEPTH");
            renderer.GlobalCommandBuffer.Blit(nullTexture, renderer.GetVolumeLightBuffer(), _material, pass);

            if (CustomRenderEvent != null)
            {
                CustomRenderEvent(renderer, this, renderer.GlobalCommandBuffer, viewProj);
            }
        }
    }
    private void SetupPointLight(Nigiri renderer, Matrix4x4 viewProj)
    {
        if (_commandBuffer == null)
        {
            Start();
        }

        _commandBuffer.Clear();

        int pass = 0;

        if (!IsCameraInPointLightBounds())
        {
            pass = 2;
        }

        _material.SetPass(pass);

        Mesh mesh = Nigiri.GetPointLightMesh();

        float     scale = _light.range * 2.0f;
        Matrix4x4 world = Matrix4x4.TRS(transform.position, _light.transform.rotation, new Vector3(scale, scale, scale));

        _material.SetMatrix("_WorldViewProj", viewProj * world);
        _material.SetMatrix("_WorldView", Camera.current.worldToCameraMatrix * world);

        if (Noise)
        {
            _material.EnableKeyword("NOISE");
        }
        else
        {
            _material.DisableKeyword("NOISE");
        }

        _material.SetVector("_LightPos", new Vector4(_light.transform.position.x, _light.transform.position.y, _light.transform.position.z, 1.0f / (_light.range * _light.range)));
        _material.SetColor("_LightColor", _light.color * _light.intensity);

        if (_light.cookie == null)
        {
            _material.EnableKeyword("POINT");
            _material.DisableKeyword("POINT_COOKIE");
        }
        else
        {
            Matrix4x4 view = Matrix4x4.TRS(_light.transform.position, _light.transform.rotation, Vector3.one).inverse;
            _material.SetMatrix("_MyLightMatrix0", view);

            _material.EnableKeyword("POINT_COOKIE");
            _material.DisableKeyword("POINT");

            _material.SetTexture("_LightTexture0", _light.cookie);
        }

        bool forceShadowsOff = false;

        if ((_light.transform.position - Camera.current.transform.position).magnitude >= QualitySettings.shadowDistance)
        {
            forceShadowsOff = true;
        }

        if (_light.shadows != LightShadows.None && forceShadowsOff == false)
        {
            _material.EnableKeyword("SHADOWS_CUBE");
            _commandBuffer.SetGlobalTexture("_ShadowMapTexture", BuiltinRenderTextureType.CurrentActive);
            _commandBuffer.SetRenderTarget(renderer.GetVolumeLightBuffer());

            _commandBuffer.DrawMesh(mesh, world, _material, 0, pass);

            if (CustomRenderEvent != null)
            {
                CustomRenderEvent(renderer, this, _commandBuffer, viewProj);
            }
        }
        else
        {
            _material.DisableKeyword("SHADOWS_CUBE");
            renderer.GlobalCommandBuffer.DrawMesh(mesh, world, _material, 0, pass);

            if (CustomRenderEvent != null)
            {
                CustomRenderEvent(renderer, this, renderer.GlobalCommandBuffer, viewProj);
            }
        }
    }