void SetupMainLightConstants(CommandBuffer cmd, ref LightData lightData)
        {
            Vector4 lightPos, lightColor, lightAttenuation, lightSpotDir;

            InitializeLightConstants(lightData.visibleLights, lightData.mainLightIndex, out lightPos, out lightColor, out lightAttenuation, out lightSpotDir);

            cmd.SetGlobalVector(LightConstantBuffer._MainLightPosition, lightPos);
            cmd.SetGlobalVector(LightConstantBuffer._MainLightColor, lightColor);
        }
        void SetupShaderLightConstants(CommandBuffer cmd, ref LightData lightData)
        {
            // Clear to default all light constant data
            for (int i = 0; i < LightweightRenderPipeline.maxVisibleAdditionalLights; ++i)
            {
                InitializeLightConstants(lightData.visibleLights, -1, out m_AdditionalLightPositions[i],
                                         out m_AdditionalLightColors[i],
                                         out m_AdditionalLightAttenuations[i],
                                         out m_AdditionalLightSpotDirections[i]);
            }

            m_MixedLightingSetup = MixedLightingSetup.None;

            // Main light has an optimized shader path for main light. This will benefit games that only care about a single light.
            // Lightweight pipeline also supports only a single shadow light, if available it will be the main light.
            SetupMainLightConstants(cmd, ref lightData);
            SetupAdditionalLightConstants(cmd, ref lightData);
        }
        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();
        }
Esempio n. 4
0
        static void InitializeLightData(PipelineSettings settings, NativeArray <VisibleLight> visibleLights, int mainLightIndex, int maxAdditionalLights,
                                        int maxPerObjectAdditionalLights, out LightData lightData)
        {
            lightData.mainLightIndex = mainLightIndex;

            if (settings.additionalLightsRenderingMode != LightRenderingMode.Disabled)
            {
                lightData.additionalLightsCount =
                    Math.Min((mainLightIndex != -1) ? visibleLights.Length - 1 : visibleLights.Length,
                             maxAdditionalLights);
                lightData.maxPerObjectAdditionalLightsCount = Math.Min(settings.maxAdditionalLights, maxPerObjectAdditionalLights);
            }
            else
            {
                lightData.additionalLightsCount             = 0;
                lightData.maxPerObjectAdditionalLightsCount = 0;
            }

            lightData.shadeAdditionalLightsPerVertex = settings.additionalLightsRenderingMode == LightRenderingMode.PerVertex;
            lightData.visibleLights         = visibleLights;
            lightData.supportsMixedLighting = settings.mixedLightingSupported;
        }
        void SetupMainLightConstants(CommandBuffer cmd, ref LightData lightData)
        {
            LightCookie lightcookie;
            Vector4     lightPos, lightColor, lightAttenuation, lightSpotDir;

            InitializeLightConstants(lightData.visibleLights, lightData.mainLightIndex, out lightPos, out lightColor, out lightAttenuation, out lightSpotDir, out lightcookie);
            cmd.SetGlobalVector(LightConstantBuffer._MainLightPosition, lightPos);
            cmd.SetGlobalVector(LightConstantBuffer._MainLightColor, lightColor);
            if (lightcookie != null)
            {
                cmd.EnableShaderKeyword("_LIGHTCOOKIE");
                cmd.SetGlobalMatrix(LightConstantBuffer._MainLightLightMat, lightcookie.LightMat);
                cmd.SetGlobalFloat(LightConstantBuffer._MainLightCookieSize, lightcookie.CookieSize);
                cmd.SetGlobalTexture(LightConstantBuffer._MainlightCookie, lightcookie.Tex);
                cmd.SetGlobalFloat(LightConstantBuffer._MainLightCookieFalloff, lightcookie.Falloff);
                cmd.SetGlobalColor(LightConstantBuffer._MainLightCookieColor, lightcookie.cookieColor);
            }
            else
            {
                cmd.DisableShaderKeyword("_LIGHTCOOKIE");
            }
        }
        void SetupMainLightConstants(CommandBuffer cmd, ref RenderingData renderingData)
        {
            LightData   lightData = renderingData.lightData;
            LightCookie lightcookie;
            Vector4     lightPos, lightColor, lightAttenuation, lightSpotDir;

            InitializeLightConstants(lightData.visibleLights, lightData.mainLightIndex, out lightPos, out lightColor, out lightAttenuation, out lightSpotDir, out lightcookie);
            cmd.SetGlobalVector(LightConstantBuffer._MainLightPosition, lightPos);
            cmd.SetGlobalVector(LightConstantBuffer._MainLightColor, lightColor);

            Camera    cam            = renderingData.cameraData.camera;
            Matrix4x4 projMatrix     = GL.GetGPUProjectionMatrix(cam.projectionMatrix, false);
            Matrix4x4 viewMatrix     = cam.worldToCameraMatrix;
            Matrix4x4 viewProjMatrix = projMatrix * viewMatrix;
            Vector4   input          = new Vector4(lightcookie.LightDir.x, lightcookie.LightDir.y, lightcookie.LightDir.z, 0.0f);
            Vector4   vpCoord        = viewProjMatrix * input;
            float     slope          = vpCoord.y / vpCoord.x;

            //Debug.Log("Dir: "+lightcookie.LightDir + " viewCood:" + viewCood + " vpCoord " + vpCoord + " slope:" + slope);
            cmd.SetGlobalMatrix(LightConstantBuffer._MainLightLightMat, lightcookie.LightMat);
            cmd.SetGlobalFloat(LightConstantBuffer._MainLightSlope, slope);
        }
        void SetupAdditionalLightConstants(CommandBuffer cmd, ref LightData lightData)
        {
            int maxVisibleAdditionalLights = LightweightRenderPipeline.maxVisibleAdditionalLights;
            var lights = lightData.visibleLights;

            if (lightData.additionalLightsCount > 0)
            {
                int additionalLightsCount = 0;
                for (int i = 0; i < lights.Length && additionalLightsCount < maxVisibleAdditionalLights; ++i)
                {
                    VisibleLight light = lights[i];
                    if (light.lightType != LightType.Directional)
                    {
                        InitializeLightConstants(lights, i, out m_AdditionalLightPositions[additionalLightsCount],
                                                 out m_AdditionalLightColors[additionalLightsCount],
                                                 out m_AdditionalLightAttenuations[additionalLightsCount],
                                                 out m_AdditionalLightSpotDirections[additionalLightsCount],
                                                 out m_AdditionalLightOcclusionProbeChannels[additionalLightsCount]);
                        additionalLightsCount++;
                    }
                }

                cmd.SetGlobalVector(LightConstantBuffer._AdditionalLightsCount, new Vector4(lightData.maxPerObjectAdditionalLightsCount,
                                                                                            0.0f, 0.0f, 0.0f));
            }
            else
            {
                cmd.SetGlobalVector(LightConstantBuffer._AdditionalLightsCount, Vector4.zero);
            }

            cmd.SetGlobalVectorArray(LightConstantBuffer._AdditionalLightsPosition, m_AdditionalLightPositions);
            cmd.SetGlobalVectorArray(LightConstantBuffer._AdditionalLightsColor, m_AdditionalLightColors);
            cmd.SetGlobalVectorArray(LightConstantBuffer._AdditionalLightsAttenuation, m_AdditionalLightAttenuations);
            cmd.SetGlobalVectorArray(LightConstantBuffer._AdditionalLightsSpotDir, m_AdditionalLightSpotDirections);
            cmd.SetGlobalVectorArray(LightConstantBuffer._AdditionalLightOcclusionProbeChannel, m_AdditionalLightOcclusionProbeChannels);
        }
Esempio n. 8
0
        void RenderMainLightCascadeShadowmap(ref ScriptableRenderContext context, ref CullingResults cullResults, ref LightData lightData, ref ShadowData shadowData)
        {
            int shadowLightIndex = lightData.mainLightIndex;

            if (shadowLightIndex == -1)
            {
                return;
            }

            VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex];

            CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag);

            using (new ProfilingSample(cmd, m_ProfilerTag))
            {
                var settings = new ShadowDrawingSettings(cullResults, shadowLightIndex);

                for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
                {
                    var splitData = settings.splitData;
                    splitData.cullingSphere = m_CascadeSplitDistances[cascadeIndex];
                    settings.splitData      = splitData;
                    Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, ref shadowData, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].resolution);
                    ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);
                    ShadowUtils.RenderShadowSlice(cmd, ref context, ref m_CascadeSlices[cascadeIndex],
                                                  ref settings, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].viewMatrix);
                }

                SetupMainLightShadowReceiverConstants(cmd, ref shadowData, shadowLight);
            }

            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadows, true);
            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowCascades, shadowData.mainLightShadowCascadesCount > 1);
            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, shadowLight.light.shadows == LightShadows.Soft && shadowData.supportsSoftShadows);
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }
        void RenderAdditionalShadowmapAtlas(ref ScriptableRenderContext context, ref CullingResults cullResults, ref LightData lightData, ref ShadowData shadowData)
        {
            NativeArray <VisibleLight> visibleLights = lightData.visibleLights;

            bool          additionalLightHasSoftShadows = false;
            CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag);

            using (new ProfilingSample(cmd, m_ProfilerTag))
            {
                for (int i = 0; i < m_AdditionalShadowCastingLightIndices.Count; ++i)
                {
                    int          shadowLightIndex = m_AdditionalShadowCastingLightIndices[i];
                    VisibleLight shadowLight      = visibleLights[shadowLightIndex];

                    if (m_AdditionalShadowCastingLightIndices.Count > 1)
                    {
                        ShadowUtils.ApplySliceTransform(ref m_AdditionalLightSlices[i], m_ShadowmapWidth, m_ShadowmapHeight);
                    }

                    var     settings   = new ShadowDrawingSettings(cullResults, shadowLightIndex);
                    Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex,
                                                                   ref shadowData, m_AdditionalLightSlices[i].projectionMatrix, m_AdditionalLightSlices[i].resolution);
                    ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);
                    ShadowUtils.RenderShadowSlice(cmd, ref context, ref m_AdditionalLightSlices[i], ref settings, m_AdditionalLightSlices[i].projectionMatrix, m_AdditionalLightSlices[i].viewMatrix);
                    additionalLightHasSoftShadows |= shadowLight.light.shadows == LightShadows.Soft;
                }

                SetupAdditionalLightsShadowReceiverConstants(cmd, ref shadowData);
            }

            // We share soft shadow settings for main light and additional lights to save keywords.
            // So we check here if pipeline supports soft shadows and either main light or any additional light has soft shadows
            // to enable the keyword.
            // TODO: In PC and Consoles we can upload shadow data per light and branch on shader. That will be more likely way faster.
            bool mainLightHasSoftShadows = shadowData.supportsMainLightShadows &&
                                           lightData.mainLightIndex != -1 &&
                                           visibleLights[lightData.mainLightIndex].light.shadows == LightShadows.Soft;

            bool softShadows = shadowData.supportsSoftShadows && (mainLightHasSoftShadows || additionalLightHasSoftShadows);

            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.AdditionalLightShadows, true);
            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, softShadows);
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }