예제 #1
0
        public void SetupPerObjectLightIndices(ref CullResults cullResults, ref LightData lightData)
        {
            if (lightData.additionalLightsCount == 0)
            {
                return;
            }

            List <VisibleLight> visibleLights = lightData.visibleLights;

            int[] perObjectLightIndexMap = cullResults.GetLightIndexMap();

            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.Count; ++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.Count; ++i)
            {
                perObjectLightIndexMap[i] = -1;
            }

            cullResults.SetLightIndexMap(perObjectLightIndexMap);

            // if not using a compute buffer, engine will set indices in 2 vec4 constants
            // unity_4LightIndices0 and unity_4LightIndices1
            if (useStructuredBufferForLights)
            {
                int lightIndicesCount = cullResults.GetLightIndicesCount();
                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.FillLightIndices(perObjectLightIndices);
                }
            }
        }
예제 #2
0
        private void SetupShaderLightListConstants(VisibleLight[] lights, ref LightData lightData, ref ScriptableRenderContext context)
        {
            int maxLights = Math.Min(kMaxVisibleLights, lights.Length);

            for (int i = 0; i < maxLights; ++i)
            {
                VisibleLight currLight = lights [i];
                if (currLight.lightType == LightType.Directional)
                {
                    Vector4 dir = -currLight.localToWorld.GetColumn(2);
                    m_LightPositions [i] = new Vector4(dir.x, dir.y, dir.z, 0.0f);
                }
                else
                {
                    Vector4 pos = currLight.localToWorld.GetColumn(3);
                    m_LightPositions [i] = new Vector4(pos.x, pos.y, pos.z, 1.0f);
                }

                m_LightColors[i] = currLight.finalColor;

                float rangeSq   = currLight.range * currLight.range;
                float quadAtten = (currLight.lightType == LightType.Directional) ? 0.0f : 25.0f / rangeSq;

                if (currLight.lightType == LightType.Spot)
                {
                    Vector4 dir = currLight.localToWorld.GetColumn(2);
                    m_LightSpotDirections [i] = new Vector4(-dir.x, -dir.y, -dir.z, 0.0f);

                    float spotAngle     = Mathf.Deg2Rad * currLight.spotAngle;
                    float cosOuterAngle = Mathf.Cos(spotAngle * 0.5f);
                    float cosInneAngle  = Mathf.Cos(spotAngle * 0.25f);
                    float angleRange    = cosInneAngle - cosOuterAngle;
                    m_LightAttenuations [i] = new Vector4(cosOuterAngle,
                                                          Mathf.Approximately(angleRange, 0.0f) ? 1.0f : angleRange, quadAtten, rangeSq);
                }
                else
                {
                    m_LightSpotDirections [i] = new Vector4(0.0f, 0.0f, 1.0f, 0.0f);
                    m_LightAttenuations [i]   = new Vector4(-1.0f, 1.0f, quadAtten, rangeSq);
                }
            }

            // Lightweight pipeline only upload kMaxVisibleLights to shader cbuffer.
            // We tell the pipe to disable remaining lights by setting it to -1.
            int[] lightIndexMap = m_CullResults.GetLightIndexMap();
            for (int i = kMaxVisibleLights; i < lightIndexMap.Length; ++i)
            {
                lightIndexMap[i] = -1;
            }
            m_CullResults.SetLightIndexMap(lightIndexMap);

            CommandBuffer cmd = CommandBufferPool.Get("SetupShadowShaderConstants");

            cmd.SetGlobalVector("globalLightCount", new Vector4(lightData.pixelLightsCount, lightData.vertexLightsCount, 0.0f, 0.0f));
            cmd.SetGlobalVectorArray("globalLightPos", m_LightPositions);
            cmd.SetGlobalVectorArray("globalLightColor", m_LightColors);
            cmd.SetGlobalVectorArray("globalLightAtten", m_LightAttenuations);
            cmd.SetGlobalVectorArray("globalLightSpotDir", m_LightSpotDirections);
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
    void ConfigureLights()
    {
        mainLightExists = false;
        shadowTileCount = 0;
        for (int i = 0; i < cull.visibleLights.Count; 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.localToWorld.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;
                if (i == 0 && shadow.x > 0f && shadowCascades > 0)
                {
                    mainLightExists  = true;
                    shadowTileCount -= 1;
                }
            }
            else
            {
                visibleLightDirectionsOrPositions[i] =
                    light.localToWorld.GetColumn(3);
                attenuation.x = 1f /
                                Mathf.Max(light.range * light.range, 0.00001f);

                if (light.lightType == LightType.Spot)
                {
                    Vector4 v = light.localToWorld.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);
                }
            }

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

        if (mainLightExists || cull.visibleLights.Count > maxVisibleLights)
        {
            int[] lightIndices = cull.GetLightIndexMap();
            if (mainLightExists)
            {
                lightIndices[0] = -1;
            }
            for (int i = maxVisibleLights; i < cull.visibleLights.Count; i++)
            {
                lightIndices[i] = -1;
            }
            cull.SetLightIndexMap(lightIndices);
        }
    }
예제 #4
0
    void ConfigureLights()
    {
        mainLightExists = false;
        bool shadowmaskExists    = false;
        bool subtractiveLighting = false;

        shadowTileCount = 0;
        for (int i = 0; i < cull.visibleLights.Count; 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;

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

                if (baking.mixedLightingMode == MixedLightingMode.Subtractive)
                {
                    subtractiveLighting = true;
                    cameraBuffer.SetGlobalColor(
                        subtractiveShadowColorId,
                        RenderSettings.subtractiveShadowColor.linear
                        );
                }
            }

            if (light.lightType == LightType.Directional)
            {
                //因为要求出光源的朝向,相当于要知道光源transform.forward,矩阵第三列是光源z轴在世界坐标系下表示,也就是forward
                Vector4 v = light.localToWorld.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;

                if (i == 0 && shadow.x > 0f && shadowCascades > 0)
                {
                    mainLightExists  = true;
                    shadowTileCount -= 1;
                }
            }
            else
            {
                //第四列是光源原点在世界坐标系中的位置
                visibleLightDirectionsOrPositions[i] = light.localToWorld.GetColumn(3);
                attenuation.x = 1f / Mathf.Max(light.range * light.range, 0.00001f);

                if (light.lightType == LightType.Spot)
                {
                    Vector4 v = light.localToWorld.GetColumn(2);
                    v.x = -v.x;
                    v.y = -v.y;
                    v.z = -v.z;
                    //存储spot光源方向
                    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);

                    //Light shadowLight = light.light;
                    //Bounds shadowBounds;
                    //if (shadowLight.shadows != LightShadows.None && cull.GetShadowCasterBounds(i, out shadowBounds))
                    //{
                    //    shadowTileCount += 1;
                    //    shadow.x = shadowLight.shadowStrength;
                    //    shadow.y = shadowLight.shadows == LightShadows.Soft ? 1f : 0f;
                    //}
                }
                else
                {
                    visibleLightSpotDirections[i] = Vector4.one;
                }
            }
            visibleLightAttenuations[i] = attenuation;
            shadowData[i] = shadow;
        }

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

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

        //如果超过maxVisibleLights数量的灯光,该脚本不会传输给Shader
        //但是Unity自身可能会对超出maxVisibleLights的灯光,进行unity_4LightIndices0赋值,下标会找不到,_VisibleLightColors越界
        if (mainLightExists || cull.visibleLights.Count > maxVisibleLights)
        {
            int[] lightIndices = cull.GetLightIndexMap();
            if (mainLightExists)
            {
                lightIndices[0] = -1;
            }
            for (int i = maxVisibleLights; i < cull.visibleLights.Count; i++)
            {
                lightIndices[i] = -1;
            }
            cull.SetLightIndexMap(lightIndices);
        }
    }
예제 #5
0
    void ConfigureLights()
    {
        mainLightExists = false;
        bool shadowmaskExists    = false;
        bool subtractiveLighting = false;

        shadowTileCount = 0;

        for (int i = 0; i < cull.visibleLights.Count; i++)
        {
            if (i == maxVisibleLights)
            {
                break;
            }
            VisibleLight light = cull.visibleLights[i];
            visibleLightColors[i] = light.finalColor;

            Vector4 attenuation = Vector4.zero;
            attenuation.w = 1f;   //if no spot light, factor =1

            Vector4 shadow = Vector4.zero;

            //shadowmask settings
            LightBakingOutput baking = light.light.bakingOutput;
            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,
                        RenderSettings.subtractiveShadowColor.linear
                        );
                }
            }


            //light settings
            if (light.lightType == LightType.Directional)
            {
                Vector4 v = light.localToWorld.GetColumn(2);
                v.x = -v.x;
                v.y = -v.y;
                v.z = -v.z;  //change to vector surfaceToLight
                visibleLightDirectionsOrPositions[i] = v;

                shadow   = ConfigureShadows(i, light.light);
                shadow.z = 1f;

                //directional light index =0, cast shadow, use cascades
                if (i == 0 && shadow.x > 0f && shadowCascades > 0)
                {
                    mainLightExists  = true;
                    shadowTileCount -= 1;   //cascaded shadow map is not included in tiled shadow map
                }
            }
            else
            {
                visibleLightDirectionsOrPositions[i] = light.localToWorld.GetColumn(3);
                attenuation.x = 1f /
                                Mathf.Max(light.range * light.range, 0.00001f);

                if (light.lightType == LightType.Spot)
                {
                    Vector4 v = light.localToWorld.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;

                    //buffer shadowData
                    shadow = ConfigureShadows(i, light.light);
                }
                else
                {
                    //indicator of pointlight
                    visibleLightSpotDirections[i] = Vector4.one;
                }
            }

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

        //number of lights exceeds upper limit
        if (mainLightExists || cull.visibleLights.Count > maxVisibleLights)
        {
            int[] lightIndices = cull.GetLightIndexMap();
            if (mainLightExists)
            {
                //remove main light from diffuseLight render, avoid a second render
                lightIndices[0] = -1;
            }
            for (int i = maxVisibleLights; i < cull.visibleLights.Count; i++)
            {
                lightIndices[i] = -1;
            }
            cull.SetLightIndexMap(lightIndices);
        }

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

        //enable shadowmask keyword
        CoreUtils.SetKeyword(cameraBuffer, shadowmaskKeyword,
                             shadowmaskExists && !useDistanceShadowmask); //if use shadowmask mode
        CoreUtils.SetKeyword(cameraBuffer, distanceShadowmaskKeyword,
                             shadowmaskExists && useDistanceShadowmask);  //if use distance shadowmask
        CoreUtils.SetKeyword(cameraBuffer, subtractiveLightingKeyword,
                             subtractiveLighting);
    }
예제 #6
0
    // 计算光数据
    void ConfigureLights()
    {
        mainLightExists = false;

        shadowTileCount = 0;

        for (int i = 0; i < cull.visibleLights.Count; i++)
        {
            // 其他光被抛弃
            if (i == maxVisibleLights)
            {
                break;
            }

            VisibleLight light = cull.visibleLights[i];

            // finalColor是光的颜色和亮度的乘积,并且已经被转换到正确的颜色空间
            visibleLightColors[i] = light.finalColor;

            // 点光和聚光的边界衰减
            Vector4 attenuation = Vector4.zero;

            // 保证计算聚光灯的边界衰减不会影响其他类型的灯
            attenuation.w = 1f;

            Vector4 shadow = Vector4.zero;

            if (light.lightType == LightType.Directional)
            {
                // 获取光线方向
                Vector4 v = light.localToWorld.GetColumn(2);
                // shader中使用视点到光的方向,因此需要取反,w为0,不需要取反
                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;

                    // 层级阴影使用另一张阴影纹理
                    shadowTileCount -= 1;
                }
            }
            else
            {
                // 获取光的位置
                visibleLightDirectionsOrPositions[i] = light.localToWorld.GetColumn(3);

                // 计算点光的边界衰减数据,放在attenuation的x分量中
                attenuation.x = 1f / Mathf.Max(light.range * light.range, 0.00001f);

                // 如果是聚光灯
                if (light.lightType == LightType.Spot)
                {
                    // 设定方向
                    Vector4 v = light.localToWorld.GetColumn(2);
                    v.x = -v.x;
                    v.y = -v.y;
                    v.z = -v.z;
                    visibleLightSpotDirections[i] = v;

                    // 计算聚光的边界衰减数据,并放在attenuation的z和w分量中
                    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);
                }
            }

            visibleLightAttenuations[i] = attenuation;

            shadowData[i] = shadow;
        }

        // 如果光的数量超过maxVisibleLights,将超过的灯光的索引剔除掉
        if (mainLightExists || cull.visibleLights.Count > maxVisibleLights)
        {
            // 获取光索引数组
            int[] lightIndices = cull.GetLightIndexMap();

            if (mainLightExists)
            {
                // 将主光剔除掉,否则主光会被渲染两次
                // 这也意味着每个物体支持的像素光的数量变为5
                lightIndices[0] = -1;
            }

            for (int i = maxVisibleLights; i < cull.visibleLights.Count; i++)
            {
                // 索引为-1的光会被剔除掉
                lightIndices[i] = -1;
            }
            // 设置光索引数组
            cull.SetLightIndexMap(lightIndices);
        }
    }
예제 #7
0
    void ConfigureLights()
    {
        shadowTileCount = 0;

        for (int i = 0; i < cull.visibleLights.Count; i++)
        {
            if (i == maxVisibleLights)
            {
                break;
            }
            VisibleLight light = cull.visibleLights[i];
            visibleLightColors[i] = light.finalColor;

            Vector4 attenuation = Vector4.zero;
            attenuation.w = 1f;   //if no spot light, factor =1

            Vector4 shadow = Vector4.zero;

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

                if (light.lightType == LightType.Spot)
                {
                    Vector4 v = light.localToWorld.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;

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

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

        //number of lights exceeds upper limit
        if (cull.visibleLights.Count > maxVisibleLights)
        {
            int[] lightIndices = cull.GetLightIndexMap();
            for (int i = maxVisibleLights; i < cull.visibleLights.Count; i++)
            {
                lightIndices[i] = -1;
            }
            cull.SetLightIndexMap(lightIndices);
        }
    }
예제 #8
0
    void ConfigureLights()
    {
        mainLightExists = false;
        bool shadowmaskExists    = false;
        bool subtractiveLighting = false;

        shadowTileCount = 0;
        for (int i = 0; i < cull.visibleLights.Count; 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;

            LightBakingOutput baking = light.light.bakingOutput;
            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,
                        RenderSettings.subtractiveShadowColor.linear
                        );
                }
            }

            if (light.lightType == LightType.Directional)
            {
                Vector4 v = light.localToWorld.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;
                if (i == 0 && shadow.x > 0f && shadowCascades > 0)
                {
                    mainLightExists  = true;
                    shadowTileCount -= 1;
                }
            }
            else
            {
                visibleLightDirectionsOrPositions[i] =
                    light.localToWorld.GetColumn(3);
                attenuation.x = 1f /
                                Mathf.Max(light.range * light.range, 0.00001f);

                if (light.lightType == LightType.Spot)
                {
                    Vector4 v = light.localToWorld.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;
        }

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

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

        if (mainLightExists || cull.visibleLights.Count > maxVisibleLights)
        {
            int[] lightIndices = cull.GetLightIndexMap();
            if (mainLightExists)
            {
                lightIndices[0] = -1;
            }
            for (int i = maxVisibleLights; i < cull.visibleLights.Count; i++)
            {
                lightIndices[i] = -1;
            }
            cull.SetLightIndexMap(lightIndices);
        }
    }
예제 #9
0
    void ConfigureLights()
    {
        mainLightExists = false;
        shadowTileCount = 0;

        for (int i = 0; i < cull.visibleLights.Count; i++)
        {
            if (i == maxVisibleLights)
            {
                break;
            }
            VisibleLight light = cull.visibleLights[i];
            visibleLightColors[i] = light.finalColor;

            Vector4 attenuation = Vector4.zero;
            attenuation.w = 1f;   //if no spot light, factor =1

            Vector4 shadow = Vector4.zero;

            if (light.lightType == LightType.Directional)
            {
                Vector4 v = light.localToWorld.GetColumn(2);
                v.x = -v.x;
                v.y = -v.y;
                v.z = -v.z;  //change to vector surfaceToLight
                visibleLightDirectionsOrPositions[i] = v;

                shadow   = ConfigureShadows(i, light.light);
                shadow.z = 1f;

                //directional light index =0, cast shadow, use cascades
                if (i == 0 && shadow.x > 0f && shadowCascades > 0)
                {
                    mainLightExists  = true;
                    shadowTileCount -= 1;   //cascaded shadow map is not included in tiled shadow map
                }
            }
            else
            {
                visibleLightDirectionsOrPositions[i] = light.localToWorld.GetColumn(3);
                attenuation.x = 1f /
                                Mathf.Max(light.range * light.range, 0.00001f);

                if (light.lightType == LightType.Spot)
                {
                    Vector4 v = light.localToWorld.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;

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

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

        //number of lights exceeds upper limit
        if (mainLightExists || cull.visibleLights.Count > maxVisibleLights)
        {
            int[] lightIndices = cull.GetLightIndexMap();
            if (mainLightExists)
            {
                //remove main light from diffuseLight render, avoid a second render
                lightIndices[0] = -1;
            }
            for (int i = maxVisibleLights; i < cull.visibleLights.Count; i++)
            {
                lightIndices[i] = -1;
            }
            cull.SetLightIndexMap(lightIndices);
        }
    }
예제 #10
0
    //------------------------------------------------------------------------------
    private void ConfigureLights()
    {
        for (int i = 0; i < cullResults.visibleLights.Count; i++)
        {
            // might try to put more lights in the scene than supported in pipeline
            if (i == maxVisibleLights)
            {
                Debug.LogError("Attempting to use more lights in the scene than the renderer supports. Max supported lights: " + maxVisibleLights);
                break;
            }

            // set light color
            VisibleLight light = cullResults.visibleLights[i];
            visibleLightColors[i] = light.finalColor;

            // set light vector, attentuation, & spotdirection
            //   based on light type
            Vector4 a = Vector4.zero;
            a.w = 1.0f;
            if (light.lightType == LightType.Directional)
            {
                // 3rd column is z-axis of light, which is the direction it shines in
                Vector4 v = light.localToWorld.GetColumn(2);
                // negate so vector is pointing towards the light
                v.x = -v.x;
                v.y = -v.y;
                v.z = -v.z;
                visibleLightVectors[i] = v;
            }
            else
            {
                // 3rd column is position
                visibleLightVectors[i] = light.localToWorld.GetColumn(3);
                a.x = 1.0f / Mathf.Max(light.range * light.range, 0.00001f);

                // set direction & extra attentuation info if it's a spot light
                if (light.lightType == LightType.Spot)
                {
                    Vector4 v = light.localToWorld.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((46.0f / 64.0f) * outerTan));
                    float angleRange = Mathf.Max(innerCos - outerCos, 0.001f);
                    a.z = 1.0f / angleRange;
                    a.w = -outerCos * a.z;
                }
            }
            visibleLightAttenuations[i] = a;
        }

        // let unity know about unused lights so it doesn't write
        //   to out of bounds locations in light data
        if (cullResults.visibleLights.Count > maxVisibleLights)
        {
            // allocates new memory every frame, booo
            int[] lightIndices = cullResults.GetLightIndexMap();
            for (int i = maxVisibleLights; i < cullResults.visibleLights.Count; i++)
            {
                lightIndices[i] = -1;
            }
            cullResults.SetLightIndexMap(lightIndices);
        }
    }
예제 #11
0
    void ConfigureLights()
    {
        for (int i = 0; i < cull.visibleLights.Count; i++)
        {
            if (i == maxVisibleLights)
            {
                break;
            }
            VisibleLight light = cull.visibleLights[i];
            visibleLightColors[i] = light.finalColor;

            Vector4 attenuation = Vector4.zero;
            attenuation.w = 1f;   //if no spot light, factor =1

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

                if (light.lightType == LightType.Spot)
                {
                    Vector4 v = light.localToWorld.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;
        }

        //number of lights exceeds upper limit
        if (cull.visibleLights.Count > maxVisibleLights)
        {
            int[] lightIndices = cull.GetLightIndexMap();
            for (int i = maxVisibleLights; i < cull.visibleLights.Count; i++)
            {
                lightIndices[i] = -1;
            }
            cull.SetLightIndexMap(lightIndices);
        }
    }