public PSSMLTSampler() { rnd = new FastRandom(); //new HaltonSequence(); TotalSamples = 0L; state = MCMCSamplerState.Initialized; }
public Sample GetSample(Sample prevSample) { Sample newSample = null; switch (state) { case MCMCSamplerState.Initialized: if (currentSample == null) { currentSample = GetNewSample(true); } newSample = GetNewSample(false); newSample.sampleData = currentSample.sampleData; initializedSamples++; if (initializedSamples > screenWidth*screenHeight*4) { state = MCMCSamplerState.LargeStep; } return newSample; case MCMCSamplerState.LargeStep: currentSample = GetNewSample(true); currentMutation = 0; state = MCMCSamplerState.SmallStep; break; case MCMCSamplerState.SmallStep: currentSample = Mutate(prevSample??currentSample, currentMutation++, MaxMutations); if (currentMutation >= MaxMutations) { state = MCMCSamplerState.LargeStep; currentSample = GetNewSample(true); currentMutation = 0; } break; } if (GetLazyValue(currentSample) < LargeStepProbability) { state = MCMCSamplerState.LargeStep; } return currentSample; }
public override void Splat(SampleBuffer sampleBuffer) { //Check tentative prob //Add contribution //Change state // Change sample state in init by ChangedState var yImportance = sampler.EvalImportance(ref Throughput, pathWeight); float sampleWeight = yImportance; if (yImportance<=0f) goto @init; var yContribution = Radiance / yImportance; bool accept; float a = 0f; if (!sampler.ImportanceReady) { sampler.Add_B(ref yContribution); sampleBuffer.SplatSample(this.Sample.imageX, this.Sample.imageY, ref Radiance); this.InitPath(this.pathIntegrator); return; } if (yImportance > 0f) { if ((SamplerState != MCMCSamplerState.SmallStep || xImportance <= 0f || mutate)) { SwitchToSmallStep(yImportance, pathWeight, ref yContribution); goto init; //Print(string.Format("{0} changed state to {1}", this.SamplerID, this.SamplerState)); } else if (SamplerState == MCMCSamplerState.SmallStep) { a = Math.Min(1f, (yImportance/xImportance)); //contrib = (contrib / sampler.Importance) / sampler.MaxMutations; sampleWeight = a; this.mutationsCount++; if (sampler.NextFloat() < a) { xImportance = yImportance; this.xContribution = yContribution; //this.TentativeSample = new Sample(this.Sample); Push(); accept = true; //this.pathWeight = a; } else { if (!this.Pop()) { //Print("Chain restart - stack empty - mutations " + mutationsCount); //sampleBuffer.SplatSample(this.Sample.imageX, this.Sample.imageY, ref contrib, 1f-a); this.Sample = new Sample(this.TentativeSample); rejectCount++; this.pathWeight = this.TentativeWeight; } //Splat = false; //return; } /* * */ //var newSample = sampler.GetNextSample(this.Sample, I, oldI, 1.0f, ref contrib, out outC, out newW, false); } } else if (xImportance >= 0f && this.SamplerState == MCMCSamplerState.SmallStep) { if (!this.Pop()) { if (this.TentativeSample != null) { //Print("Chain restart - stack empty - mutations " + mutationsCount); //sampleBuffer.SplatSample(this.Sample.imageX, this.Sample.imageY, ref contrib, 1f-a); this.Sample = new Sample(this.TentativeSample); rejectCount++; this.pathWeight = this.TentativeWeight; } else { this.SamplerState = MCMCSamplerState.LargeStep; } } } if (!xContribution.IsBlack()) { //sampleWeight *= 1f/pathWeight; //contrib *= (1f/sampler.MaxMutations); //contrib *= new RgbSpectrum((float)this.sampler.B[0],(float)this.sampler.B[1],(float)this.sampler.B[2]); var contribution = xContribution; /* if (accept) { contribution *= sampleWeight*sampler.Importance; } else { contribution *= (1f - sampleWeight) * sampler.Importance; } */ sampleBuffer.SplatSample(this.Sample.imageX, this.Sample.imageY, ref contribution); } if ((mutationsCount >= sampler.MaxMutations) & (sampler.NextFloat() > (1f - sampler.LargeStepProb)))//time > mutationsCount || { this.SamplerState = MCMCSamplerState.LargeStep; this.time = 0; //Print(string.Format("{0} changed state to {1}", this.SamplerID, this.SamplerState)); //Print("Chain restart - max mutations"); } @init: this.InitPath(this.pathIntegrator); }
private void SwitchToSmallStep(float imp, float pathW, ref RgbSpectrum contribution) { this.xImportance = imp; this.xContribution = contribution; this.TentativeSample = new Sample(this.Sample); this.TentativeWeight = pathW; Push(); this.SamplerState = MCMCSamplerState.SmallStep; }
public override void Splat(SampleBuffer sampleBuffer) { //Check tentative prob //Add contribution //Change state // Change sample state in init by ChangedState if (!sampler.ImportanceReady) { sampler.Add_B(ref Radiance); sampleBuffer.SplatSample(this.Sample.imageX, this.Sample.imageY, ref Radiance); this.InitPath(this.pathIntegrator); return; } var yImportance = sampler.EvalImportance(ref Radiance, pathWeight); if (yImportance <= 0f || Radiance.IsBlack()) { if (SamplerState == MCMCSamplerState.SmallStep) { mutationsCount++; } goto @init; } float sampleWeight = 1f; float a; var yContribution = Radiance / Radiance.y(); var contrib = yContribution; switch (SamplerState) { case MCMCSamplerState.Initialized: case MCMCSamplerState.LargeStep: if (xImportance <= 0f || mutate) { SwitchToSmallStep(yImportance, pathWeight, ref yContribution); goto init; //Print(string.Format("{0} changed state to {1}", this.SamplerID, this.SamplerState)); } break; } if (yImportance > 0f) { if (SamplerState == MCMCSamplerState.SmallStep) { a = Math.Min(1f, (yImportance / xImportance)); //contrib = (contrib / sampler.Importance) / sampler.MaxMutations; sampleWeight = a; this.mutationsCount++; if (sampler.NextFloat() < a) { xImportance = yImportance; this.xContribution = yContribution; contrib = yContribution*a; //this.TentativeSample = new Sample(this.Sample); Push(); //this.pathWeight = a; } else { contrib = yContribution*(1f - a); if (!this.Pop()) { //Print("Chain restart - stack empty - mutations " + mutationsCount); //sampleBuffer.SplatSample(this.Sample.imageX, this.Sample.imageY, ref contrib, 1f-a); this.Sample = new Sample(this.TentativeSample); rejectCount++; this.pathWeight = this.TentativeWeight; } //Splat = false; //return; } //var newSample = sampler.GetNextSample(this.Sample, I, oldI, 1.0f, ref contrib, out outC, out newW, false); } RgbSpectrum c = contrib * (sampler.Importance/ sampler.MaxMutations) * sampler.LargeStepProb; //var c = Radiance*sampleWeight*sampler.Br; sampleBuffer.SplatSample(this.Sample.imageX, this.Sample.imageY, ref c); } @init: if (rejectCount >= sampler.MaxMutations) { this.SamplerState = MCMCSamplerState.LargeStep; } if ((mutationsCount >= sampler.MaxMutations) || (sampler.NextFloat() > (1f - sampler.LargeStepProb)))//time > mutationsCount || { this.SamplerState = MCMCSamplerState.LargeStep; this.time = 0; //Print(string.Format("{0} changed state to {1}", this.SamplerID, this.SamplerState)); //Print("Chain restart - max mutations"); } this.InitPath(this.pathIntegrator); }
public Sample EvalNextSample(Sample oldSample, float importance) { if (oldSample == null) return GetSample(null); switch (SamplerState) { case MCMCSamplerState.LargeStep: case MCMCSamplerState.Initialized: if (importance > 0f) { this.SamplerState = MCMCSamplerState.SmallStep; this.mutationsCount = 0; this.TentativeSample = new Sample(oldSample); this.ChainStart = new Sample(oldSample); this.TentativeWeight = importance; this.TotalSamples++; return this.TentativeSample; } else { return this.GetSample(null); } case MCMCSamplerState.SmallStep: if (importance > 0f) { mutationsCount++; PushSample(); this.SmallStep(); } else { if (!PopSample()) { this.TentativeSample = new Sample(ChainStart); } } if (mutationsCount > MaxMutations || (rnd.NextFloat() < LargeStepProb)) { this.SamplerState = MCMCSamplerState.LargeStep; this.mutationsCount = 0; return GetSample(null); } this.TotalSamples++; return this.TentativeSample; default: return GetSample(null); } }
public void Init(int width, int height) { rnd.Reinitialise((int)DateTime.Now.Ticks); if (screenWidth == 0 && screenHeight == 0) { Width = screenWidth = width; Height = screenHeight = height; screenWidth = width - 1; screenHeight = height - 1; } currentSampleScreenX = 0; currentSampleScreenY = screenStartLine; currentSubSampleIndex = 0; pass = 0; this.SamplerState = MCMCSamplerState.Initialized; }