public Sample GetSample(Sample prevSample = null) { totalSamples++; if (prevSample == null) { var ns = new PsSample(this); ns.imageX = ns.GetLazyValue() * screenWidth; ns.imageY = ns.GetLazyValue() * screenHeight; ns.pass = pass; return ns; } prevSample.imageX = prevSample.GetLazyValue() * screenWidth; prevSample.imageY = prevSample.GetLazyValue() * screenHeight; prevSample.pass = pass; (prevSample as PsSample).MutationsCount = 0; (prevSample as PsSample).CurrentDim = 0; (prevSample as PsSample).MaxDimPrev = 0; return prevSample; }
public float GetLazyValue(Sample sample) { return sample.GetLazyValue(pass); }
public Sample GetSample(Sample prevSample) { TotalSamples++; if (!warmUpcomplete) { var wmsample = new Sample(this); var rx = wmsample.GetLazyValue(); var ry = wmsample.GetLazyValue(); wmsample.imageX = rx * screenWidth; wmsample.imageY = ry * screenHeight; warmUpcomplete = TotalSamples >= screenWidth * screenHeight * WarmupPasses; return wmsample; } #if VERBOSE if (TotalSamples == screenWidth * screenHeight * WarmupPasses+1) { Tracer.TraceLine("T{0} Warmup complete", tIdx); var sampleBlocks = new HashSet<SampleBlock>(); foreach (var sampleBlock in blocks) { if (!sampleBlocks.Contains(sampleBlock) && (sampleBlock.BlockError(Film) > ErrorStop)) { sampleBlock.CachedError = sampleBlock.BlockError(Film); sampleBlocks.Add(sampleBlock); } } this.blocks = sampleBlocks.ToList(); Tracer.TraceLine("T{0} duplicate removal complete", tIdx); Classify(blocks); Tracer.TraceLine("T{0} classification complete", tIdx); } #endif CurrentBlock.TotalSamples++; if (blocks.Count == 0) { this.Init(Width, Height); Tracer.TraceLine("Adaptive sampling complete! Start another iteration"); return null; } currentBlockSample++; if (currentBlockSample >= CurrentBlock.SamplesInBlock(ImportantBlockSamples)) { blockIndex++; currentBlockSample= 0; } if (blockIndex >= blocks.Count) { blockIndex = Math.Min(tIdx, blocks.Count - 1); } CurrentBlock = blocks[blockIndex]; if (CurrentBlock.TotalSamples >= CurrentBlock.SamplesPerIteration * CurrentBlock.BlockWidth * CurrentBlock.BlockHeight) { var blockError = CurrentBlock.BlockError(this.Film); if (blockError > ErrorSplit) { this.SplitBlock(CurrentBlock); } else if (blockError < ErrorStop) { #if VERBOSE Tracer.TraceLine("{0} Block is ready", blockIndex); Tracer.TraceLine("Rem block {0} block error {1} ", blocks[blockIndex].ToString(), blockError, blocks[blockIndex].BlockWidth, blocks[blockIndex].BlockHeight); #endif this.TotalSamples += this.CurrentBlock.SamplerPerBlock; #if VERBOSE Tracer.TraceLine("Block Count " + blocks.Count); #endif } else if (subBlocks.Count < 65535) { foreach (var block in blocks) { var proposalB = block.Split(block.SamplesPerIteration); foreach (var proposalBlock in proposalB) { if (proposalBlock.BlockError(Film) > block.BlockError(Film)) { //this.blocks.AddRange(proposalBlock.Split(CurrentBlock.SamplesPerIteration)); subBlocks.Add(proposalBlock); } else { //this.blocks.Add(proposalBlock); //this.blocks.AddRange(proposalBlock.Split(proposalBlock.SamplesPerIteration * 2)); subBlocks.AddRange(proposalBlock.Split(proposalBlock.SamplesPerIteration)); //foreach (var block in blocks) //{ // Film.StatsRect(block.Xstart, block.Ystart, block.BlockWidth, block.BlockHeight, blockIndex); //} } } } } #if VERBOSE //Tracer.TraceLine("T{4}- Removing {2}/{3} block {1} error {0}", blockError, CurrentBlock.ToString(), blocks.Count, blockIndex, tIdx); #endif this.blocks.Remove(CurrentBlock); if (blocks.Count == 0 && this.subBlocks.Count > 0) { Tracer.TraceLine("T{0} Dicing", tIdx); generation++; this.blocks = this.subBlocks.ToList(); this.subBlocks.Clear(); var sampleBlocks = new HashSet<SampleBlock>(); foreach (var sampleBlock in blocks) { if (!sampleBlocks.Contains(sampleBlock) && (sampleBlock.BlockError(Film) > ErrorStop)) { sampleBlock.CachedError = sampleBlock.BlockError(Film); sampleBlocks.Add(sampleBlock); } } #if VERBOSE Tracer.TraceLine("Removing {0} duplicates", this.blocks.Count - sampleBlocks.Count); Tracer.TraceLine("T{0} Generation {1} sampling", tIdx, generation); #endif Classify(blocks); } if (blockIndex >= this.blocks.Count) { this.blockIndex = 0; } this.CurrentBlock = this.blocks[blockIndex]; this.EvalCurrentBlock(); pass += CurrentBlock.SamplesPerIteration; #if VERBOSE2 for (int index = 0; index < blocks.Count; index++) { var block = blocks[index]; //bool remove = false; //if ((block.Xstart + block.BlockWidth) > screenWidth) //{ // Tracer.TraceLine("Invalid block Width " + (block.Xstart + block.BlockWidth)); // remove = true; //} //if ((block.Ystart + block.BlockHeight) > screenHeight) //{ // Tracer.TraceLine("Invalid block Height " + (block.Ystart + block.BlockHeight)); // remove = true; //} Film.StatsRect(block.Xstart, block.Ystart, block.BlockWidth, block.BlockHeight, blockIndex); //if (remove) //{ // blocks.RemoveAt(index); // Tracer.TraceLine("Removing invalid block {0} block size {2}x{3}", blockIndex, blockError, blocks[blockIndex].BlockWidth, blocks[blockIndex].BlockHeight); //} } #endif } CurrentBlock = blocks[blockIndex]; Sample sample = CurrentBlock.GetSample(this); return sample; }
public override void GenerateLiRays(IRayEngineScene scn, Sample sample, ref RayData ray, VolumeComputation comp) { comp.Reset(); var scene = (RayEngineScene)(scn); var sigs = sig_s; comp.EmittedLight = lightEmission; float t0, t1; if (!region.Intersect(ray, out t0, out t1)) return; if (sigs.IsBlack() || (scene.Lights.Length < 1)) { float distance = t1 - t0; comp.EmittedLight = lightEmission * distance; } else { // Prepare for volume integration stepping float distance = t1 - t0; var nSamples = MathLab.Ceil2UInt(distance / stepSize); float step = distance / nSamples; RgbSpectrum Tr = new RgbSpectrum(1f); RgbSpectrum Lv = new RgbSpectrum(); var p = ray.Point(t0); float offset = sample.GetLazyValue(); t0 += offset * step; //Vector pPrev; for (var i = 0; i < nSamples; ++i, t0 += step) { //pPrev = p; p = ray.Point(t0); Sigma_s(ref p, out sigs); //sigs = NoiseProvider.Instance.Noise3D(((Vector)p).Normalize()); Lv += lightEmission; if (!sigs.IsBlack() && (scene.Lights.Length) > 0) { // Select the light to sample float lightStrategyPdf; var light = scene.Lights[scene.SampleLights(sample.GetLazyValue(), out lightStrategyPdf)]; // Select a point on the light surface float lightPdf; Normal fakeNorml = new Normal(0f, 0f, 1f); LightSample ls = new LightSample(); light.EvaluateShadow(ref p, ref fakeNorml, sample.GetLazyValue(), sample.GetLazyValue(), sample.GetLazyValue(), ref ls); var lightColor = (RgbSpectrumInfo)(ls.Spectrum); lightPdf = ls.Pdf; comp.Rays[comp.RayCount] = ls.LightRay; if ((lightPdf > 0f) && !lightColor.IsBlack()) { comp.ScatteredLight[comp.RayCount] =(RgbSpectrum)(Tr * sigs * lightColor * MathLab.Exp(-distance) * ((Density(ref p) * step) / (4f * MathLab.M_PI * lightPdf * lightStrategyPdf))); comp.RayCount++; } } comp.EmittedLight = Lv * step; } } }
public PathVertexData CreateEyeVertex(ICamera camera, Sample sample) { IRay ray; camera.GetRay(sample.imageX, sample.imageY, out ray); return new PathVertexData() { Flags = (byte)PathVertexType.Camera, CameraPoint = ray.Origin, CameraDirection = ray.Direction, Lens = new UV(sample.GetLazyValue(), sample.GetLazyValue()), Time = sample.GetLazyValue() }; }
public PathVertexData CreateLightVertex(Sample Sample) { LightSample ls; var light = context.Scene.Lights[context.Scene.SampleLights(Sample.GetLazyValue())]; light.EvaluatePhoton(context.Scene, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), out ls); var ray = ls.LightRay; var weight = ls.Pdf * (1f / context.Scene.Lights.Length); var thr = (RgbSpectrum)(ls.Spectrum) * weight; return new PathVertexData { Flags = (byte)PathVertexType.Light, Emission = thr, HitPoint = ray.Org, OutgoingDirection = ray.Dir, }; }
public PathVertex CreatePathVertex(ref RayData ray, ref RayHit rayHit, Sample Sample) { PathVertex result = null; bool missed = rayHit.Index == 0xffffffffu; if (missed) { if (scene.EnvironmentMap == null) { result = new EnvironmentPathVertex() { IncomingDirection = -ray.Dir }; } else { result = new ImplicitLightVertex() { IncomingDirection = -ray.Dir, Light = scene.EnvironmentMap }; } return result; } var hitInfo = surfaceSampler.GetIntersection(ref ray, ref rayHit); var hitPoint = ray.Point(rayHit.Distance); var currentTriangleIndex = (int)rayHit.Index; if (hitInfo.IsLight) { var lt = scene.GetLightByIndex(currentTriangleIndex); result = new ImplicitLightVertex() { IncomingDirection = -ray.Dir, Light = lt, HitItemId = currentTriangleIndex, Point = hitPoint }; } else { Vector wo = -ray.Dir; float fPdf; Vector wi; bool specularBounce; float u0 = Sample.GetLazyValue(), u1 = Sample.GetLazyValue(), u2 = Sample.GetLazyValue(), u3 = Sample.GetLazyValue(); var bsdf = hitInfo.MMaterial; var throughput = RgbSpectrum.Unit; RgbSpectrum f = bsdf.Sample_f(ref wo, out wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref throughput, u0, u1, u2, ref hitInfo.TextureData, out fPdf, out specularBounce); result = new GeometryVertex() { BsdfSampleWeight = fPdf, GeometryNormal = hitInfo.Normal, ShadingNormal = hitInfo.ShadingNormal, HitItemId = currentTriangleIndex, IncomingDirection = wo, OutgoingDirection = wi, Point = hitPoint, Sample = f, u0 = u0, u1 = u1, u2 = u2, u3 = u3, SampledBsdf = bsdf }; } return result; }
public ExplicitLightVertex CreateLightVertex(Sample sample, GeometryVertex vertex) { int currentLightIndex = scene.SampleLights(sample.GetLazyValue()); var light = scene.Lights[currentLightIndex]; var ls = new LightSample(); light.EvaluateShadow(ref vertex.Point, ref vertex.GeometryNormal, sample.GetLazyValue(), sample.GetLazyValue(), sample.GetLazyValue(), ref ls); if (ls.Pdf <= 0f) { throw new Exception(); } /* secRays[tracedShadowRayCount].color = new RgbSpectrum(ls.Spectrum); secRays[tracedShadowRayCount].pdf = ls.Pdf; secRays[tracedShadowRayCount].shadowRay = ls.LightRay; Vector lwi = secRays[tracedShadowRayCount].shadowRay.Dir; RgbSpectrum fs; hitInfo.MMaterial.f( ref secRays[tracedShadowRayCount].shadowRay.Dir, ref wo, ref hitInfo.ShadingNormal, out fs, BrdfType.Diffuse); secRays[tracedShadowRayCount].color *= lightTroughtput * Vector.AbsDot(ref hitInfo.ShadingNormal, ref lwi) * fs; */ return new ExplicitLightVertex() { }; }