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."); } } }
protected override void PruneShadowCasters(Camera camera, VisibleLight[] lights, ref VectorArray <int> shadowRequests, ref ShadowRequestVector requestsGranted, out uint totalRequestCount) { Debug.Assert(shadowRequests.Count() > 0); // at this point the array is sorted in order of some importance determined by the prioritize function requestsGranted.Reserve(shadowRequests.Count()); totalRequestCount = 0; ShadowmapBase.ShadowRequest sreq = new ShadowmapBase.ShadowRequest(); uint totalSlots = ResetMaxShadows(); // there's a 1:1 mapping between the index in the shadowRequests array and the element in requestsGranted at the same index. // if the prune function skips requests it must make sure that the array is still compact m_TmpSortKeys.Reset(shadowRequests.Count()); for (uint i = 0, count = shadowRequests.Count(); i < count && totalSlots > 0; ++i) { int requestIdx = shadowRequests[i]; VisibleLight vl = lights[requestIdx]; bool add = false; int facecount = 0; GPUShadowType shadowType = GPUShadowType.Point; switch (vl.lightType) { case LightType.Directional: add = m_MaxShadows[(int)GPUShadowType.Directional, 0]-- >= 0; shadowType = GPUShadowType.Directional; facecount = m_ShadowSettings.directionalLightCascadeCount; break; case LightType.Point: add = m_MaxShadows[(int)GPUShadowType.Point, 0]-- >= 0; shadowType = GPUShadowType.Point; facecount = 6; break; case LightType.Spot: add = m_MaxShadows[(int)GPUShadowType.Spot, 0]-- >= 0; shadowType = GPUShadowType.Spot; facecount = 1; break; } if (add) { sreq.instanceId = vl.light.GetInstanceID(); sreq.index = (uint)requestIdx; sreq.facemask = (uint)(1 << facecount) - 1; sreq.shadowType = shadowType; totalRequestCount += (uint)facecount; requestsGranted.AddUnchecked(sreq); totalSlots--; } else { m_TmpSortKeys.AddUnchecked(requestIdx); } } // make sure that shadowRequests contains all light indices that are going to cast a shadow first, then the rest shadowRequests.Reset(); requestsGranted.ExtractTo(ref shadowRequests, (ShadowmapBase.ShadowRequest request) => { return((int)request.index); }); m_TmpSortKeys.ExtractTo(ref shadowRequests, (long idx) => { return((int)idx); }); }