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); }
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."); } } }