Exemple #1
0
        public bool Setup(ref RenderingData renderingData)
        {
            if (!renderingData.shadowData.supportsMainLightShadows)
            {
                return(false);
            }

            Clear();
            int shadowLightIndex = renderingData.lightData.mainLightIndex;

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

            VisibleLight shadowLight = renderingData.lightData.visibleLights[shadowLightIndex];
            Light        light       = shadowLight.light;

            if (light.shadows == LightShadows.None)
            {
                return(false);
            }

            if (shadowLight.lightType != LightType.Directional)
            {
                Debug.LogWarning("Only directional lights are supported as main light.");
            }

            Bounds bounds;

            if (!renderingData.cullResults.GetShadowCasterBounds(shadowLightIndex, out bounds))
            {
                return(false);
            }

            m_ShadowCasterCascadesCount = renderingData.shadowData.mainLightShadowCascadesCount;

            int shadowResolution = ShadowUtils.GetMaxTileResolutionInAtlas(renderingData.shadowData.mainLightShadowmapWidth,
                                                                           renderingData.shadowData.mainLightShadowmapHeight, m_ShadowCasterCascadesCount);

            m_ShadowmapWidth  = renderingData.shadowData.mainLightShadowmapWidth;
            m_ShadowmapHeight = (m_ShadowCasterCascadesCount == 2) ?
                                renderingData.shadowData.mainLightShadowmapHeight >> 1 :
                                renderingData.shadowData.mainLightShadowmapHeight;

            for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
            {
                bool success = ShadowUtils.ExtractDirectionalLightMatrix(ref renderingData.cullResults, ref renderingData.shadowData,
                                                                         shadowLightIndex, cascadeIndex, m_ShadowmapWidth, m_ShadowmapHeight, shadowResolution, light.shadowNearPlane,
                                                                         out m_CascadeSplitDistances[cascadeIndex], out m_CascadeSlices[cascadeIndex], out m_CascadeSlices[cascadeIndex].viewMatrix, out m_CascadeSlices[cascadeIndex].projectionMatrix);

                if (!success)
                {
                    return(false);
                }
            }

            return(true);
        }
Exemple #2
0
        public bool Setup(ref RenderingData renderingData)
        {
            using var profScope = new ProfilingScope(null, m_ProfilingSetupSampler);

            if (!renderingData.shadowData.supportsMainLightShadows)
            {
                return(false);
            }

            Clear();
            int shadowLightIndex = renderingData.lightData.mainLightIndex;

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

            VisibleLight shadowLight = renderingData.lightData.visibleLights[shadowLightIndex];
            Light        light       = shadowLight.light;

            if (light.shadows == LightShadows.None)
            {
                return(false);
            }

            if (shadowLight.lightType != LightType.Directional)
            {
                Debug.LogWarning("Only directional lights are supported as main light.");
            }

            Bounds bounds;

            if (!renderingData.cullResults.GetShadowCasterBounds(shadowLightIndex, out bounds))
            {
                return(false);
            }

            m_ShadowCasterCascadesCount = renderingData.shadowData.mainLightShadowCascadesCount;

            int shadowResolution = ShadowUtils.GetMaxTileResolutionInAtlas(renderingData.shadowData.mainLightShadowmapWidth,
                                                                           renderingData.shadowData.mainLightShadowmapHeight, m_ShadowCasterCascadesCount);

            renderTargetWidth  = renderingData.shadowData.mainLightShadowmapWidth;
            renderTargetHeight = (m_ShadowCasterCascadesCount == 2) ?
                                 renderingData.shadowData.mainLightShadowmapHeight >> 1 :
                                 renderingData.shadowData.mainLightShadowmapHeight;

            for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
            {
                bool success = ShadowUtils.ExtractDirectionalLightMatrix(ref renderingData.cullResults, ref renderingData.shadowData,
                                                                         shadowLightIndex, cascadeIndex, renderTargetWidth, renderTargetHeight, shadowResolution, light.shadowNearPlane,
                                                                         out m_CascadeSplitDistances[cascadeIndex], out m_CascadeSlices[cascadeIndex]);

                if (!success)
                {
                    return(false);
                }
            }

            m_MainLightShadowmapTexture = ShadowUtils.GetTemporaryShadowTexture(renderTargetWidth, renderTargetHeight, k_ShadowmapBufferBits);
            m_MaxShadowDistanceSq       = renderingData.cameraData.maxShadowDistance * renderingData.cameraData.maxShadowDistance;
            m_CascadeBorder             = renderingData.shadowData.mainLightShadowCascadeBorder;

            return(true);
        }
            override public bool Reserve(FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint[] widths, uint[] heights, ref VectorArray <ShadowData> entries, ref VectorArray <ShadowPayload> payload, VisibleLight[] lights)
            {
                ShadowData sd    = shadowData;
                ShadowData dummy = new ShadowData();

                if (sr.shadowType != GPUShadowType.Point && sr.shadowType != GPUShadowType.Spot && sr.shadowType != GPUShadowType.Directional)
                {
                    return(false);
                }

                if (sr.shadowType == GPUShadowType.Directional)
                {
                    for (uint i = 0; i < k_MaxCascadesInShader; ++i)
                    {
                        m_TmpSplits[i].Set(0.0f, 0.0f, 0.0f, float.NegativeInfinity);
                    }
                }

                Key key;

                key.id            = sr.instanceId;
                key.faceIdx       = 0;
                key.visibleIdx    = (int)sr.index;
                key.shadowDataIdx = entries.Count();

                uint originalEntryCount    = entries.Count();
                uint originalPayloadCount  = payload.Count();
                uint originalActiveEntries = m_ActiveEntriesCount;

                uint facecnt  = sr.facecount;
                uint facemask = sr.facemask;
                uint bit      = 1;
                int  resIdx   = 0;

                entries.Reserve(6);

                float nearPlaneOffset = QualitySettings.shadowNearPlaneOffset;

                while (facecnt > 0)
                {
                    if ((bit & facemask) != 0)
                    {
                        uint width  = widths[resIdx];
                        uint height = heights[resIdx];
                        uint ceIdx;
                        if (!Alloc(frameId, key, width, height, out ceIdx, payload))
                        {
                            entries.Purge(entries.Count() - originalEntryCount);
                            payload.Purge(payload.Count() - originalPayloadCount);
                            uint added = m_ActiveEntriesCount - originalActiveEntries;
                            for (uint i = originalActiveEntries; i < m_ActiveEntriesCount; ++i)
                            {
                                m_EntryCache.Swap(i, m_EntryCache.Count() - i - 1);
                            }
                            m_EntryCache.Purge(added, Free);
                            m_ActiveEntriesCount = originalActiveEntries;
                            return(false);
                        }

                        // read
                        CachedEntry ce = m_EntryCache[ceIdx];
                        // modify
                        Matrix4x4 vp;
                        if (sr.shadowType == GPUShadowType.Point)
                        {
                            vp = ShadowUtils.ExtractPointLightMatrix(lights[sr.index], key.faceIdx, 2.0f, out ce.current.view, out ce.current.proj, out ce.current.lightDir, out ce.current.splitData, m_CullResults, (int)sr.index);
                        }
                        else if (sr.shadowType == GPUShadowType.Spot)
                        {
                            vp = ShadowUtils.ExtractSpotLightMatrix(lights[sr.index], out ce.current.view, out ce.current.proj, out ce.current.lightDir, out ce.current.splitData);
                        }
                        else if (sr.shadowType == GPUShadowType.Directional)
                        {
                            vp = ShadowUtils.ExtractDirectionalLightMatrix(lights[sr.index], key.faceIdx, m_CascadeCount, m_CascadeRatios, nearPlaneOffset, width, height, out ce.current.view, out ce.current.proj, out ce.current.lightDir, out ce.current.splitData, m_CullResults, (int)sr.index);
                            m_TmpSplits[key.faceIdx]    = ce.current.splitData.cullingSphere;
                            m_TmpSplits[key.faceIdx].w *= ce.current.splitData.cullingSphere.w;
                        }
                        else
                        {
                            vp = Matrix4x4.identity; // should never happen, though
                        }
                        // write :(
                        m_EntryCache[ceIdx] = ce;

                        sd.worldToShadow = vp.transpose; // apparently we need to transpose matrices that are sent to HLSL
                        sd.scaleOffset   = new Vector4(ce.current.viewport.width * m_WidthRcp, ce.current.viewport.height * m_HeightRcp, ce.current.viewport.x, ce.current.viewport.y);
                        sd.texelSizeRcp  = new Vector2(m_WidthRcp, m_HeightRcp);
                        sd.PackShadowmapId(m_TexSlot, m_SampSlot, ce.current.slice);
                        sd.shadowType    = sr.shadowType;
                        sd.payloadOffset = payload.Count();
                        entries.AddUnchecked(sd);

                        resIdx++;
                        facecnt--;
                        key.shadowDataIdx++;
                    }
                    else
                    {
                        // we push a dummy face in, otherwise we'd need a mapping from face index to shadowData in the shader as well
                        entries.AddUnchecked(dummy);
                    }
                    key.faceIdx++;
                    bit <<= 1;
                }

                if (sr.shadowType == GPUShadowType.Directional)
                {
                    ShadowPayload sp = new ShadowPayload();
                    payload.Reserve(k_MaxCascadesInShader);
                    for (uint i = 0; i < k_MaxCascadesInShader; i++)
                    {
                        sp.Set(m_TmpSplits[i]);
                        payload.AddUnchecked(sp);
                    }
                }

                return(true);
            }