예제 #1
0
 public PSSMLTSampler()
 {
     rnd =
         new FastRandom();
     //new HaltonSequence();
     TotalSamples = 0L;
     state = MCMCSamplerState.Initialized;
 }
예제 #2
0
        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;
        }
예제 #3
0
        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);
        }
예제 #4
0
 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;
 }
예제 #5
0
        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);
        }
예제 #6
0
        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);

            }
        }
예제 #7
0
 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;
 }