// ------------------------ Debug API -------------------------------
#if UNITY_EDITOR
        internal void PrintLightStatusInCachedAtlas()
        {
            bool headerPrinted = false;
            var  lights        = GameObject.FindObjectsOfType <HDAdditionalLightData>();

            foreach (var light in lights)
            {
                ShadowMapType shadowMapType = light.GetShadowMapType(light.type);
                if (instance.LightIsPendingPlacement(light, shadowMapType))
                {
                    if (!headerPrinted)
                    {
                        Debug.Log(" ===== Lights pending placement in the cached shadow atlas: ===== ");
                        headerPrinted = true;
                    }
                    Debug.Log("\t Name: " + light.name + " Type: " + light.type + " Resolution: " + light.GetResolutionFromSettings(shadowMapType, m_InitParams));
                }
            }

            headerPrinted = false;
            foreach (var light in lights)
            {
                ShadowMapType shadowMapType = light.GetShadowMapType(light.type);
                if (!(instance.LightIsPendingPlacement(light, light.GetShadowMapType(light.type))) && light.lightIdxForCachedShadows != -1)
                {
                    if (!headerPrinted)
                    {
                        Debug.Log("===== Lights placed in cached shadow atlas: ===== ");
                        headerPrinted = true;
                    }
                    Debug.Log("\t Name: " + light.name + " Type: " + light.type + " Resolution: " + light.GetResolutionFromSettings(shadowMapType, m_InitParams));
                }
            }
        }
        internal HDShadowResolutionRequest GetResolutionRequest(ShadowMapType type, bool cachedShadow, int index)
        {
            if (cachedShadow)
            {
                switch (type)
                {
                case ShadowMapType.PunctualAtlas:
                    return(m_Atlas.GetCachedRequest(index));

                case ShadowMapType.AreaLightAtlas:
                    return(m_AreaLightShadowAtlas.GetCachedRequest(index));
                }
            }
            else
            {
                if (index < 0 || index >= m_ShadowRequestCount)
                {
                    return(null);
                }

                return(m_ShadowResolutionRequests[index]);
            }

            return(null);
        }
Example #3
0
        public int ReserveShadowResolutions(Vector2 resolution, ShadowMapType shadowMapType)
        {
            if (m_ShadowRequestCount >= m_MaxShadowRequests)
            {
                Debug.LogWarning("Max shadow requests count reached, dropping all exceeding requests. You can increase this limit by changing the max requests in the HDRP asset");
                return(-1);
            }

            HDShadowResolutionRequest resolutionRequest = new HDShadowResolutionRequest {
                resolution    = resolution,
                shadowMapType = shadowMapType,
            };

            switch (shadowMapType)
            {
            case ShadowMapType.PunctualAtlas:
                m_Atlas.ReserveResolution(resolutionRequest);
                break;

            case ShadowMapType.AreaLightAtlas:
                m_AreaLightShadowAtlas.ReserveResolution(resolutionRequest);
                break;

            case ShadowMapType.CascadedDirectional:
                m_CascadeAtlas.ReserveResolution(resolutionRequest);
                break;
            }

            m_ShadowResolutionRequests.Add(resolutionRequest);
            m_ShadowRequestCount = m_ShadowResolutionRequests.Count;

            return(m_ShadowResolutionRequests.Count - 1);
        }
        internal int ReserveShadowResolutions(Vector2 resolution, ShadowMapType shadowMapType, int lightID, int index, bool canBeCached, out int cachedRequestIdx)
        {
            cachedRequestIdx = -1;
            if (m_ShadowRequestCount >= m_MaxShadowRequests)
            {
                Debug.LogWarning("Max shadow requests count reached, dropping all exceeding requests. You can increase this limit by changing the max requests in the HDRP asset");
                return(-1);
            }
            int cachedIndex = -1;


            m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter].resolution           = resolution;
            m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter].shadowMapType        = shadowMapType;
            m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter].lightID              = lightID;
            m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter].emptyRequest         = false;
            m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter].indexInLight         = index;
            m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter].atlasViewport.width  = resolution.x;
            m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter].atlasViewport.height = resolution.y;
            if (canBeCached)
            {
                m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter].hasBeenStoredInCachedList = true;
            }
            else
            {
                m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter].hasBeenStoredInCachedList = false;
            }



            switch (shadowMapType)
            {
            case ShadowMapType.PunctualAtlas:
                if (canBeCached)
                {
                    cachedIndex = m_Atlas.RegisterCachedLight(m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter]);
                }
                m_Atlas.ReserveResolution(m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter]);
                break;

            case ShadowMapType.AreaLightAtlas:
                if (canBeCached)
                {
                    cachedIndex = m_AreaLightShadowAtlas.RegisterCachedLight(m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter]);
                }

                m_AreaLightShadowAtlas.ReserveResolution(m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter]);
                break;

            case ShadowMapType.CascadedDirectional:
                m_CascadeAtlas.ReserveResolution(m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter]);
                break;
            }

            m_ShadowResolutionRequestCounter++;
            m_ShadowRequestCount = m_ShadowResolutionRequestCounter;
            cachedRequestIdx     = cachedIndex;

            return(m_ShadowResolutionRequestCounter - 1);
        }
Example #5
0
        // ------------------------------------------------------------------------------------------
        //                                      Init Functions
        // ------------------------------------------------------------------------------------------
        public HDCachedShadowAtlas(ShadowMapType type)
        {
            m_PlacedShadows           = new Dictionary <int, CachedShadowRecord>(s_InitialCapacity);
            m_ShadowsPendingRendering = new Dictionary <int, CachedShadowRecord>(s_InitialCapacity);
            m_TempListForPlacement    = new List <CachedShadowRecord>(s_InitialCapacity);

            m_RegisteredLightDataPendingPlacement = new Dictionary <int, HDAdditionalLightData>(s_InitialCapacity);
            m_RecordsPendingPlacement             = new Dictionary <int, CachedShadowRecord>(s_InitialCapacity);

            m_ShadowType = type;
        }
        internal int GetAtlasShapeID(ShadowMapType type)
        {
            switch (type)
            {
            case ShadowMapType.PunctualAtlas:
                return(m_Atlas.atlasShapeID);

            case ShadowMapType.AreaLightAtlas:
                return(m_AreaLightShadowAtlas.atlasShapeID);
            }
            return(-1);
        }
Example #7
0
        public static Reaction <Camera> Renderer(SceneGraph scene,
                                                 int mapSize, ShadowMapType type, bool cascaded)
        {
            var depthFramebuffer = new Framebuffer(FramebufferTarget.Framebuffer);

            _shadowShader = cascaded ?
                            new GLProgram(
                VertexShaderCascaded(),
                GeometryShaderCascaded(),
                DepthFragmentShader()) :
                            new GLProgram(
                VertexShader(),
                type == ShadowMapType.Depth ? DepthFragmentShader() : VarianceFragmentShader());

            _instance = new Shadows(_shadowShader, cascaded);

            Texture depthTexture;
            var     render = React.By <Camera> (_instance.Render);

            if (type == ShadowMapType.Depth || cascaded)
            {
                depthTexture = cascaded ?
                               new Texture(TextureTarget.Texture2DArray, PixelInternalFormat.DepthComponent16,
                                           mapSize, mapSize, CascadedShadowUniforms.MapCount, PixelFormat.DepthComponent,
                                           PixelType.Float, IntPtr.Zero) :
                               new Texture(TextureTarget.Texture2D, PixelInternalFormat.DepthComponent16,
                                           mapSize, mapSize, PixelFormat.DepthComponent, PixelType.Float, IntPtr.Zero);
                depthFramebuffer.AddTexture(FramebufferAttachment.DepthAttachment, depthTexture);
            }
            else
            {
                depthTexture = new Texture(TextureTarget.Texture2D, PixelInternalFormat.Rg32f,
                                           mapSize, mapSize, PixelFormat.Rg, PixelType.Float, IntPtr.Zero);
                depthFramebuffer.AddTexture(FramebufferAttachment.ColorAttachment0, depthTexture);
                depthFramebuffer.AddRenderbuffer(FramebufferAttachment.DepthAttachment,
                                                 RenderbufferStorage.DepthComponent16, mapSize, mapSize);
                var gaussTexture = new Texture(TextureTarget.Texture2D, PixelInternalFormat.Rg32f,
                                               mapSize / 2, mapSize / 2, PixelFormat.Rg, PixelType.Float, IntPtr.Zero);
                render = render.And(GaussianFilter.Both().MapInput((Camera cam) =>
                                                                   Tuple.Create(depthTexture, gaussTexture)));
            }
            scene.GlobalLighting.ShadowMap = depthTexture;

            return(render
                   .DrawBuffer(type == ShadowMapType.Depth ? DrawBufferMode.None : DrawBufferMode.Front)
                   .DepthTest()
                   .Culling()
                   .Viewport(new Vec2i(mapSize, mapSize))
                   .Program(_shadowShader)
                   .Texture(depthTexture)
                   .Framebuffer(depthFramebuffer));
        }
        internal bool LightIsPendingPlacement(HDAdditionalLightData light, ShadowMapType shadowMapType)
        {
            if (shadowMapType == ShadowMapType.PunctualAtlas)
            {
                return(punctualShadowAtlas.LightIsPendingPlacement(light));
            }
            if (shadowMapType == ShadowMapType.AreaLightAtlas)
            {
                return(areaShadowAtlas.LightIsPendingPlacement(light));
            }

            return(false);
        }
        internal bool AtlasHasResized(ShadowMapType type)
        {
            switch (type)
            {
            case ShadowMapType.PunctualAtlas:
                return(m_Atlas.HasResizedThisFrame());

            case ShadowMapType.AreaLightAtlas:
                return(m_AreaLightShadowAtlas.HasResizedThisFrame());
            }

            return(false);
        }
        internal bool CachedDataIsValid(ShadowMapType type)
        {
            const int thresholdOfValidFrames = 30;

            switch (type)
            {
            case ShadowMapType.PunctualAtlas:
                return(m_Atlas.frameOfCacheValidity > thresholdOfValidFrames);

            case ShadowMapType.AreaLightAtlas:
                return(m_AreaLightShadowAtlas.frameOfCacheValidity > thresholdOfValidFrames);
            }

            return(false);
        }
 internal void MarkShadowAsRendered(int shadowIdx, ShadowMapType shadowMapType)
 {
     if (shadowMapType == ShadowMapType.PunctualAtlas)
     {
         punctualShadowAtlas.MarkAsRendered(shadowIdx);
     }
     if (shadowMapType == ShadowMapType.AreaLightAtlas)
     {
         areaShadowAtlas.MarkAsRendered(shadowIdx);
     }
     if (shadowMapType == ShadowMapType.CascadedDirectional)
     {
         m_DirectionalShadowPendingUpdate[shadowIdx] = false;
     }
 }
        internal bool ShadowIsPendingUpdate(int shadowIdx, ShadowMapType shadowMapType)
        {
            if (shadowMapType == ShadowMapType.PunctualAtlas)
            {
                return(punctualShadowAtlas.ShadowIsPendingRendering(shadowIdx));
            }
            if (shadowMapType == ShadowMapType.AreaLightAtlas)
            {
                return(areaShadowAtlas.ShadowIsPendingRendering(shadowIdx));
            }
            if (shadowMapType == ShadowMapType.CascadedDirectional)
            {
                return(m_DirectionalShadowPendingUpdate[shadowIdx]);
            }

            return(false);
        }
        internal void MarkCachedShadowSlotsAsEmpty(ShadowMapType shadowMapType, int lightID)
        {
            switch (shadowMapType)
            {
            case ShadowMapType.PunctualAtlas:
                if (m_Atlas != null)
                {
                    m_Atlas.MarkCachedShadowSlotAsEmpty(lightID);
                }
                break;

            case ShadowMapType.AreaLightAtlas:
                if (m_AreaLightShadowAtlas != null)
                {
                    m_AreaLightShadowAtlas.MarkCachedShadowSlotAsEmpty(lightID);
                }
                break;
            }
        }
Example #14
0
        internal int ReserveShadowResolutions(Vector2 resolution, ShadowMapType shadowMapType, int lightID, int index, ShadowMapUpdateType updateType)
        {
            if (m_ShadowRequestCount >= m_MaxShadowRequests)
            {
                Debug.LogWarning("Max shadow requests count reached, dropping all exceeding requests. You can increase this limit by changing the max requests in the HDRP asset");
                return(-1);
            }

            m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter].shadowMapType = shadowMapType;

            // Note: for cached shadows we manage the resolution requests directly on the CachedShadowAtlas as they need special handling. We however keep incrementing the counter for two reasons:
            //      - Maintain the limit of m_MaxShadowRequests
            //      - Avoid to refactor other parts that the shadow manager that get requests indices from here.

            if (updateType != ShadowMapUpdateType.Cached || shadowMapType == ShadowMapType.CascadedDirectional)
            {
                m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter].resolution = resolution;
                m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter].dynamicAtlasViewport.width  = resolution.x;
                m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter].dynamicAtlasViewport.height = resolution.y;

                switch (shadowMapType)
                {
                case ShadowMapType.PunctualAtlas:
                    m_Atlas.ReserveResolution(m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter]);
                    break;

                case ShadowMapType.AreaLightAtlas:
                    m_AreaLightShadowAtlas.ReserveResolution(m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter]);
                    break;

                case ShadowMapType.CascadedDirectional:
                    m_CascadeAtlas.ReserveResolution(m_ShadowResolutionRequests[m_ShadowResolutionRequestCounter]);
                    break;
                }
            }


            m_ShadowResolutionRequestCounter++;
            m_ShadowRequestCount = m_ShadowResolutionRequestCounter;

            return(m_ShadowResolutionRequestCounter - 1);
        }
Example #15
0
        internal void PruneEmptyCachedSlots(ShadowMapType type)
        {
            switch (type)
            {
            case ShadowMapType.PunctualAtlas:
                if (m_Atlas != null)
                {
                    m_Atlas.PruneDeadCachedLightSlots();
                }
                break;

            case ShadowMapType.AreaLightAtlas:
                if (m_AreaLightShadowAtlas != null)
                {
                    m_AreaLightShadowAtlas.PruneDeadCachedLightSlots();
                }
                break;

            default:
                break;
            }
        }
Example #16
0
        public static Reaction<Camera> Renderer(SceneGraph scene,
			int mapSize, ShadowMapType type, bool cascaded)
        {
            var depthFramebuffer = new Framebuffer (FramebufferTarget.Framebuffer);
            _shadowShader = cascaded ?
                new GLProgram (
                    VertexShaderCascaded (),
                    GeometryShaderCascaded (),
                    DepthFragmentShader ()) :
                new GLProgram (
                    VertexShader (),
                    type == ShadowMapType.Depth ? DepthFragmentShader () : VarianceFragmentShader ());

            _instance = new Shadows (_shadowShader, cascaded);

            Texture depthTexture;
            var render =React.By<Camera> (_instance.Render);
            if (type == ShadowMapType.Depth || cascaded)
            {
                depthTexture = cascaded ?
                    new Texture (TextureTarget.Texture2DArray, PixelInternalFormat.DepthComponent16,
                        mapSize, mapSize, CascadedShadowUniforms.MapCount, PixelFormat.DepthComponent,
                        PixelType.Float, IntPtr.Zero) :
                    new Texture (TextureTarget.Texture2D, PixelInternalFormat.DepthComponent16,
                        mapSize, mapSize, PixelFormat.DepthComponent, PixelType.Float, IntPtr.Zero);
                depthFramebuffer.AddTexture (FramebufferAttachment.DepthAttachment, depthTexture);
            }
            else
            {
                depthTexture = new Texture (TextureTarget.Texture2D, PixelInternalFormat.Rg32f,
                    mapSize, mapSize, PixelFormat.Rg, PixelType.Float, IntPtr.Zero);
                depthFramebuffer.AddTexture (FramebufferAttachment.ColorAttachment0, depthTexture);
                depthFramebuffer.AddRenderbuffer (FramebufferAttachment.DepthAttachment,
                    RenderbufferStorage.DepthComponent16, mapSize, mapSize);
                var gaussTexture = new Texture (TextureTarget.Texture2D, PixelInternalFormat.Rg32f,
                    mapSize / 2, mapSize / 2, PixelFormat.Rg, PixelType.Float, IntPtr.Zero);
                render = render.And (GaussianFilter.Both ().MapInput ((Camera cam) =>
                    Tuple.Create (depthTexture, gaussTexture)));
            }
            scene.GlobalLighting.ShadowMap = depthTexture;

            return render
                .DrawBuffer (type == ShadowMapType.Depth ? DrawBufferMode.None : DrawBufferMode.Front)
                .DepthTest ()
                .Culling ()
                .Viewport (new Vec2i (mapSize, mapSize))
                .Program (_shadowShader)
                .Texture (depthTexture)
                .Framebuffer (depthFramebuffer);
        }
 internal void UpdateResolutionRequest(ref HDShadowResolutionRequest request, int shadowIdx, ShadowMapType shadowMapType)
 {
     if (shadowMapType == ShadowMapType.PunctualAtlas)
     {
         punctualShadowAtlas.UpdateResolutionRequest(ref request, shadowIdx);
     }
     else if (shadowMapType == ShadowMapType.AreaLightAtlas)
     {
         areaShadowAtlas.UpdateResolutionRequest(ref request, shadowIdx);
     }
 }
 internal void UpdateResolutionRequest(ref HDShadowResolutionRequest request, int shadowIdx, ShadowMapType shadowMapType)
 {
     if (shadowMapType == ShadowMapType.PunctualAtlas)
     {
         punctualShadowAtlas.UpdateResolutionRequest(ref request, shadowIdx);
     }
     else if (shadowMapType == ShadowMapType.AreaLightAtlas)
     {
         areaShadowAtlas.UpdateResolutionRequest(ref request, shadowIdx);
     }
     else if (shadowMapType == ShadowMapType.CascadedDirectional)
     {
         request.cachedAtlasViewport = request.dynamicAtlasViewport;
     }
 }
        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);
            }
        }