예제 #1
0
            public override void ProcessShadowRequests(FrameId frameId, CullResults cullResults, Camera camera, VisibleLight[] lights, ref uint shadowRequestsCount, int[] shadowRequests, out int[] shadowDataIndices)
            {
                shadowDataIndices = null;

                // TODO:
                // Cached the cullResults here so we don't need to pass them around.
                // Allocate needs to pass them to the shadowmaps, as the ShadowUtil functions calculating view/proj matrices need them to call into C++ land.
                // Ideally we can get rid of that at some point, then we wouldn't need to cache them here, anymore.
                foreach (var sm in m_Shadowmaps)
                {
                    sm.Assign(cullResults);
                }

                if (shadowRequestsCount == 0 || lights == null || shadowRequests == null)
                {
                    shadowRequestsCount = 0;
                    return;
                }

                // first sort the shadow casters according to some priority
                PrioritizeShadowCasters(camera, lights, shadowRequestsCount, shadowRequests);

                // next prune them based on some logic
                VectorArray <int> requestedShadows = new VectorArray <int>(shadowRequests, 0, shadowRequestsCount, false);

                m_TmpRequests.Reset(shadowRequestsCount);
                uint totalGranted;

                PruneShadowCasters(camera, lights, ref requestedShadows, ref m_TmpRequests, out totalGranted);

                // if there are no shadow casters at this point -> bail
                if (totalGranted == 0)
                {
                    shadowRequestsCount = 0;
                    return;
                }

                // TODO: Now would be a good time to kick off the culling jobs for the granted requests - but there's no way to control that at the moment.

                // finally go over the lights deemed shadow casters and try to fit them into the shadow map
                // shadowmap allocation must succeed at this point.
                m_ShadowCtxt.ClearData();
                ShadowDataVector    shadowVector  = m_ShadowCtxt.shadowDatas;
                ShadowPayloadVector payloadVector = m_ShadowCtxt.payloads;

                m_ShadowIndices.Reset(m_TmpRequests.Count());
                AllocateShadows(frameId, lights, totalGranted, ref m_TmpRequests, ref m_ShadowIndices, ref shadowVector, ref payloadVector);
                Debug.Assert(m_TmpRequests.Count() == m_ShadowIndices.Count());
                m_ShadowCtxt.shadowDatas = shadowVector;
                m_ShadowCtxt.payloads    = payloadVector;

                // and set the output parameters
                uint offset;

                shadowDataIndices = m_ShadowIndices.AsArray(out offset, out shadowRequestsCount);
            }
예제 #2
0
            protected override void AllocateShadows(FrameId frameId, VisibleLight[] lights, uint totalGranted, ref ShadowRequestVector grantedRequests, ref ShadowIndicesVector shadowIndices, ref ShadowDataVector shadowDatas, ref ShadowPayloadVector shadowmapPayload)
            {
                ShadowData sd = new ShadowData();

                shadowDatas.Reserve(totalGranted);
                shadowIndices.Reserve(grantedRequests.Count());
                for (uint i = 0, cnt = grantedRequests.Count(); i < cnt; ++i)
                {
                    VisibleLight        vl  = lights[grantedRequests[i].index];
                    Light               l   = vl.light;
                    AdditionalLightData ald = l.GetComponent <AdditionalLightData>();

                    // set light specific values that are not related to the shadowmap
                    GPUShadowType shadowtype;
                    ShadowUtils.MapLightType(ald.archetype, vl.lightType, out sd.lightType, out shadowtype);
                    sd.bias    = l.shadowBias;
                    sd.quality = 0;

                    shadowIndices.AddUnchecked((int)shadowDatas.Count());

                    int smidx = 0;
                    while (smidx < k_MaxShadowmapPerType)
                    {
                        if (m_ShadowmapsPerType[(int)shadowtype, smidx].Reserve(frameId, ref sd, grantedRequests[i], (uint)ald.shadowResolution, (uint)ald.shadowResolution, ref shadowDatas, ref shadowmapPayload, lights))
                        {
                            break;
                        }
                        smidx++;
                    }
                    if (smidx == k_MaxShadowmapPerType)
                    {
                        throw new ArgumentException("The requested shadows do not fit into any shadowmap.");
                    }
                }

                // final step for shadowmaps that only gather data during the previous loop and do the actual allocation once they have all the data.
                foreach (var sm in m_Shadowmaps)
                {
                    if (!sm.ReserveFinalize(frameId, ref shadowDatas, ref shadowmapPayload))
                    {
                        throw new ArgumentException("Shadow allocation failed in the ReserveFinalize step.");
                    }
                }
            }