Example #1
0
        void ConfigureLights(CullingResults cull)
        {
            Vector4[] visibleLightColors     = new Vector4[_maximumLightCount];
            Vector4[] visibleLightDirections = new Vector4[_maximumLightCount];
            for (int i = 0; i < cull.visibleLights.Length; i++)
            {
                if (i > _maximumLightCount)
                {
                    break;
                }
                VisibleLight light = cull.visibleLights[i];
                visibleLightColors[i] = light.finalColor;
                // visibleLightColors[i].y = light.finalColor.g;
                // visibleLightColors[i].z = light.finalColor.b;

                Vector4 v = light.localToWorldMatrix.GetColumn(2);
                v.x = -v.x;
                v.y = -v.y;
                v.z = -v.z;
                visibleLightDirections[i] = v;
            }
            if (cull.visibleLights.Length > _maximumLightCount)
            {
                var lightIndices = cull.GetLightIndexMap(new Unity.Collections.Allocator());//.GetLightIndexMap();
                for (int i = _maximumLightCount; i < cull.visibleLights.Length; i++)
                {
                    lightIndices[i] = -1;
                }
                cull.SetLightIndexMap(lightIndices);
            }

            _buffer.SetGlobalVectorArray(Shader.PropertyToID("_VisibleLightColors"), visibleLightColors);
            _buffer.SetGlobalVectorArray(Shader.PropertyToID("_VisibleLightDirections"), visibleLightDirections);
        }
    void ConfigureLights()
    {
        for (int i = 0; i < _cullingResults.visibleLights.Length; i++)
        {
            if (i == maxVisibleLights)
            {
                break;
            }

            VisibleLight light = _cullingResults.visibleLights[i];
            visibleLightColors[i] = light.finalColor;
            Vector4 attenuation = Vector4.zero;
            attenuation.w = 1f;

            if (light.lightType == LightType.Directional)
            {
                Vector4 v = light.localToWorldMatrix.GetColumn(2);
                v.x = -v.x;
                v.y = -v.y;
                v.z = -v.z;
                visibleLightDirectionsOrPositions[i] = v;
            }
            else
            {
                visibleLightDirectionsOrPositions[i] = light.localToWorldMatrix.GetColumn(3);
                attenuation.x = 1f / Mathf.Max(light.range * light.range, 0.00001f);

                if (light.lightType == LightType.Spot)
                {
                    Vector4 v = light.localToWorldMatrix.GetColumn(2);
                    v.x = -v.x;
                    v.y = -v.y;
                    v.z = -v.z;
                    visibleLightSpotDirections[i] = v;

                    float outerRad   = Mathf.Deg2Rad * 0.5f * light.spotAngle;
                    float outerCos   = Mathf.Cos(outerRad);
                    float outerTan   = Mathf.Tan(outerRad);
                    float innerCos   = Mathf.Cos(Mathf.Atan((46f / 64f) * outerTan));
                    float angleRange = Mathf.Max(innerCos - outerCos, 0.001f);
                    attenuation.z = 1f / angleRange;
                    attenuation.w = -outerCos * attenuation.z;
                }
            }

            visibleLightAttenuations[i] = attenuation;
        }

        if (_cullingResults.visibleLights.Length > maxVisibleLights)
        {
            var lightIndices = _cullingResults.GetLightIndexMap(Allocator.Temp);
            for (int i = maxVisibleLights; i < _cullingResults.visibleLights.Length; i++)
            {
                lightIndices[i] = -1;
            }

            _cullingResults.SetLightIndexMap(lightIndices);
        }
    }
Example #3
0
 internal static void SetupCullingResultsForRendering(ref RenderingData renderingData, ref CullingResults cullingResults, PerObjectData perObjectData)
 {
     if (0 < renderingData.lightData.additionalLightsCount && (perObjectData & PerObjectData.LightIndices) != 0)
     {
         cullingResults.visibleLights.CopyFrom(renderingData.cullResults.visibleLights);
         var lightIndexMap = renderingData.cullResults.GetLightIndexMap(Unity.Collections.Allocator.Temp);
         cullingResults.SetLightIndexMap(lightIndexMap);
         lightIndexMap.Dispose();
     }
     if ((perObjectData & PerObjectData.ReflectionProbes) != 0)
     {
         cullingResults.visibleReflectionProbes.CopyFrom(renderingData.cullResults.visibleReflectionProbes);
         var indexMap = renderingData.cullResults.GetReflectionProbeIndexMap(Unity.Collections.Allocator.Temp);
         cullingResults.SetReflectionProbeIndexMap(indexMap);
         indexMap.Dispose();
     }
 }
        void SetupPerObjectLightIndices(CullingResults cullResults, ref LightData lightData)
        {
            if (lightData.additionalLightsCount == 0)
            {
                return;
            }

            var visibleLights          = lightData.visibleLights;
            var perObjectLightIndexMap = cullResults.GetLightIndexMap(Allocator.Temp);
            int directionalLightsCount = 0;
            int additionalLightsCount  = 0;

            // Disable all directional lights from the perobject light indices
            // Pipeline handles them globally.
            for (int i = 0; i < visibleLights.Length; ++i)
            {
                if (additionalLightsCount >= LightweightRenderPipeline.maxVisibleAdditionalLights)
                {
                    break;
                }

                VisibleLight light = visibleLights[i];
                if (light.lightType == LightType.Directional)
                {
                    perObjectLightIndexMap[i] = -1;
                    ++directionalLightsCount;
                }
                else
                {
                    perObjectLightIndexMap[i] -= directionalLightsCount;
                    ++additionalLightsCount;
                }
            }

            // Disable all remaining lights we cannot fit into the global light buffer.
            for (int i = directionalLightsCount + additionalLightsCount; i < visibleLights.Length; ++i)
            {
                perObjectLightIndexMap[i] = -1;
            }

            cullResults.SetLightIndexMap(perObjectLightIndexMap);
            perObjectLightIndexMap.Dispose();
        }
Example #5
0
        int SetupPerObjectLightIndices(ref CullingResults cullingResults, int dynamicLightsMaxCount)
        {
            Debug.Assert(dynamicLightsMaxCount > 0);

            var visibleLights = cullingResults.visibleLights;

            var perObjectLightIndexMap       = cullingResults.GetLightIndexMap(Allocator.Temp);
            int globalDirectionalLightsCount = 0;
            int additionalLightsCount        = 0;

            // Disable all directional lights from the perobject light indices
            // Pipeline handles main light globally and there's no support for additional directional lights atm.
            for (int i = 0; i < visibleLights.Length; ++i)
            {
                if (additionalLightsCount >= dynamicLightsMaxCount)
                {
                    break;
                }

                VisibleLight light = visibleLights[i];
                // if (i == lightData.mainLightIndex)
                // {
                //     perObjectLightIndexMap[i] = -1;
                //     ++globalDirectionalLightsCount;
                // }
                // else
                // {
                perObjectLightIndexMap[i] -= globalDirectionalLightsCount;
                ++additionalLightsCount;
                // }
            }

            // Disable all remaining lights we cannot fit into the global light buffer.
            for (int i = globalDirectionalLightsCount + additionalLightsCount; i < perObjectLightIndexMap.Length; ++i)
            {
                perObjectLightIndexMap[i] = -1;
            }

            cullingResults.SetLightIndexMap(perObjectLightIndexMap);
            perObjectLightIndexMap.Dispose();
            return(additionalLightsCount);
        }
    void ConfigureLights()
    {
        shadowTileCount = 0;
        for (int i = 0; i < cull.visibleLights.Length; i++)
        {
            if (i == maxVisibleLights)
            {
                break;
            }

            VisibleLight light = cull.visibleLights[i];
            visibleLightColors[i] = light.finalColor;

            Vector4 attenuation = Vector4.zero;
            attenuation.w = 1f;
            Vector4 shadow = Vector4.zero;
            if (light.lightType == LightType.Directional)
            {
                Vector4 v = light.localToWorldMatrix.GetColumn(2);
                v.x = -v.x;
                v.y = -v.y;
                v.z = -v.z;
                visibleLightDirectionsOrPositions[i] = v;

                shadow   = ConfigureShadows(i, light.light);
                shadow.z = 1f;                //marks the shadow as being a directional light shadow
            }
            else
            {
                visibleLightDirectionsOrPositions[i] = light.localToWorldMatrix.GetColumn(3);                //this is the position for point lights
                attenuation.x = 1f / Mathf.Max(light.range * light.range, 0.00001f);


                if (light.lightType == LightType.Spot)
                {
                    Vector4 v = light.localToWorldMatrix.GetColumn(2);
                    v.x = -v.x;
                    v.y = -v.y;
                    v.z = -v.z;
                    visibleLightSpotDirections[i] = v;


                    float outerRad = Mathf.Deg2Rad * 0.5f * light.spotAngle;
                    float outerCos = Mathf.Cos(outerRad);
                    float outerTan = Mathf.Tan(outerRad);
                    float innerCos = Mathf.Cos(Mathf.Atan(((46f / 64f) * outerTan)));

                    float angleRange = Mathf.Max(innerCos - outerCos, 0.001f);
                    attenuation.z = 1f / angleRange;
                    attenuation.w = -outerCos * attenuation.z;

                    //shadows
                    shadow = ConfigureShadows(i, light.light);
                }
            }

            visibleLightAttenuations[i] = attenuation;
            shadowData[i] = shadow;
        }

        //TODO: READ UP ON NATIVE LISTS AND JUNK
        if (cull.visibleLights.Length > maxVisibleLights)
        {
            var lightIndicies = cull.GetLightIndexMap(Unity.Collections.Allocator.Temp);

            for (int i = maxVisibleLights; i < cull.visibleLights.Length; i++)
            {
                lightIndicies[i] = -1;
            }
            cull.SetLightIndexMap(lightIndicies);
        }
    }
Example #7
0
    void ConfigureLights()
    {
        mainLightExists    = false;
        shadowMapTileCount = 0;
        for (int i = 0; i < cullingResults.visibleLights.Length; i++)
        {
            if (i == maxVisibleLights)
            {
                break;
            }
            VisibleLight light = cullingResults.visibleLights[i];
            visibleLightColors[i] = light.finalColor;
            Vector4 attenuation = Vector4.zero;
            attenuation.w = 1f;
            Vector4 shadow = Vector4.zero;

            if (light.lightType == LightType.Directional)
            {
                Vector4 v = CalculateLightDir(light);
                visibleLightDirectionsOrPositions[i] = v;
                shadow   = ConfigureShadows(i, light.light);
                shadow.z = 1f;
                if (i == 0 && shadow.x > 0f && shadowCascades > 0)
                {
                    mainLightExists     = true;
                    shadowMapTileCount -= 1;
                }
            }
            else
            {
                visibleLightDirectionsOrPositions[i] =
                    light.localToWorldMatrix.GetColumn(3);
                attenuation = CalcualteAtten(light);

                if (light.lightType == LightType.Spot)
                {
                    Vector4 v = CalculateLightDir(light);
                    visibleLightSpotDirections[i] = v;
                    attenuation = CalcualteAtten(light);
                    shadow      = ConfigureShadows(i, light.light);
                    shadow.z    = 0;
                }
            }

            visibleLightAttenuations[i] = attenuation;
            shadowData[i] = shadow;
        }

        if (mainLightExists || cullingResults.visibleLights.Length > maxVisibleLights)
        {
            Unity.Collections.NativeArray <int> lightIndices = cullingResults.GetLightIndexMap(Unity.Collections.Allocator.Temp);

            if (mainLightExists)
            {
                lightIndices[0] = -1;
            }

            for (int i = maxVisibleLights; i < cullingResults.visibleLights.Length; i++)
            {
                lightIndices[i] = -1;
            }
            cullingResults.SetLightIndexMap(lightIndices);
        }
    }
Example #8
0
    void SetupLights(bool useLightPerObject, int camRenderingLayerMask)
    {
        //get a temp light indice array
        NativeArray <int> indexMap = useLightPerObject ?
                                     cullingResults.GetLightIndexMap(Allocator.Temp) :
                                     default;

        //Switch to get lights via Culling result
        NativeArray <VisibleLight> visibleLights = cullingResults.visibleLights;

        int dirLightCount = 0, otherLightCount = 0;
        int i;

        for (i = 0; i < visibleLights.Length; i++)
        {
            // set the index for directional lights to -1 unity will not include this into per object lighting
            int          newIndex     = -1;
            VisibleLight visibleLight = visibleLights[i];
            Light        light        = visibleLight.light;
            if ((light.renderingLayerMask & camRenderingLayerMask) != 0)
            {
                switch (visibleLight.lightType)
                {
                case LightType.Directional:
                    if (dirLightCount < maxDirLightCount)
                    {
                        SetupDirectionalLight(dirLightCount++, i, ref visibleLight, light);
                    }
                    break;

                case LightType.Point:
                    if (otherLightCount < maxOtherLightCount)
                    {
                        newIndex = otherLightCount;
                        SetupPointLight(otherLightCount++, i, ref visibleLight, light);
                    }
                    break;

                case LightType.Spot:
                    if (otherLightCount < maxOtherLightCount)
                    {
                        newIndex = otherLightCount;
                        SetupSpotLight(otherLightCount++, i, ref visibleLight, light);
                    }
                    break;
                }
            }
            if (useLightPerObject)//set index for visible lights
            {
                indexMap[i] = newIndex;
            }
        }
        if (useLightPerObject)//set index of invisible lights to -1
        {
            for (; i < indexMap.Length; i++)
            {
                indexMap[i] = -1;
            }
            cullingResults.SetLightIndexMap(indexMap);
            indexMap.Dispose();
            Shader.EnableKeyword(lightsPerObjectKeyword);
        }
        else
        {
            Shader.DisableKeyword(lightsPerObjectKeyword);
        }


        //Set to global so all shader for dirctional lights
        buffer.SetGlobalInt(dirLightCountId, dirLightCount);
        if (dirLightCount > 0)
        {
            buffer.SetGlobalVectorArray(dirLightColorId, dirLightColors);
            buffer.SetGlobalVectorArray(dirLightDirectionsAndMasksId, dirLightDirectionsAndMasks);
            buffer.SetGlobalVectorArray(dirLightShadowDataId, dirLightShadowData);
        }
        //set params for other lights
        buffer.SetGlobalInt(otherLightCountID, otherLightCount);
        if (otherLightCount > 0)
        {
            buffer.SetGlobalVectorArray(otherLightColorsID, otherLightColors);
            buffer.SetGlobalVectorArray(otherLightPositionsID, otherLightPositions);
            buffer.SetGlobalVectorArray(otherLightDirectionsAndMasksID, otherLightDirectionsAndMasks);
            buffer.SetGlobalVectorArray(otherLightSpotAnhglesID, otherLightSpotAngles);
            buffer.SetGlobalVectorArray(otherLightShadowDataId, otherLightShadowData);
        }
    }
Example #9
0
    void SetupLights(bool useLightsPerObject)
    {
        NativeArray <int> indexMap = useLightsPerObject ?
                                     cullingResults.GetLightIndexMap(Allocator.Temp) : default;

        NativeArray <VisibleLight> visibleLights = cullingResults.visibleLights;
        int dirLightCount   = 0;
        int otherLightCount = 0;
        int i;

        for (i = 0; i < visibleLights.Length; i++)
        {
            int          newIndex     = -1;
            VisibleLight visibleLight = visibleLights[i];
            switch (visibleLight.lightType)
            {
            case LightType.Directional:
                if (dirLightCount < maxDirLightCount)
                {
                    SetupDirectionalLight(dirLightCount++, ref visibleLight);
                }
                break;

            case LightType.Point:
                if (otherLightCount < maxOtherLightCount)
                {
                    newIndex = otherLightCount;
                    SetupPointLight(otherLightCount++, ref visibleLight);
                }
                break;

            case LightType.Spot:
                if (otherLightCount < maxOtherLightCount)
                {
                    newIndex = otherLightCount;
                    SetupSpotLight(otherLightCount++, ref visibleLight);
                }
                break;
            }

            if (useLightsPerObject)
            {
                indexMap[i] = newIndex;
            }
        }

        //We have to sanitize these lists so only the indices of visible non-directional lights remain.
        //保留可见的非方向光
        if (useLightsPerObject)
        {
            for (; i < indexMap.Length; i++)
            {
                indexMap[i] = -1;
            }
            cullingResults.SetLightIndexMap(indexMap);
            indexMap.Dispose();
            Shader.EnableKeyword(lightsPerObjectKeyword);
        }
        else
        {
            Shader.DisableKeyword(lightsPerObjectKeyword);
        }

        buffer.SetGlobalInt(dirLightCountId, dirLightCount);
        if (dirLightCount > 0)
        {
            buffer.SetGlobalVectorArray(dirLightColorsId, dirLightColors);
            buffer.SetGlobalVectorArray(dirLightDirectionsId, dirLightDirections);
            buffer.SetGlobalVectorArray(dirLightShadowDataId, dirLightShadowData);
        }

        buffer.SetGlobalInt(otherLightCountId, otherLightCount);
        if (otherLightCount > 0)
        {
            buffer.SetGlobalVectorArray(otherLightColorsId, otherLightColors);
            buffer.SetGlobalVectorArray(
                otherLightPositionsId, otherLightPositions
                );
            buffer.SetGlobalVectorArray(
                otherLightDirectionsId, otherLightDirections
                );

            buffer.SetGlobalVectorArray(
                otherLightShadowDataId, otherLightShadowData
                );
        }
    }
Example #10
0
    /// <summary>
    /// 构建灯光信息
    /// </summary>
    private void configureLights()
    {
        m_mainLightExits  = false;
        m_shadowTileCount = 0;


        for (int i = 0; i < m_cullingResults.visibleLights.Length; i++)
        {
            //相机控制中存在的灯光大于最大灯光配置时停止
            if (i == m_maxVisibleLights)
            {
                break;
            }

            VisibleLight light = m_cullingResults.visibleLights[i];

            //设置灯光颜色
            m_visibleLightColors[i] = light.finalColor;

            //灯光衰减信息
            Vector4 attenuation = Vector4.zero;
            attenuation.w = 1.0f;

            Vector4 shadow = Vector4.zero;

            if (light.lightType == LightType.Directional)
            {
                //通过取灯光变换矩阵的Z取反获得灯光方向
                Vector4 v = light.localToWorldMatrix.GetColumn(2);
                v.x = -v.x;
                v.y = -v.y;
                v.z = -v.z;

                //设置灯光的方向
                m_visibleLightDirectionsOrPositions[i] = v;

                shadow   = configureShadows(i, light.light);
                shadow.z = 1.0f;

                //判断是否使用CSM
                if (i == 0 && shadow.x > 0.0f && m_rpp.shadowCascades > 0)
                {
                    m_mainLightExits   = true;
                    m_shadowTileCount -= 1;
                }
            }
            else
            {
                //提取第4列的位置变换保存灯光位置
                m_visibleLightDirectionsOrPositions[i] = light.localToWorldMatrix.GetColumn(3);

                attenuation.x = 1f / Mathf.Max(light.range * light.range, 0.00001f);

                if (light.lightType == LightType.Spot)
                {
                    Vector4 v = light.localToWorldMatrix.GetColumn(2);
                    v.x = -v.x;
                    v.y = -v.y;
                    v.z = -v.z;

                    //聚光灯方向
                    m_visibleLightSpotDirections[i] = v;

                    //计算聚光灯的半角余弦值
                    float outerRad = Mathf.Deg2Rad * 0.5f * light.spotAngle;
                    float outerCos = Mathf.Cos(outerRad);
                    float outerTan = Mathf.Tan(outerRad);

                    //定义聚光灯内外角关系,计算内角余弦值
                    float innerCos = Mathf.Cos(Mathf.Atan((46f / 64f) * outerTan));
                    //计算内外角余弦差值,避免为0
                    //cos(ri) - cos(r0)
                    float angleRange = Mathf.Max(innerCos - outerCos, 0.001f);
                    attenuation.z = 1.0f / angleRange;
                    // - cos(r0) / cos(ri) - cos(r0)
                    attenuation.w = -outerCos * attenuation.z;

                    shadow = configureShadows(i, light.light);
                }
            }

            //方向光没有衰减信息
            m_visibleLightAttenuations[i] = attenuation;

            //构建阴影信息 x: 阴影强度 y: 阴影类型
            m_shadowData[i] = shadow;
        }

        //当场景灯光数量改变后清除没用的灯光信息
        if (m_cullingResults.visibleLights.Length > m_maxVisibleLights)
        {
            var indexs = m_cullingResults.GetLightIndexMap(new Unity.Collections.Allocator());

            if (m_mainLightExits)
            {
                indexs[0] = -1;
            }

            for (int i = m_maxVisibleLights; i < m_cullingResults.visibleLights.Length; i++)
            {
                indexs[i] = -1;
            }

            m_cullingResults.SetLightIndexMap(indexs);
        }
    }
Example #11
0
        //存入可见的方向光信息
        void ConfigureLights()
        {
            mainLightExists = false;
            shadowTileCount = 0;
            for (int i = 0; i < culling.visibleLights.Length; ++i)
            {
                if (i == maxVisibleLights)
                {
                    break;
                }

                Vector4      attenuation = Vector4.zero;
                VisibleLight light       = culling.visibleLights[i];
                visibleLightColors[i] = light.finalColor;
                attenuation.w         = 1;
                Vector4 shadow = Vector4.zero;

                if (light.lightType == LightType.Directional)
                {
                    Vector4 v = light.localToWorldMatrix.GetColumn(2);
                    v.x = -v.x;
                    v.y = -v.y;
                    v.z = -v.z;
                    visibleLightDirectionsOrPositions[i] = v;
                    shadow = ConfigureShadows(i, light.light);

                    //用z通道为1来表示存储的是方向光的数据
                    shadow.z = 1;

                    //判断是否是满足条件的主光源
                    if (i == 0 && shadow.x > 0f && shadowCascades > 0)
                    {
                        mainLightExists = true;
                        //级联阴影贴图不会使用其他阴影一样的贴图
                        shadowTileCount -= 1;
                    }
                }
                else
                {
                    visibleLightDirectionsOrPositions[i] = light.localToWorldMatrix.GetColumn(3);
                    attenuation.x = 1f / Mathf.Max(light.range * light.range, 0.00001f);
                    if (light.lightType == LightType.Spot)
                    {
                        Vector4 v = light.localToWorldMatrix.GetColumn(2);
                        v.x = -v.x;
                        v.y = -v.y;
                        v.z = -v.z;
                        visibleLightSpotDirections[i] = v;

                        //计算lwpl里面的聚光灯的innerCos和outerCos
                        float outerRad = Mathf.Deg2Rad * 0.5f * light.spotAngle;
                        float outerCos = Mathf.Cos(outerRad);
                        float outerTan = Mathf.Tan(outerRad);
                        float innerCos = Mathf.Cos(Mathf.Atan((46 / 64f) * outerTan));
                        //lwpl的衰减定义是

                        /*
                         *  (Ds * Dl)a + b
                         *  a = 1/(cos(ri) - cos(ro)
                         *  b = -cos(ro)a
                         *
                         *  cos(ri)是innerCos, cos(ro)是outerCos
                         *  Ds * Dl是聚光灯朝向和灯光方向的点乘
                         */
                        float anleRange = Mathf.Max(innerCos - outerCos, 0.001f);
                        attenuation.z = 1f / anleRange;
                        attenuation.w = -outerCos * attenuation.z;

                        shadow = ConfigureShadows(i, light.light);
                    }
                }
                visibleLightAttenuations[i] = attenuation;
                shadowData[i] = shadow;
            }

            //排除多余的light
            if (mainLightExists || culling.visibleLights.Length > maxVisibleLights)
            {
                NativeArray <int> lightIndices = culling.GetLightIndexMap(Allocator.Temp);
                if (mainLightExists)
                {
                    lightIndices[0] = -1;
                }

                for (int i = maxVisibleLights; i < culling.visibleLights.Length; ++i)
                {
                    lightIndices[i] = -1;
                }

                culling.SetLightIndexMap(lightIndices);
            }
        }
Example #12
0
    void ConfigureLights()
    {
        mainLightExists = false;
        shadowTileCount = 0;
        bool shadowmaskExists = false;

        for (int i = 0; i < cull.visibleLights.Length; i++)
        {
            if (i == maxVisibleLights)
            {
                break;
            }

            VisibleLight light = cull.visibleLights[i];
            visibleLightColors[i] = light.finalColor;
            Vector4 attenuation = Vector4.zero;
            attenuation.w = 1f;
            Vector4 shadow = Vector4.zero;

            // shadowmask ?
            LightBakingOutput baking = light.light.bakingOutput;
            visibleLightOcclusionMasks[i] = occlusionMasks[baking.occlusionMaskChannel + 1];
            if (baking.lightmapBakeType == LightmapBakeType.Mixed)
            {
                shadowmaskExists |= baking.mixedLightingMode == MixedLightingMode.Shadowmask;
            }

            if (light.lightType == LightType.Directional)
            {
                Vector4 v = light.localToWorldMatrix.GetColumn(2);
                v.x = -v.x;
                v.y = -v.y;
                v.z = -v.z;
                visibleLightDirectionsOrPositions[i] = v;
                shadow   = ConfigureShadows(i, light.light);
                shadow.z = 1f;// flag
                if (i == 0 && shadow.x > 0f && shadowCascades > 0)
                {
                    mainLightExists  = true;
                    shadowTileCount -= 1;
                }
            }
            else
            {
                visibleLightDirectionsOrPositions[i] = light.localToWorldMatrix.GetColumn(3);
                attenuation.x = 1f / Mathf.Max(light.range * light.range, 0.00001f);
                if (light.lightType == LightType.Spot)
                {
                    Vector4 v = light.localToWorldMatrix.GetColumn(2);
                    v.x = -v.x;
                    v.y = -v.y;
                    v.z = -v.z;
                    visibleLightSpotDirections[i] = v;

                    float outerRad   = Mathf.Deg2Rad * 0.5f * light.spotAngle;
                    float outerCos   = Mathf.Cos(outerRad);
                    float outerTan   = Mathf.Tan(outerRad);
                    float innerCos   = Mathf.Cos(Mathf.Atan((46f / 64f) * outerTan));
                    float angleRange = Mathf.Max(innerCos - outerCos, 0.001f);
                    attenuation.z = 1f / angleRange;
                    attenuation.w = -outerCos * attenuation.z;
                    shadow        = ConfigureShadows(i, light.light);
                }
                else
                {
                    visibleLightSpotDirections[i] = Vector4.one;
                }
            }

            visibleLightAttenuations[i] = attenuation;
            shadowData[i] = shadow;
        }

        // shadowmask
        bool useDistanceShadowmask = QualitySettings.shadowmaskMode == ShadowmaskMode.DistanceShadowmask;

        CoreUtils.SetKeyword(cameraBuffer, shadowmaskKeyword, shadowmaskExists && !useDistanceShadowmask);
        CoreUtils.SetKeyword(cameraBuffer, distanceShadowmaskKeyword, shadowmaskExists && useDistanceShadowmask);

        if (mainLightExists || cull.visibleLights.Length > maxVisibleLights)
        {
            NativeArray <int> lightIndices = cull.GetLightIndexMap(Allocator.Temp);
            if (mainLightExists)
            {
                lightIndices[0] = -1;
            }
            for (int i = maxVisibleLights; i < cull.visibleLights.Length; i++)
            {
                lightIndices[i] = -1;
            }
            cull.SetLightIndexMap(lightIndices);
        }
    }
Example #13
0
    void SetupLights(bool useLightsPerObject, int renderingLayerMask)
    {
        NativeArray <int>          indexMap = useLightsPerObject ? cullingResults.GetLightIndexMap(Allocator.Temp) : default;
        NativeArray <VisibleLight> visibleLights = cullingResults.visibleLights;
        int dirLightCount = 0, otherLightCount = 0;
        int i;

        for (i = 0; i < visibleLights.Length; i++)
        {
            int          newIndex     = -1;
            VisibleLight visibleLight = visibleLights[i];
            Light        light        = visibleLight.light;
            if ((light.renderingLayerMask & renderingLayerMask) != 0)
            {
                switch (visibleLight.lightType)
                {
                case LightType.Directional:
                    if (dirLightCount < maxDirLightCount)
                    {
                        SetupDirectionalLight(dirLightCount++, i, ref visibleLight, light);
                    }
                    break;

                case LightType.Point:
                    if (otherLightCount < maxOtherLightCount)
                    {
                        newIndex = otherLightCount;
                        SetupPointLight(otherLightCount++, i, ref visibleLight, light);
                    }
                    break;

                case LightType.Spot:
                    if (otherLightCount < maxOtherLightCount)
                    {
                        newIndex = otherLightCount;
                        SetupSpotLight(otherLightCount++, i, ref visibleLight, light);
                    }
                    break;
                }
            }
            if (useLightsPerObject)
            {
                indexMap[i] = newIndex;
            }
        }

        if (useLightsPerObject)
        {
            for (; i < indexMap.Length; i++)
            {
                indexMap[i] = -1;
            }
            cullingResults.SetLightIndexMap(indexMap);
            indexMap.Dispose();
            Shader.EnableKeyword(lightsPerObjectKeyword);
        }
        else
        {
            Shader.DisableKeyword(lightsPerObjectKeyword);
        }

        buffer.SetGlobalInt(dirLightCountId, dirLightCount);
        if (dirLightCount > 0)
        {
            buffer.SetGlobalVectorArray(dirLightColorsId, dirLightColors);
            buffer.SetGlobalVectorArray(dirLightDirectionsId, dirLightDirectionsAndMasks);
            buffer.SetGlobalVectorArray(dirLightShadowDataId, dirLightShadowData);
        }

        buffer.SetGlobalInt(otherLightCountId, otherLightCount);
        if (otherLightCount > 0)
        {
            buffer.SetGlobalVectorArray(otherLightColorsId, otherLightColors);
            buffer.SetGlobalVectorArray(otherLightPositionsId, otherLightPositions);
            buffer.SetGlobalVectorArray(otherLightDirectionsId, otherLightDirectionsAndMasks);
            buffer.SetGlobalVectorArray(otherLightSpotAnglesId, otherLightSpotAngles);
            buffer.SetGlobalVectorArray(otherLightShadowDataId, otherLightShadowData);
        }
    }
Example #14
0
    private void Render(ScriptableRenderContext context, Camera camera)
    {
        BeginCameraRendering(camera);
        ScriptableCullingParameters parameters;

        if (!camera.TryGetCullingParameters(out parameters))
        {
            return;
        }
        CullingResults cullingResults = context.Cull(ref parameters);

        context.SetupCameraProperties(camera);


        cameraBuffer.Clear();
        cameraBuffer.ClearRenderTarget((camera.clearFlags & CameraClearFlags.Depth) != 0, (camera.clearFlags & CameraClearFlags.Color) != 0, camera.backgroundColor);
        context.ExecuteCommandBuffer(cameraBuffer);

        //init

        FilteringSettings filteringSettings = new FilteringSettings(RenderQueueRange.all);
        SortingSettings   sortingSettings   = new SortingSettings();
        DrawingSettings   drawingSettings   = new DrawingSettings(m_ShaderTagId, sortingSettings);

        RenderShawder(context);

        //  cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives();


        //drawSkybox
        context.DrawSkybox(camera);

        #region light
        var lightcount = Mathf.Min(cullingResults.visibleLights.Length, MAX_VISABLE_COUNT);
        LightColors         = new Vector4[MAX_VISABLE_COUNT];
        LightDirections     = new Vector4[MAX_VISABLE_COUNT];
        LightAttenuations   = new Vector4[MAX_VISABLE_COUNT];
        LightSpotDirections = new Vector4[MAX_VISABLE_COUNT];
        for (int i = 0; i < cullingResults.visibleLights.Length; i++)
        {
            if (i == MAX_VISABLE_COUNT)
            {
                break;
            }
            LightSpotDirections[i] = Vector4.zero;
            LightDirections[i]     = Vector4.zero;
            LightAttenuations[i]   = Vector4.zero;
            LightColors[i]         = Vector4.zero;
            var light = cullingResults.visibleLights[i];
            LightSpotDirections[i] = Vector4.zero;
            LightAttenuations[i].w = 1f;
            if (light.lightType == LightType.Directional)
            {
                var v = light.localToWorldMatrix.GetColumn(2);
                v.x = -v.x;
                v.y = -v.y;
                v.z = -v.z;
                v.w = 0;//
                LightDirections[i] = v;
            }
            else
            {
                LightDirections[i]   = cullingResults.visibleLights[i].localToWorldMatrix.GetColumn(3);
                LightDirections[i].w = 1;

                //衰减 (1-(dir^2/range^2)^2)^2
                LightAttenuations[i].x = 1f / Mathf.Max(Mathf.Sqrt(light.range), 0.000001f);

                //spot fade (lightPos*lightDir)-cos(r_out)/cos(r_in)-cos(r_out)
                if (light.lightType == LightType.Spot)
                {
                    var dir = light.localToWorldMatrix.GetColumn(2);
                    dir.x = -dir.x;
                    dir.y = -dir.y;
                    dir.z = -dir.z;
                    LightSpotDirections[i] = dir;
                    var outerRad = Mathf.Deg2Rad * 0.5f * light.spotAngle;
                    var outerCos = Mathf.Cos(outerRad);
                    //tan(r_in) = 46/64*tan(r_out)
                    var outerTan = Mathf.Tan(outerRad);
                    var innerCos = Mathf.Cos(Mathf.Atan(23 / 32 * outerTan));
                    LightAttenuations[i].z = 1 / Mathf.Max(innerCos - outerCos, 0.0001f);
                    LightAttenuations[i].w = -outerCos * LightAttenuations[i].z;
                }
            }
            LightColors[i] = light.finalColor;
        }
        if (cullingResults.visibleLights.Length > MAX_VISABLE_COUNT)
        {
            NativeArray <int> lightMap = cullingResults.GetLightIndexMap(Allocator.Invalid);
            for (int i = MAX_VISABLE_COUNT; i < cullingResults.visibleLights.Length; i++)
            {
                lightMap[i] = -1;
            }
            cullingResults.SetLightIndexMap(lightMap);
            lightMap.Dispose();
        }
        cameraBuffer.Clear();
        cameraBuffer.SetGlobalVectorArray(_LightDirectionsID, LightDirections);
        cameraBuffer.SetGlobalVectorArray(_LightColorId, LightColors);
        cameraBuffer.SetGlobalVectorArray(_LightAttenuationID, LightAttenuations);
        cameraBuffer.SetGlobalVectorArray(_LightSpotDirectionID, LightSpotDirections);
        context.ExecuteCommandBuffer(cameraBuffer);
        #endregion
        //qaueue
        filteringSettings.renderQueueRange = RenderQueueRange.opaque;
        sortingSettings.criteria           = SortingCriteria.CommonOpaque;
        context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
        context.Submit();
        if (shadowMap)
        {
            RenderTexture.ReleaseTemporary(shadowMap);
            shadowMap = null;
        }
    }
Example #15
0
        static void SetupAdditionalLightConstants(CommandBuffer buffer, NativeArray <VisibleLight> visibleLights, int mainLightIndex, CullingResults cullingResults)
        {
            NativeArray <int> indexMap       = cullingResults.GetLightIndexMap(Allocator.Temp);
            int globalDirectionalLightsCount = 0;
            int additionalLightsCount        = 0;

            for (int i = 0; i < visibleLights.Length; i++)
            {
                if (additionalLightsCount >= maxVisibleAdditionalLights)
                {
                    break;
                }

                VisibleLight light = visibleLights[i];
                if (i == mainLightIndex)
                {
                    indexMap[i] = -1;
                    globalDirectionalLightsCount += 1;
                }
                else
                {
                    indexMap[i]           -= globalDirectionalLightsCount;
                    additionalLightsCount += 1;
                }
            }

            for (int i = globalDirectionalLightsCount + additionalLightsCount; i < indexMap.Length; i++)
            {
                indexMap[i] = -1;
            }

            cullingResults.SetLightIndexMap(indexMap);
            indexMap.Dispose();

            Vector4[] additionalLightPositions              = new Vector4[maxVisibleAdditionalLights];
            Vector4[] additionalLightColors                 = new Vector4[maxVisibleAdditionalLights];
            Vector4[] additionalLightAttenuations           = new Vector4[maxVisibleAdditionalLights];
            Vector4[] additionalLightSpotDirections         = new Vector4[maxVisibleAdditionalLights];
            Vector4[] additionalLightOcclusionProbeChannels = new Vector4[maxVisibleAdditionalLights];
            if (additionalLightsCount > 0)
            {
                for (int i = 0, lightIndex = 0; i < visibleLights.Length && lightIndex < maxVisibleAdditionalLights; i++)
                {
                    VisibleLight light = visibleLights[i];
                    if (mainLightIndex != i)
                    {
                        InitializeLightConstants(visibleLights, i, out additionalLightPositions[lightIndex], out additionalLightColors[lightIndex], out additionalLightAttenuations[lightIndex], out additionalLightSpotDirections[lightIndex], out additionalLightOcclusionProbeChannels[lightIndex]);
                        lightIndex += 1;
                    }
                }

                buffer.SetGlobalVectorArray(additionalLightsPositionId, additionalLightPositions);
                buffer.SetGlobalVectorArray(additionalLightsColorId, additionalLightColors);
                buffer.SetGlobalVectorArray(additionalLightsAttenuationId, additionalLightAttenuations);
                buffer.SetGlobalVectorArray(additionalLightsSpotDirId, additionalLightSpotDirections);
                buffer.SetGlobalVectorArray(additionalLightOcclusionProbeChannelId, additionalLightOcclusionProbeChannels);
                buffer.SetGlobalVector(additionalLightsCountId, new Vector4(maxPerObjectAdditionalLights, 0.0f, 0.0f, 0.0f));
            }
            else
            {
                buffer.SetGlobalVector(additionalLightsCountId, Vector4.zero);
            }
        }
Example #16
0
        private void ConfigureLights()
        {
            mainLightExists = false;
            bool shadowmaskExists    = false;
            bool subtractiveLighting = false;

            shadowTileCount = 0;
            for (int i = 0; i < cullingResults.visibleLights.Length; i++)
            {
                if (i == maxVisibleLights)
                {
                    break;
                }
                VisibleLight light = cullingResults.visibleLights[i];
                // finalColor字段存储了光源的颜色,该颜色数据是由光源的color属性和intensity属性相乘后的结果,并经过了颜色空间的校正。
                visibleLightColors[i] = light.finalColor;
                Vector4 attenuation = Vector4.zero;
                attenuation.w = 1f; // 为了保证不同类型的光照计算的一致性(用同样的shader代码),将w分量设置为1。
                Vector4 shadow = Vector4.zero;

                LightBakingOutput baking = light.light.bakingOutput;
                // 有四种可能的掩码,我们可以在静态数组(occlusionMasks)中预定义。
                // 但也有可能有些灯光不使用阴影遮罩。我们将通过将第一个遮罩组件设置为-1来指示这一点。
                // 如果灯光不使用阴影遮罩,则通道为-1,因此在检索预定义的 occlusionMasks 时+1。
                visibleLightOcclusionMasks[i] = occlusionMasks[baking.occlusionMaskChannel + 1];
                if (baking.lightmapBakeType == LightmapBakeType.Mixed)
                {
                    shadowmaskExists |= baking.mixedLightingMode == MixedLightingMode.Shadowmask; // 判读是否存在烘培阴影。
                    if (baking.mixedLightingMode == MixedLightingMode.Subtractive)
                    {
                        subtractiveLighting = true;
                        cameraBuffer.SetGlobalColor(subtractiveShadowColorId, UnityEngine.RenderSettings.subtractiveShadowColor.linear);
                    }
                }

                if (light.lightType == LightType.Directional)
                {
                    // 方向光的光源方向信息可以通过光源的旋转信息获得,光源的方向是它的z轴方向。
                    // 我们可以通过VisibleLight.localToWorldMatrix矩阵获取在世界坐标系中的该信息。这个矩阵的第三列定义了光源的本地Z轴方向。
                    Vector4 v = light.localToWorldMatrix.GetColumn(2);
                    // 在shader中我们使用从物体朝向光源的向量方向进行计算,所以将获得的光源方向进行取反操作。
                    v.x = -v.x;
                    v.y = -v.y;
                    v.z = -v.z;
                    visibleLightDirectionsOrPositions[i] = v;
                    // 设置阴影。
                    shadow   = ConfigureShadows(i, light.light);
                    shadow.z = 1f; // 用阴影数据的z分量来区分是方向光还是聚光灯。
                    if (i == 0 && shadow.x > 0f && ShadowCascades > 0)
                    {
                        mainLightExists = true;
                        // 我们会为主光源提供单独的渲染贴图,所以当我们拥有主光源时,让图块计数减1,
                        // 并且在RenderShadows函数中将其从常规阴影贴图渲染中排除。
                        shadowTileCount -= 1;
                    }
                }
                else if (light.lightType == LightType.Point || light.lightType == LightType.Spot)
                {
                    // 点光源不关心光的方向而关心光源的位置。这个矩阵的第四列定义了光源的世界位置。
                    visibleLightDirectionsOrPositions[i] = light.localToWorldMatrix.GetColumn(3);
                    attenuation.x = 1f / Mathf.Max(light.range * light.range, 0.00001f);
                    if (light.lightType == LightType.Spot)
                    {
                        // 聚光灯的光源方向。
                        Vector4 v = light.localToWorldMatrix.GetColumn(2);
                        v.x = -v.x;
                        v.y = -v.y;
                        v.z = -v.z;
                        visibleLightSpotDirections[i] = v;
                        // 聚光灯的衰减。
                        float outerRad   = Mathf.Deg2Rad * 0.5f * light.spotAngle;
                        float outerCos   = Mathf.Cos(outerRad);
                        float outerTan   = Mathf.Tan(outerRad);
                        float innerCos   = Mathf.Cos(Mathf.Atan(((46f / 64f) * outerTan)));
                        float angleRange = Mathf.Max(innerCos - outerCos, 0.001f);
                        attenuation.z = 1f / angleRange;
                        attenuation.w = -outerCos * attenuation.z;
                        // 设置阴影。
                        shadow = ConfigureShadows(i, light.light);
                    }
                    else
                    {
                        visibleLightSpotDirections[i] = Vector4.one;
                    }
                }
                // 填充点光源或聚光灯的光照范围。
                visibleLightAttenuations[i] = attenuation;
                shadowData[i] = shadow;
            }

            cameraBuffer.SetGlobalVectorArray(visibleLightColorsId, visibleLightColors);
            cameraBuffer.SetGlobalVectorArray(visibleLightDirectionsOrPositionsId, visibleLightDirectionsOrPositions);
            cameraBuffer.SetGlobalVectorArray(visibleLightAttenuationsId, visibleLightAttenuations);     // 点光源。
            cameraBuffer.SetGlobalVectorArray(visibleLightSpotDirectionsId, visibleLightSpotDirections); // 聚光灯。
            cameraBuffer.SetGlobalVectorArray(visibleLightOcclusionMasksId, visibleLightOcclusionMasks);

            // 尽管目前我们已经支持到场景中最多16个光源,但是依然无法避免有可能会存在更多光源的情况。
            // 当超出时,我们需要告诉Unity需要将一些光源舍弃以避免数组的越界。
            // 如果主光源存在,在渲染前将主光源移出可见光列表,以防止在shader中计算多次(会导致像素光数量上限变成5个)。
            if (mainLightExists || cullingResults.visibleLights.Length > maxVisibleLights)
            {
                var lightIndexs = cullingResults.GetLightIndexMap(Unity.Collections.Allocator.TempJob);
                if (mainLightExists)
                {
                    lightIndexs[0] = -1;
                }
                for (int i = maxVisibleLights; i < cullingResults.visibleLights.Length; i++)
                {
                    lightIndexs[i] = -1;
                }
                cullingResults.SetLightIndexMap(lightIndexs);
                lightIndexs.Dispose();
            }

            bool useDistanceShadowmask = QualitySettings.shadowmaskMode == ShadowmaskMode.DistanceShadowmask;

            CoreUtils.SetKeyword(cameraBuffer, shadowmaskKeyword, shadowmaskExists && !useDistanceShadowmask);
            CoreUtils.SetKeyword(cameraBuffer, distanceShadowmaskKeyword, shadowmaskExists && useDistanceShadowmask);
            CoreUtils.SetKeyword(cameraBuffer, subtractiveLightingKeyword, subtractiveLighting);
        }
    void ConfigureLights()
    {
        shadowTileCount = 0;
        for (int i = 0; i < _cullingResults.visibleLights.Length; i++)
        {
            if (i == maxVisibleLights)
            {
                break;
            }

            VisibleLight light = _cullingResults.visibleLights[i];
            visibleLightColors[i] = light.finalColor;
            Vector4 attenuation = Vector4.zero;
            attenuation.w = 1f;
            Vector4 shadow = Vector4.zero;

            if (light.lightType == LightType.Directional)
            {
                Vector4 v = light.localToWorldMatrix.GetColumn(2);
                v.x = -v.x;
                v.y = -v.y;
                v.z = -v.z;
                visibleLightDirectionsOrPositions[i] = v;
            }
            else
            {
                visibleLightDirectionsOrPositions[i] = light.localToWorldMatrix.GetColumn(3);
                attenuation.x = 1f / Mathf.Max(light.range * light.range, 0.00001f);

                if (light.lightType == LightType.Spot)
                {
                    Vector4 v = light.localToWorldMatrix.GetColumn(2);
                    v.x = -v.x;
                    v.y = -v.y;
                    v.z = -v.z;
                    visibleLightSpotDirections[i] = v;

                    float outerRad   = Mathf.Deg2Rad * 0.5f * light.spotAngle;
                    float outerCos   = Mathf.Cos(outerRad);
                    float outerTan   = Mathf.Tan(outerRad);
                    float innerCos   = Mathf.Cos(Mathf.Atan((46f / 64f) * outerTan));
                    float angleRange = Mathf.Max(innerCos - outerCos, 0.001f);
                    attenuation.z = 1f / angleRange;
                    attenuation.w = -outerCos * attenuation.z;

                    Light  shadowLight = light.light;
                    Bounds shadowBounds;
                    if (shadowLight.shadows != LightShadows.None &&
                        _cullingResults.GetShadowCasterBounds(i, out shadowBounds))
                    {
                        shadowTileCount += 1;
                        shadow.x         = shadowLight.shadowStrength;
                        shadow.y         = shadowLight.shadows == LightShadows.Soft ? 1f : 0f;
                    }
                }
            }

            visibleLightAttenuations[i] = attenuation;
            shadowData[i] = shadow;
        }

        if (_cullingResults.visibleLights.Length > maxVisibleLights)
        {
            var lightIndices = _cullingResults.GetLightIndexMap(Allocator.Temp);
            for (int i = maxVisibleLights; i < _cullingResults.visibleLights.Length; i++)
            {
                lightIndices[i] = -1;
            }

            _cullingResults.SetLightIndexMap(lightIndices);
        }
    }
Example #18
0
        public void SetupPerObjectLightIndices(ref CullingResults cullResults, ref LightData lightData)
        {
            if (lightData.additionalLightsCount == 0)
            {
                return;
            }

            var visibleLights          = lightData.visibleLights;
            var perObjectLightIndexMap = cullResults.GetLightIndexMap(Allocator.Temp);

            int directionalLightsCount = 0;
            int additionalLightsCount  = 0;

            // Disable all directional lights from the perobject light indices
            // Pipeline handles them globally.
            for (int i = 0; i < visibleLights.Length; ++i)
            {
                if (additionalLightsCount >= maxVisibleAdditionalLights)
                {
                    break;
                }

                VisibleLight light = visibleLights[i];
                if (light.lightType == LightType.Directional)
                {
                    perObjectLightIndexMap[i] = -1;
                    ++directionalLightsCount;
                }
                else
                {
                    perObjectLightIndexMap[i] -= directionalLightsCount;
                    ++additionalLightsCount;
                }
            }

            // Disable all remaining lights we cannot fit into the global light buffer.
            for (int i = directionalLightsCount + additionalLightsCount; i < visibleLights.Length; ++i)
            {
                perObjectLightIndexMap[i] = -1;
            }

            cullResults.SetLightIndexMap(perObjectLightIndexMap);
            perObjectLightIndexMap.Dispose();

            // if not using a compute buffer, engine will set indices in 2 vec4 constants
            // unity_4LightIndices0 and unity_4LightIndices1
            if (useStructuredBufferForLights)
            {
                int lightIndicesCount = cullResults.lightAndReflectionProbeIndexCount;
                if (lightIndicesCount > 0)
                {
                    if (perObjectLightIndices == null)
                    {
                        perObjectLightIndices = new ComputeBuffer(lightIndicesCount, sizeof(int));
                    }
                    else if (perObjectLightIndices.count < lightIndicesCount)
                    {
                        perObjectLightIndices.Release();
                        perObjectLightIndices = new ComputeBuffer(lightIndicesCount, sizeof(int));
                    }

                    cullResults.FillLightAndReflectionProbeIndices(perObjectLightIndices);
                }
            }
        }
        private void SetupLights(bool useLightsPerObject)
        {
            // lightIndexMap contains light indices, matching the visible light indices plus all other active lights in the scene (from catlike)
            // we only use lightIndexMap for point and spot light
            NativeArray <int>          lightIndexMap = useLightsPerObject ? cullingResults.GetLightIndexMap(Allocator.Temp) : default;
            NativeArray <VisibleLight> visibleLights = cullingResults.visibleLights;
            int directionalLightCount = 0;
            int otherLightCount       = 0;
            int i = 0;

            for (; i < visibleLights.Length; ++i)
            {
                int          newIndex     = -1;
                VisibleLight visibleLight = visibleLights[i];

                switch (visibleLight.lightType)
                {
                case LightType.Directional:
                {
                    if (directionalLightCount < maxDirectionalLightCount)
                    {
                        SetupDirectionalLight(directionalLightCount++, i, ref visibleLight);
                    }

                    break;
                }

                case LightType.Point:
                {
                    if (otherLightCount < maxOtherLightCount)
                    {
                        newIndex = otherLightCount;
                        SetupPointLight(otherLightCount++, i, ref visibleLight);
                    }

                    break;
                }

                case LightType.Spot:
                {
                    if (otherLightCount < maxOtherLightCount)
                    {
                        newIndex = otherLightCount;
                        SetupSpotLight(otherLightCount++, i, ref visibleLight);
                    }

                    break;
                }
                }

                if (useLightsPerObject)
                {
                    lightIndexMap[i] = newIndex;
                }
            }

            if (useLightsPerObject)
            {
                for (; i < lightIndexMap.Length; ++i)
                {
                    lightIndexMap[i] = -1;
                }
                //
                cullingResults.SetLightIndexMap(lightIndexMap);
                Shader.EnableKeyword(lightsPerObjectKeyword);
                lightIndexMap.Dispose();
            }

            else
            {
                Shader.DisableKeyword(lightsPerObjectKeyword);
            }

            // Light light = RenderSettings.sun;
            // commandBuffer.SetGlobalVector(directionalLightColorPropertyID, light.color.linear * light.intensity);
            // commandBuffer.SetGlobalVector(directionalLightDirectionPropertyID, -light.transform.forward);

            commandBuffer.SetGlobalInt(directionalLightCountPropertyID, directionalLightCount);

            if (directionalLightCount > 0)
            {
                commandBuffer.SetGlobalVectorArray(directionalLightColorsPropertyID, directionalLightColors);
                commandBuffer.SetGlobalVectorArray(directionalLightDirectionsPropertyID, directionalLightDirections);
                commandBuffer.SetGlobalVectorArray(directionalShadowInfosPropertyID, _DirectionalShadowInfos);
            }

            commandBuffer.SetGlobalInt(otherLightCountPropertyID, otherLightCount);

            if (otherLightCount > 0)
            {
                commandBuffer.SetGlobalVectorArray(otherLightColorsPropertyID, otherLightColors);
                commandBuffer.SetGlobalVectorArray(otherLightPositionsProoertyID, otherLightPositions);
                commandBuffer.SetGlobalVectorArray(otherLightDirectionsPropertyID, otherLightDirections);
                commandBuffer.SetGlobalVectorArray(otherLightSpotAnglesPropertyID, otherLightSpotAngles);
                commandBuffer.SetGlobalVectorArray(otherLightShadowDatasPropertyID, otherLightShadowDatas);
            }
        }