Esempio n. 1
0
        public void ReserveShadows(Camera camera, HDShadowManager shadowManager, HDShadowInitParameters initParameters, CullResults cullResults, FrameSettings frameSettings, int lightIndex)
        {
            Bounds bounds;

            m_WillRenderShadows  = m_Light.shadows != LightShadows.None && frameSettings.enableShadow;
            m_WillRenderShadows &= cullResults.GetShadowCasterBounds(lightIndex, out bounds);
            // When creating a new light, at the first frame, there is no AdditionalShadowData so we can't really render shadows
            m_WillRenderShadows &= m_ShadowData != null && m_ShadowData.shadowDimmer > 0;

            if (!m_WillRenderShadows)
            {
                return;
            }

            // Create shadow requests array using the light type
            if (shadowRequests == null || m_ShadowRequestIndices == null)
            {
                const int maxLightShadowRequestsCount = 6;
                shadowRequests         = new HDShadowRequest[maxLightShadowRequestsCount];
                m_ShadowRequestIndices = new int[maxLightShadowRequestsCount];

                for (int i = 0; i < maxLightShadowRequestsCount; i++)
                {
                    shadowRequests[i] = new HDShadowRequest();
                }
            }

            Vector2 viewportSize = new Vector2(m_ShadowData.shadowResolution, m_ShadowData.shadowResolution);

            // Compute dynamic shadow resolution
            if (initParameters.useDynamicViewportRescale && m_Light.type != LightType.Directional)
            {
                // resize viewport size by the normalized size of the light on screen
                // When we will have access to the non screen clamped bounding sphere light size, we could use it to scale the shadow map resolution
                // For the moment, this will be enough
                viewportSize *= Mathf.Lerp(64f / viewportSize.x, 1f, m_Light.range / (camera.transform.position - transform.position).magnitude);
                viewportSize  = Vector2.Max(new Vector2(64f, 64f) / viewportSize, viewportSize);

                // Prevent flickering caused by the floating size of the viewport
                viewportSize.x = Mathf.Round(viewportSize.x);
                viewportSize.y = Mathf.Round(viewportSize.y);
            }

            viewportSize = Vector2.Max(viewportSize, new Vector2(16, 16));

            // Update the directional shadow atlas size
            if (m_Light.type == LightType.Directional)
            {
                shadowManager.UpdateDirectionalShadowResolution((int)viewportSize.x, m_ShadowSettings.cascadeShadowSplitCount);
            }

            // Reserver wanted resolution in the shadow atlas
            bool allowResize = m_Light.type != LightType.Directional;
            int  count       = GetShadowRequestCount();

            for (int index = 0; index < count; index++)
            {
                m_ShadowRequestIndices[index] = shadowManager.ReserveShadowResolutions(viewportSize, allowResize);
            }
        }
        public void ReserveShadows(Camera camera, HDShadowManager shadowManager, HDShadowInitParameters initParameters, CullingResults cullResults, FrameSettings frameSettings, int lightIndex)
        {
            Bounds bounds;
            float  cameraDistance = Vector3.Distance(camera.transform.position, transform.position);

            m_WillRenderShadows = legacyLight.shadows != LightShadows.None && frameSettings.IsEnabled(FrameSettingsField.Shadow);

            m_WillRenderShadows &= cullResults.GetShadowCasterBounds(lightIndex, out bounds);
            // When creating a new light, at the first frame, there is no AdditionalShadowData so we can't really render shadows
            m_WillRenderShadows &= m_ShadowData != null && m_ShadowData.shadowDimmer > 0;
            // If the shadow is too far away, we don't render it
            if (m_ShadowData != null)
            {
                m_WillRenderShadows &= legacyLight.type == LightType.Directional || cameraDistance < (m_ShadowData.shadowFadeDistance);
            }

#if ENABLE_RAYTRACING
            m_WillRenderShadows &= !(lightTypeExtent == LightTypeExtent.Rectangle && useRayTracedShadows);
#endif

            if (!m_WillRenderShadows)
            {
                return;
            }

            // Create shadow requests array using the light type
            if (shadowRequests == null || m_ShadowRequestIndices == null)
            {
                const int maxLightShadowRequestsCount = 6;
                shadowRequests         = new HDShadowRequest[maxLightShadowRequestsCount];
                m_ShadowRequestIndices = new int[maxLightShadowRequestsCount];

                for (int i = 0; i < maxLightShadowRequestsCount; i++)
                {
                    shadowRequests[i] = new HDShadowRequest();
                }
            }

            Vector2 viewportSize = new Vector2(m_ShadowData.shadowResolution, m_ShadowData.shadowResolution);

            // Reserver wanted resolution in the shadow atlas
            ShadowMapType shadowMapType = (lightTypeExtent == LightTypeExtent.Rectangle) ? ShadowMapType.AreaLightAtlas :
                                          (legacyLight.type != LightType.Directional) ? ShadowMapType.PunctualAtlas : ShadowMapType.CascadedDirectional;

            bool viewPortRescaling = false;
            // Compute dynamic shadow resolution

            viewPortRescaling |= (shadowMapType == ShadowMapType.PunctualAtlas && initParameters.punctualLightShadowAtlas.useDynamicViewportRescale);
            viewPortRescaling |= (shadowMapType == ShadowMapType.AreaLightAtlas && initParameters.areaLightShadowAtlas.useDynamicViewportRescale);

            if (viewPortRescaling)
            {
                // resize viewport size by the normalized size of the light on screen
                // When we will have access to the non screen clamped bounding sphere light size, we could use it to scale the shadow map resolution
                // For the moment, this will be enough
                viewportSize *= Mathf.Lerp(64f / viewportSize.x, 1f, legacyLight.range / (camera.transform.position - transform.position).magnitude);
                viewportSize  = Vector2.Max(new Vector2(64f, 64f) / viewportSize, viewportSize);

                // Prevent flickering caused by the floating size of the viewport
                viewportSize.x = Mathf.Round(viewportSize.x);
                viewportSize.y = Mathf.Round(viewportSize.y);
            }

            viewportSize = Vector2.Max(viewportSize, new Vector2(16, 16));

            // Update the directional shadow atlas size
            if (legacyLight.type == LightType.Directional)
            {
                shadowManager.UpdateDirectionalShadowResolution((int)viewportSize.x, m_ShadowSettings.cascadeShadowSplitCount.value);
            }

            int count = GetShadowRequestCount();
            for (int index = 0; index < count; index++)
            {
                m_ShadowRequestIndices[index] = shadowManager.ReserveShadowResolutions(viewportSize, shadowMapType);
            }
        }
        // Must return the first executed shadow request
        public int UpdateShadowRequest(Camera camera, HDShadowInitParameters initParameters, HDShadowManager manager, VisibleLight visibleLight, CullResults cullResults, int lightIndex, out int shadowRequestCount)
        {
            int              firstShadowRequestIndex = -1;
            Vector3          cameraPos      = camera.transform.position;
            HDShadowSettings shadowSettings = VolumeManager.instance.stack.GetComponent <HDShadowSettings>();

            shadowRequestCount = 0;

            // When creating a new light, at the first frame, there is no AdditionalShadowData so we can't really render shadows
            if (m_ShadowData == null)
            {
                return(-1);
            }

            // Create shadow requests array using the light type
            if (shadowRequests == null || shadowRequests.Length != GetShadowRequestCount(shadowSettings))
            {
                int count = GetShadowRequestCount(shadowSettings);
                shadowRequests = new HDShadowRequest[count];

                for (int i = 0; i < count; i++)
                {
                    shadowRequests[i] = new HDShadowRequest();
                }
            }

            // If the shadow is too far away, we don't render it
            if (m_Light.type != LightType.Directional && Vector3.Distance(cameraPos, transform.position) >= m_ShadowData.shadowFadeDistance)
            {
                return(-1);
            }

            Vector2 viewportSize = new Vector2(m_ShadowData.shadowResolution, m_ShadowData.shadowResolution);

            if (initParameters.useDynamicViewportRescale && m_Light.type != LightType.Directional)
            {
                // resize viewport size by the normalized size of the light on screen
                // When we will have access to the non screen clamped bounding sphere light size, we could use it to scale the shadow map resolution
                // For the moment, this will be enough
                viewportSize *= Mathf.Lerp(64f / viewportSize.x, 1f, visibleLight.range / (cameraPos - transform.position).magnitude);
                viewportSize  = Vector2.Max(new Vector2(64f, 64f) / viewportSize, viewportSize);

                // Prevent flickering caused by the floating size of the viewport
                viewportSize.x = Mathf.Round(viewportSize.x);
                viewportSize.y = Mathf.Round(viewportSize.y);
            }

            viewportSize = Vector2.Max(viewportSize, new Vector2(16, 16));

            for (int requestIndex = 0; requestIndex < shadowRequests.Length; requestIndex++)
            {
                var       shadowRequest     = shadowRequests[requestIndex];
                Matrix4x4 invViewProjection = Matrix4x4.identity;

                // Write per light type matrices, splitDatas and culling parameters
                switch (m_Light.type)
                {
                case LightType.Point:
                    HDShadowUtils.ExtractPointLightData(m_Light.type, visibleLight, viewportSize, shadowNearPlane, m_ShadowData.normalBiasMax, (uint)requestIndex, out shadowRequest.view, out invViewProjection, out shadowRequest.projection, out shadowRequest.deviceProjection, out shadowRequest.splitData);
                    break;

                case LightType.Spot:
                    HDShadowUtils.ExtractSpotLightData(m_Light.type, spotLightShape, shadowNearPlane, aspectRatio, shapeWidth, shapeHeight, visibleLight, viewportSize, m_ShadowData.normalBiasMax, out shadowRequest.view, out invViewProjection, out shadowRequest.projection, out shadowRequest.deviceProjection, out shadowRequest.splitData);
                    break;

                case LightType.Directional:
                    Vector4 cullingSphere;
                    float   nearPlaneOffset = QualitySettings.shadowNearPlaneOffset;

                    HDShadowUtils.ExtractDirectionalLightData(visibleLight, viewportSize, (uint)requestIndex, shadowSettings.cascadeShadowSplitCount, shadowSettings.cascadeShadowSplits, nearPlaneOffset, cullResults, lightIndex, out shadowRequest.view, out invViewProjection, out shadowRequest.projection, out shadowRequest.deviceProjection, out shadowRequest.splitData);

                    cullingSphere = shadowRequest.splitData.cullingSphere;

                    // Camera relative for directional light culling sphere
                    if (ShaderConfig.s_CameraRelativeRendering != 0)
                    {
                        cullingSphere.x -= cameraPos.x;
                        cullingSphere.y -= cameraPos.y;
                        cullingSphere.z -= cameraPos.z;
                    }

                    manager.UpdateCascade(requestIndex, cullingSphere, shadowSettings.cascadeShadowBorders[requestIndex]);
                    break;

                case LightType.Area:
                    HDShadowUtils.ExtractAreaLightData(visibleLight, lightTypeExtent, out shadowRequest.view, out invViewProjection, out shadowRequest.projection, out shadowRequest.deviceProjection, out shadowRequest.splitData);
                    break;
                }

                // Assign all setting common to every lights
                SetCommonShadowRequestSettings(shadowRequest, cameraPos, invViewProjection, viewportSize, lightIndex);

                int shadowRequestIndex = manager.AddShadowRequest(shadowRequest);

                // Store the first shadow request id to return it
                if (firstShadowRequestIndex == -1)
                {
                    firstShadowRequestIndex = shadowRequestIndex;
                }

                shadowRequestCount++;
            }

            return(firstShadowRequestIndex);
        }