private void ComputeAverageLuminance() { const int stepSize = 20; const float stepSizeF = stepSize; int numSteps = Height / stepSize; const float offsetStep = stepSizeF * 4; LuminanceSamples.Clear(); var query = new LightingQuery(Environment); var tp = new Squared.Util.Win32TimeProvider(); long startTicks = tp.Ticks; Parallel.For( 0, numSteps, () => new List<float>(), (yStep, state, samples) => { float y = yStep * stepSizeF; float xOffset = (y % offsetStep) / 8f; float localWidth = Width + xOffset; for (Vector2 position = new Vector2(xOffset, y); position.X < localWidth; position.X += stepSizeF) { var sample = query.ComputeReceivedLightAtPosition(position); var sampleLuminance = (sample.X * 0.299f) + (sample.Y * 0.587f) + (sample.Z * 0.114f); samples.Add(sampleLuminance); } return samples; }, (samples) => { lock (LuminanceSamples) LuminanceSamples.AddRange(samples); } ); long endTicks = tp.Ticks; TickCountSamples.Add(endTicks - startTicks); if (TickCountSamples.Count > RollingLength) TickCountSamples.RemoveAt(0); LuminanceSamples.Sort(); int outliersToSkip = (LuminanceSamples.Count * 4) / 100; float accumulator = 0; int count = 0; for (int i = outliersToSkip, e = Math.Max(LuminanceSamples.Count - outliersToSkip - 1, 0); i < e; i++) { accumulator += LuminanceSamples[i]; count += 1; } AverageLuminance = (accumulator / count) * LuminanceScaler; RollingAverageSamples.Add(AverageLuminance); if (RollingAverageSamples.Count > RollingLength) RollingAverageSamples.RemoveAt(0); }
private void ComputeAverageLuminance() { const int stepSize = 20; const float stepSizeF = stepSize; int numSteps = Height / stepSize; const float offsetStep = stepSizeF * 4; LuminanceSamples.Clear(); var query = new LightingQuery(Environment, true); var tp = new Squared.Util.Win32TimeProvider(); long startTicks = tp.Ticks; Parallel.For( 0, numSteps, () => new List <float>(), (yStep, state, samples) => { float y = yStep * stepSizeF; float xOffset = (y % offsetStep) / 8f; float localWidth = Width + xOffset; Vector4 sample; for (Vector2 position = new Vector2(xOffset, y); position.X < localWidth; position.X += stepSizeF) { if (query.ComputeReceivedLightAtPosition(position, out sample)) { var sampleLuminance = (sample.X * 0.299f) + (sample.Y * 0.587f) + (sample.Z * 0.114f); samples.Add(sampleLuminance); } } return(samples); }, (samples) => { lock (LuminanceSamples) LuminanceSamples.AddRange(samples); } ); long endTicks = tp.Ticks; TickCountSamples.Add(endTicks - startTicks); if (TickCountSamples.Count > RollingLength) { TickCountSamples.RemoveAt(0); } LuminanceSamples.Sort(); int outliersToSkip = (LuminanceSamples.Count * 4) / 100; float accumulator = 0; int count = 0; for (int i = outliersToSkip, e = Math.Max(LuminanceSamples.Count - outliersToSkip - 1, 0); i < e; i++) { accumulator += LuminanceSamples[i]; count += 1; } AverageLuminance = (accumulator / count) * LuminanceScaler; RollingAverageSamples.Add(AverageLuminance); if (RollingAverageSamples.Count > RollingLength) { RollingAverageSamples.RemoveAt(0); } }