public void InitShadowManager(RenderPipelineResources renderPipelineResources, DepthBits directionalShadowDepthBits,
                                      HDShadowInitParameters.HDShadowAtlasInitParams punctualLightAtlasInfo, HDShadowInitParameters.HDShadowAtlasInitParams areaLightAtlasInfo, int maxShadowRequests, Shader clearShader)
        {
            Material clearMaterial = CoreUtils.CreateEngineMaterial(clearShader);

            // Prevent the list from resizing their internal container when we add shadow requests
            m_ShadowDatas.Capacity        = maxShadowRequests;
            m_ShadowResolutionRequests    = new HDShadowResolutionRequest[maxShadowRequests];
            m_ShadowRequests              = new HDShadowRequest[maxShadowRequests];
            m_CachedDirectionalShadowData = new HDDirectionalShadowData[1]; // we only support directional light shadow

            for (int i = 0; i < maxShadowRequests; i++)
            {
                m_ShadowResolutionRequests[i] = new HDShadowResolutionRequest();
            }

            // The cascade atlas will be allocated only if there is a directional light
            m_Atlas = new HDShadowAtlas(renderPipelineResources, punctualLightAtlasInfo.shadowAtlasResolution, punctualLightAtlasInfo.shadowAtlasResolution, HDShaderIDs._ShadowmapAtlas, HDShaderIDs._ShadowAtlasSize, clearMaterial, maxShadowRequests, depthBufferBits: punctualLightAtlasInfo.shadowAtlasDepthBits, name: "Shadow Map Atlas");
            // Cascade atlas render texture will only be allocated if there is a shadow casting directional light
            HDShadowAtlas.BlurAlgorithm cascadeBlur = GetDirectionalShadowAlgorithm() == DirectionalShadowAlgorithm.IMS ? HDShadowAtlas.BlurAlgorithm.IM : HDShadowAtlas.BlurAlgorithm.None;
            m_CascadeAtlas = new HDShadowAtlas(renderPipelineResources, 1, 1, HDShaderIDs._ShadowmapCascadeAtlas, HDShaderIDs._CascadeShadowAtlasSize, clearMaterial, maxShadowRequests, cascadeBlur, depthBufferBits: directionalShadowDepthBits, name: "Cascade Shadow Map Atlas");

            m_AreaLightShadowAtlas = new HDShadowAtlas(renderPipelineResources, areaLightAtlasInfo.shadowAtlasResolution, areaLightAtlasInfo.shadowAtlasResolution, HDShaderIDs._AreaLightShadowmapAtlas, HDShaderIDs._AreaShadowAtlasSize, clearMaterial, maxShadowRequests, HDShadowAtlas.BlurAlgorithm.EVSM, depthBufferBits: areaLightAtlasInfo.shadowAtlasDepthBits, name: "Area Light Shadow Map Atlas", momentAtlasShaderID: HDShaderIDs._AreaShadowmapMomentAtlas);

            m_ShadowDataBuffer            = new ComputeBuffer(maxShadowRequests, System.Runtime.InteropServices.Marshal.SizeOf(typeof(HDShadowData)));
            m_DirectionalShadowDataBuffer = new ComputeBuffer(1, System.Runtime.InteropServices.Marshal.SizeOf(typeof(HDDirectionalShadowData)));

            m_MaxShadowRequests = maxShadowRequests;
        }
 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);
     }
 }
        // Used to update the resolution request processed by the light loop
        internal void UpdateResolutionRequest(ref HDShadowResolutionRequest request, int shadowIdx)
        {
            CachedShadowRecord record;
            bool valueFound = m_PlacedShadows.TryGetValue(shadowIdx, out record);

            if (!valueFound)
            {
                Debug.LogWarning("Trying to render a cached shadow map that doesn't have a slot in the atlas yet.");
            }

            request.cachedAtlasViewport = new Rect(record.offsetInAtlas.x, record.offsetInAtlas.y, record.viewportSize, record.viewportSize);
            request.resolution          = new Vector2(record.viewportSize, record.viewportSize);
        }
Beispiel #4
0
        public void InitShadowManager(RenderPipelineResources renderPipelineResources, HDShadowInitParameters initParams, RenderGraph renderGraph, Shader clearShader)
        {
            // Even when shadows are disabled (maxShadowRequests == 0) we need to allocate compute buffers to avoid having
            // resource not bound errors when dispatching a compute shader.
            m_ShadowDataBuffer            = new ComputeBuffer(Mathf.Max(initParams.maxShadowRequests, 1), System.Runtime.InteropServices.Marshal.SizeOf(typeof(HDShadowData)));
            m_DirectionalShadowDataBuffer = new ComputeBuffer(1, System.Runtime.InteropServices.Marshal.SizeOf(typeof(HDDirectionalShadowData)));
            m_MaxShadowRequests           = initParams.maxShadowRequests;
            m_ShadowRequestCount          = 0;

            if (initParams.maxShadowRequests == 0)
            {
                return;
            }

            m_ClearShadowMaterial = CoreUtils.CreateEngineMaterial(clearShader);
            m_BlitShadowMaterial  = CoreUtils.CreateEngineMaterial(renderPipelineResources.shaders.shadowBlitPS);

            // Prevent the list from resizing their internal container when we add shadow requests
            m_ShadowDatas.Capacity        = Math.Max(initParams.maxShadowRequests, m_ShadowDatas.Capacity);
            m_ShadowResolutionRequests    = new HDShadowResolutionRequest[initParams.maxShadowRequests];
            m_ShadowRequests              = new HDShadowRequest[initParams.maxShadowRequests];
            m_CachedDirectionalShadowData = new HDDirectionalShadowData[1]; // we only support directional light shadow

            for (int i = 0; i < initParams.maxShadowRequests; i++)
            {
                m_ShadowResolutionRequests[i] = new HDShadowResolutionRequest();
            }

            // The cascade atlas will be allocated only if there is a directional light
            m_Atlas = new HDDynamicShadowAtlas(renderPipelineResources, renderGraph, useSharedTexture: false, initParams.punctualLightShadowAtlas.shadowAtlasResolution, initParams.punctualLightShadowAtlas.shadowAtlasResolution,
                                               HDShaderIDs._ShadowmapAtlas, m_ClearShadowMaterial, initParams.maxShadowRequests, initParams, depthBufferBits: initParams.punctualLightShadowAtlas.shadowAtlasDepthBits, name: "Shadow Map Atlas");
            // Cascade atlas render texture will only be allocated if there is a shadow casting directional light
            HDShadowAtlas.BlurAlgorithm cascadeBlur = GetDirectionalShadowAlgorithm() == DirectionalShadowAlgorithm.IMS ? HDShadowAtlas.BlurAlgorithm.IM : HDShadowAtlas.BlurAlgorithm.None;
            m_CascadeAtlas = new HDDynamicShadowAtlas(renderPipelineResources, renderGraph, useSharedTexture: false, 1, 1, HDShaderIDs._ShadowmapCascadeAtlas, m_ClearShadowMaterial, initParams.maxShadowRequests, initParams, cascadeBlur, depthBufferBits: initParams.directionalShadowsDepthBits, name: "Cascade Shadow Map Atlas");

            if (ShaderConfig.s_AreaLights == 1)
            {
                m_AreaLightShadowAtlas = new HDDynamicShadowAtlas(renderPipelineResources, renderGraph, useSharedTexture: false, initParams.areaLightShadowAtlas.shadowAtlasResolution, initParams.areaLightShadowAtlas.shadowAtlasResolution,
                                                                  HDShaderIDs._ShadowmapAreaAtlas, m_ClearShadowMaterial, initParams.maxShadowRequests, initParams, HDShadowAtlas.BlurAlgorithm.EVSM, depthBufferBits: initParams.areaLightShadowAtlas.shadowAtlasDepthBits, name: "Area Light Shadow Map Atlas");
            }

            cachedShadowManager.InitPunctualShadowAtlas(renderPipelineResources, renderGraph, useSharedTexture: true, initParams.cachedPunctualLightShadowAtlas, initParams.cachedPunctualLightShadowAtlas,
                                                        HDShaderIDs._CachedShadowmapAtlas, m_ClearShadowMaterial, initParams.maxShadowRequests, initParams: initParams, depthBufferBits: initParams.punctualLightShadowAtlas.shadowAtlasDepthBits, name: "Cached Shadow Map Atlas");
            if (ShaderConfig.s_AreaLights == 1)
            {
                cachedShadowManager.InitAreaLightShadowAtlas(renderPipelineResources, renderGraph, useSharedTexture: true, initParams.cachedAreaLightShadowAtlas, initParams.cachedAreaLightShadowAtlas,
                                                             HDShaderIDs._CachedAreaLightShadowmapAtlas, m_ClearShadowMaterial, initParams.maxShadowRequests, initParams: initParams, HDShadowAtlas.BlurAlgorithm.EVSM, depthBufferBits: initParams.areaLightShadowAtlas.shadowAtlasDepthBits, name: "Cached Area Light Shadow Map Atlas");
            }
        }
 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;
     }
 }
Beispiel #6
0
        public HDShadowAtlas(RenderPipelineResources renderPipelineResources, int width, int height, int atlasShaderID, Material clearMaterial, int maxShadowRequests, BlurAlgorithm blurAlgorithm = BlurAlgorithm.None, FilterMode filterMode = FilterMode.Bilinear, DepthBits depthBufferBits = DepthBits.Depth16, RenderTextureFormat format = RenderTextureFormat.Shadowmap, string name = "")
        {
            this.width                = width;
            this.height               = height;
            m_FilterMode              = filterMode;
            m_DepthBufferBits         = depthBufferBits;
            m_Format                  = format;
            m_Name                    = name;
            m_AtlasShaderID           = atlasShaderID;
            m_ClearMaterial           = clearMaterial;
            m_BlurAlgorithm           = blurAlgorithm;
            m_RenderPipelineResources = renderPipelineResources;

            m_SortedRequestsCache      = new HDShadowResolutionRequest[Mathf.CeilToInt(maxShadowRequests * 1.5f)];
            m_CachedResolutionRequests = new HDShadowResolutionRequest[maxShadowRequests];
            for (int i = 0; i < maxShadowRequests; ++i)
            {
                m_CachedResolutionRequests[i] = new HDShadowResolutionRequest();
            }

            AllocateRenderTexture();
        }
 internal void ReserveResolution(HDShadowResolutionRequest shadowRequest)
 {
     m_ShadowResolutionRequests.Add(shadowRequest);
 }
        internal int RegisterCachedLight(HDShadowResolutionRequest request)
        {
            // Since we are starting caching light resolution requests, it means that data cached from now on will be valid.
            frameOfCacheValidity++;

            // If it is already registered, we do nothing.
            int shadowIndex = -1;

            for (int i = 0; i < m_ListOfCachedShadowRequests.Count; ++i)
            {
                if (!m_ListOfCachedShadowRequests[i].emptyRequest && m_ListOfCachedShadowRequests[i].lightID == request.lightID && m_ListOfCachedShadowRequests[i].indexInLight == request.indexInLight)
                {
                    shadowIndex = i;
                    break;
                }
            }

            if (shadowIndex == -1)
            {
                // First we search if we have a hole we can fill with it.
                float resolutionOfNewLight = request.atlasViewport.width;
                request.lastFrameActive = frameCounter;

                int holeWithRightSize = -1;
                for (int i = 0; i < m_ListOfCachedShadowRequests.Count; ++i)
                {
                    var currReq = m_ListOfCachedShadowRequests[i];
                    if (currReq.emptyRequest &&                                                                            // Is empty
                        request.atlasViewport.width <= currReq.atlasViewport.width &&                                      // fits the request
                        (currReq.atlasViewport.width - request.atlasViewport.width) <= currReq.atlasViewport.width * 0.1f) // but is not much smaller.
                    {
                        holeWithRightSize = i;
                        break;
                    }
                }

                if (holeWithRightSize >= 0)
                {
                    m_ListOfCachedShadowRequests[holeWithRightSize] = request.ShallowCopy();
                    return(holeWithRightSize);
                }
                else
                {
                    // We need to resort the list, so we use the occasion to reset the pool. This feels suboptimal, but it is the easiest way to comply with the pooling system.
                    // TODO: Make this cleaner and more efficient.
                    m_CachedResolutionRequestsCounter = 0;
                    for (int i = 0; i < m_ListOfCachedShadowRequests.Count; ++i)
                    {
                        int currEntryInPool = m_CachedResolutionRequestsCounter;
                        m_CachedResolutionRequests[currEntryInPool] = m_ListOfCachedShadowRequests[i].ShallowCopy();
                        m_ListOfCachedShadowRequests[i]             = m_CachedResolutionRequests[currEntryInPool];
                        m_CachedResolutionRequestsCounter++;
                    }
                    // Now we add the new element
                    m_CachedResolutionRequests[m_CachedResolutionRequestsCounter] = request.ShallowCopy();
                    m_ListOfCachedShadowRequests.Add(m_CachedResolutionRequests[m_CachedResolutionRequestsCounter]);
                    m_CachedResolutionRequestsCounter++;

                    InsertionSort(m_ListOfCachedShadowRequests.ToArray(), 0, m_ListOfCachedShadowRequests.Count);
                    frameOfCacheValidity = 0;     // Invalidate cached data
                    for (int i = 0; i < m_ListOfCachedShadowRequests.Count; ++i)
                    {
                        if (m_ListOfCachedShadowRequests[i].lightID == request.lightID && m_ListOfCachedShadowRequests[i].indexInLight == request.indexInLight)
                        {
                            return(i);
                        }
                    }
                }
            }
            else if (m_ListOfCachedShadowRequests[shadowIndex].emptyRequest)
            {
                // We still hold the spot, so fill it up again.
                m_ListOfCachedShadowRequests[shadowIndex].emptyRequest = false;
            }
            m_ListOfCachedShadowRequests[shadowIndex].lastFrameActive = frameCounter;

            return(shadowIndex);
        }
Beispiel #9
0
        public void InitShadowManager(RenderPipelineResources renderPipelineResources, HDShadowInitParameters initParams, Shader clearShader)
        {
            // Even when shadows are disabled (maxShadowRequests == 0) we need to allocate compute buffers to avoid having
            // resource not bound errors when dispatching a compute shader.
            m_ShadowDataBuffer            = new ComputeBuffer(Mathf.Max(initParams.maxShadowRequests, 1), System.Runtime.InteropServices.Marshal.SizeOf(typeof(HDShadowData)));
            m_DirectionalShadowDataBuffer = new ComputeBuffer(1, System.Runtime.InteropServices.Marshal.SizeOf(typeof(HDDirectionalShadowData)));
            m_MaxShadowRequests           = initParams.maxShadowRequests;
            m_ShadowRequestCount          = 0;

            if (initParams.maxShadowRequests == 0)
            {
                return;
            }

            m_ClearShadowMaterial = CoreUtils.CreateEngineMaterial(clearShader);
            m_BlitShadowMaterial  = CoreUtils.CreateEngineMaterial(renderPipelineResources.shaders.shadowBlitPS);

            // Prevent the list from resizing their internal container when we add shadow requests
            m_ShadowDatas.Capacity        = Math.Max(initParams.maxShadowRequests, m_ShadowDatas.Capacity);
            m_ShadowResolutionRequests    = new HDShadowResolutionRequest[initParams.maxShadowRequests];
            m_ShadowRequests              = new HDShadowRequest[initParams.maxShadowRequests];
            m_CachedDirectionalShadowData = new HDDirectionalShadowData[1]; // we only support directional light shadow

            m_GlobalShaderVariables = new ConstantBuffer <ShaderVariablesGlobal>();

            for (int i = 0; i < initParams.maxShadowRequests; i++)
            {
                m_ShadowResolutionRequests[i] = new HDShadowResolutionRequest();
            }

            HDShadowAtlas.HDShadowAtlasInitParameters punctualAtlasInitParams = new HDShadowAtlas.HDShadowAtlasInitParameters(renderPipelineResources, initParams.punctualLightShadowAtlas.shadowAtlasResolution,
                                                                                                                              initParams.punctualLightShadowAtlas.shadowAtlasResolution, HDShaderIDs._ShadowmapAtlas, m_ClearShadowMaterial, initParams.maxShadowRequests, initParams, m_GlobalShaderVariables);

            punctualAtlasInitParams.name = "Shadow Map Atlas";

            // The cascade atlas will be allocated only if there is a directional light
            m_Atlas = new HDDynamicShadowAtlas(punctualAtlasInitParams);

            // Cascade atlas render texture will only be allocated if there is a shadow casting directional light
            HDShadowAtlas.BlurAlgorithm cascadeBlur = GetDirectionalShadowAlgorithm() == DirectionalShadowAlgorithm.IMS ? HDShadowAtlas.BlurAlgorithm.IM : HDShadowAtlas.BlurAlgorithm.None;
            HDShadowAtlas.HDShadowAtlasInitParameters dirAtlasInitParams = punctualAtlasInitParams;
            dirAtlasInitParams.width           = 1;
            dirAtlasInitParams.height          = 1;
            dirAtlasInitParams.atlasShaderID   = HDShaderIDs._ShadowmapCascadeAtlas;
            dirAtlasInitParams.blurAlgorithm   = cascadeBlur;
            dirAtlasInitParams.depthBufferBits = initParams.directionalShadowsDepthBits;
            dirAtlasInitParams.name            = "Cascade Shadow Map Atlas";

            m_CascadeAtlas = new HDDynamicShadowAtlas(dirAtlasInitParams);

            HDShadowAtlas.HDShadowAtlasInitParameters areaAtlasInitParams = punctualAtlasInitParams;
            if (ShaderConfig.s_AreaLights == 1)
            {
                areaAtlasInitParams.width           = initParams.areaLightShadowAtlas.shadowAtlasResolution;
                areaAtlasInitParams.height          = initParams.areaLightShadowAtlas.shadowAtlasResolution;
                areaAtlasInitParams.atlasShaderID   = HDShaderIDs._ShadowmapAreaAtlas;
                areaAtlasInitParams.blurAlgorithm   = HDShadowAtlas.BlurAlgorithm.EVSM;
                areaAtlasInitParams.depthBufferBits = initParams.areaLightShadowAtlas.shadowAtlasDepthBits;
                areaAtlasInitParams.name            = "Area Light Shadow Map Atlas";
                m_AreaLightShadowAtlas = new HDDynamicShadowAtlas(areaAtlasInitParams);
            }

            HDShadowAtlas.HDShadowAtlasInitParameters cachedPunctualAtlasInitParams = punctualAtlasInitParams;
            cachedPunctualAtlasInitParams.width         = initParams.cachedPunctualLightShadowAtlas;
            cachedPunctualAtlasInitParams.height        = initParams.cachedPunctualLightShadowAtlas;
            cachedPunctualAtlasInitParams.atlasShaderID = HDShaderIDs._CachedShadowmapAtlas;
            cachedPunctualAtlasInitParams.name          = "Cached Shadow Map Atlas";

            cachedShadowManager.InitPunctualShadowAtlas(cachedPunctualAtlasInitParams);

            if (ShaderConfig.s_AreaLights == 1)
            {
                HDShadowAtlas.HDShadowAtlasInitParameters cachedAreaAtlasInitParams = areaAtlasInitParams;
                cachedAreaAtlasInitParams.width         = initParams.cachedAreaLightShadowAtlas;
                cachedAreaAtlasInitParams.height        = initParams.cachedAreaLightShadowAtlas;
                cachedAreaAtlasInitParams.atlasShaderID = HDShaderIDs._CachedAreaLightShadowmapAtlas;
                cachedAreaAtlasInitParams.name          = "Cached Area Light Shadow Map Atlas";

                cachedShadowManager.InitAreaLightShadowAtlas(cachedAreaAtlasInitParams);
            }
        }