public override void InitPath(IPathProcessor buffer) { base.InitPath(buffer); this.scene = pathIntegrator.Scene; this.Radiance = new RgbSpectrum(0f); this.waveRadiance = 0f; this.waveThroughput = 1f; this.PathState = PathTracerPathState.EyeVertex; if (this.secRays == null) this.secRays = new ShadowRayInfo[scene.ShadowRaysPerSample]; if (lambdaSample == 0) { this.Sample = pathIntegrator.Sampler.GetSample(this.Sample); this.Sample.InitSample(scene.MaxPathDepth*8); pathIntegrator.Scene.Camera.GetRay(Sample.imageX, Sample.imageY, out this.PathRay); } this.HeroWavelength = this.wlSampler.SampleWavelength( lambdaSample); //Sample.GetLazyValue(0)); this.RayIndex = -1; this.pathWeight = 1.0f; this.tracedShadowRayCount = 0; this.depth = 0; this.specularBounce = true; }
public override void InitPath(IPathProcessor buffer) { base.InitPath(buffer); this.scene = pathIntegrator.Scene; this.PathState = PathTracerPathState.EyeVertex; if (this.secRays == null) this.secRays = new ConnectRayInfo[MaxEyeRays]; this.RayIndex = -1; this.pathWeight = 1.0f; this.tracedShadowRayCount = 0; this.depth = 0; this.specularBounce = true; this.Radiance = new RgbSpectrum(0f); this.Sample = pathIntegrator.Sampler.GetSample(null); LightSample ls; var light = scene.Lights[scene.SampleLights(Sample.GetLazyValue())]; light.EvaluatePhoton(scene, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), out ls); PathRay = ls.LightRay; var lightPdf = ls.Pdf; Throughput = (RgbSpectrum)(ls.Spectrum); //* scene.Lights.Length) / lightPdf; //buffer.Scene.Camera.GetRay(Sample.imageX, Sample.imageY, out this.PathRay); }
public override void InitPath(IPathProcessor buffer) { base.InitPath(buffer); this.scene = pathIntegrator.Scene; this.Radiance = new RgbSpectrum(0f); this.Throughput = new RgbSpectrum(1f); this.PathState = PathTracerPathState.EyeVertex; if (this.secRays == null) this.secRays = new ShadowRayInfo[scene.ShadowRayCount]; if (this.volumeComp == null) { this.volumeComp = scene.GetVolumeComputation(); } else { this.volumeComp.Reset(); } this.Sample = pathIntegrator.Sampler.GetSample(null); IRay ray; pathIntegrator.Scene.Camera.GetRay(Sample.imageX, Sample.imageY, out ray); this.PathRay = (RayData)ray; this.RayIndex = -1; this.pathWeight = 1.0f; this.tracedShadowRayCount = 0; this.depth = 0; this.specularBounce = true; this.rayID = (int)(Sample.imageX + Sample.imageY * 640f); }
public override void InitPath(IPathProcessor buffer) { base.InitPath(buffer); this.scene = pathIntegrator.Scene; this.Radiance = new RgbSpectrum(0f); this.Throughput = new RgbSpectrum(1f); this.PathState = PathTracerPathState.EyeVertex; if (this.secRays == null) { this.secRays = new ShadowRayInfo[scene.ShadowRaysPerSample]; continueRays = new ShadowRayInfo[scene.ShadowRaysPerSample]; } if (volumeComp == null) { volumeComp = new VolumeComputation(scene.VolumeIntegrator); } contCount = 0; this.Sample = pathIntegrator.Sampler.GetSample(this.Sample); pathIntegrator.Scene.Camera.GetRay(Sample.imageX, Sample.imageY, out this.PathRay); this.RayIndex = -1; this.pathWeight = 1.0f; this.tracedShadowRayCount = 0; this.depth = 0; this.specularBounce = true; this.inVolume = false; }
public override void InitPath(IPathProcessor buffer) { base.InitPath(buffer); if (secRays == null) { secRays = new ShadowRayInfo[scene.ShadowRayCount]; } PathState = PathTracerPathState.EyeVertex; }
public override void InitPath(PathBuffer buffer) { base.InitPath(buffer); this.scene = buffer.Scene; this.Radiance = new RgbSpectrum(0f); this.Throughput = new RgbSpectrum(1f); this.PathState = PathTracerPathState.EyeVertex; this.Sample = buffer.Sampler.GetSample(); this.PathRay = new RayData ( scene.Camera.GetRay(Sample.imageX, Sample.imageY)); this.RayIndex = -1; this.pathWeight = 1.0f; this.tracedShadowRayCount = 0; this.depth = 0; this.specularBounce = true; }
public override void InitPath(IPathProcessor buffer) { base.InitPath(buffer); this.scene = pathIntegrator.Scene; this.Radiance = new SampledSpectrum(0f); this.Throughput = new SampledSpectrum(1f); this.PathState = PathTracerPathState.EyeVertex; if (this.secRays == null) this.secRays = new SpectralShadowRayInfo[scene.ShadowRaysPerSample]; this.Sample = pathIntegrator.Sampler.GetSample(null); pathIntegrator.Scene.Camera.GetRay(Sample.imageX, Sample.imageY, out this.PathRay); this.RayIndex = -1; this.pathWeight = 1.0f; this.tracedShadowRayCount = 0; this.depth = 0; this.specularBounce = true; }
public override void InitPath(IPathProcessor buffer) { base.InitPath(buffer); this.scene = pathIntegrator.Scene; if (Vertices == null) { Vertices = new PathVertex[scene.MaxPathDepth * 3]; Xvertices = new PathVertex[scene.MaxPathDepth * 3]; } this.pathDensity = 1.0f; this.Radiance = new RgbSpectrum(0f); this.Throughput = new RgbSpectrum(1f); this.PathState = PathTracerPathState.EyeVertex; if (!mutate) { this.Sample = pathIntegrator.Sampler.GetSample(this.Sample); pathIntegrator.Scene.Camera.GetRay(Sample.imageX, Sample.imageY, out this.PathRay); pathStart = PathRay.Org; XRadiance = new RgbSpectrum(); xPathDensity = 1.0f; } else { PathRay.Org = pathStart; PathRay.Dir = -Vertices[0].Wo; this.BackupPath(); this.MutatePath(); mutationCount++; if (mutationCount > MaxMutations) { this.mutate = false; this.mutationCount = 0; this.InitPath(buffer); } } this.RayIndex = -1; this.depth = 0; this.bsdfEvent = BsdfEvent.Specular; this.prevEvent = BsdfEvent.None; shadowRayEvent = BsdfEvent.None; }
public override void InitPath(IPathProcessor buffer) { base.InitPath(buffer); this.scene = pathIntegrator.Scene; this.Radiance = new RgbSpectrum(0f); this.Throughput = new RgbSpectrum(1f); this.PathState = PathTracerPathState.EyeVertex; if (this.secRays == null) { this.secRays = new ShadowRayInfo[scene.ShadowRaysPerSample]; continueRays = new ShadowRayInfo[scene.ShadowRaysPerSample]; } if (paths == null) { paths = new List<PathInfo>(); } if (CurrentVertices == null) { CurrentVertices = new List<PathVertex>(); } else { CurrentVertices.Clear(); } contCount = 0; this.Sample = pathIntegrator.Sampler.GetSample(this.Sample); pathIntegrator.Scene.Camera.GetRay(Sample.imageX, Sample.imageY, out this.PathRay); this.EyeSample = new CameraSample() { imageX = (float)Sample.imageX, imageY = (float)Sample.imageY, EyeRay = this.PathRay }; this.RayIndex = -1; this.pathWeight = 1.0f; this.tracedShadowRayCount = 0; this.depth = 0; this.specularBounce = true; }
public override void InitPath(IPathProcessor buffer) { base.InitPath(buffer); this.scene = pathIntegrator.Scene; this.Radiance = new RgbSpectrum(0f); this.Throughput = new RgbSpectrum(1f); this.PathState = PathTracerPathState.EyeVertex; this.secRays = new ShadowRayInfo[scene.ShadowRayCount]; this.sampler = (MarkovChainSampler)pathIntegrator.Sampler; this.Sample = this.sampler.EvalNextSample(this.Sample, xImportance); IRay ray; pathIntegrator.Scene.Camera.GetRay(Sample.imageX, Sample.imageY, out ray); this.PathRay = (RayData)ray; this.RayIndex = -1; this.pathWeight = 1.0f; this.tracedShadowRayCount = 0; this.depth = 0; this.specularBounce = true; }
public override void InitPath(IPathProcessor buffer) { base.InitPath(buffer); this.scene = pathIntegrator.Scene; this.Radiance = new RgbSpectrum(0f); this.Throughput = new RgbSpectrum(1f); this.PathState = PathTracerPathState.EyeVertex; if (this.secRays == null) { this.secRays = new ShadowRayInfo[scene.ShadowRaysPerSample+10]; continueRays = new ShadowRayInfo[scene.ShadowRaysPerSample+10]; } contCount = 0; this.Sample = pathIntegrator.Sampler.GetSample(this.Sample); pathIntegrator.Scene.Camera.GetRay(Sample.imageX, Sample.imageY, out this.PathRay); this.RayIndex = -1; this.tracedShadowRayCount = 0; this.depth = 0; this.bsdfEvent = BsdfEvent.Specular; this.prevEvent = BsdfEvent.None; shadowRayEvent = BsdfEvent.None; }
public override sealed void Advance(RayBuffer rayBuffer, SampleBuffer consumer) { int currentTriangleIndex = 0; #if VERBOSE try { #endif if (((PathState == PathTracerPathState.ShadowRaysOnly) || (PathState == PathTracerPathState.NextVertex)) && (tracedShadowRayCount > 0)) { for (int i = 0; i < tracedShadowRayCount; ++i) { RayHit shadowRayHit = rayBuffer.rayHits[secRays[i].ShadowRayIndex]; RgbSpectrum attenuation; bool continueTrace; if (this.VolumeShadowRayTest(ref shadowRayHit, ref secRays[i].ShadowRay, out attenuation, out continueTrace)) { Radiance += attenuation * ((secRays[i].Throughput) / secRays[i].Pdf); pathWeight *= secRays[i].Pdf; } if (continueTrace) { continueRays[contCount++] = secRays[i]; //continueRays.Add(secRays[i]); } } if (PathState == PathTracerPathState.ShadowRaysOnly) { Splat(consumer); return; } Array.Copy(continueRays, secRays, contCount); tracedShadowRayCount = contCount; contCount = 0; } RayHit rayHit = rayBuffer.rayHits[RayIndex]; Vector wo = -PathRay.Dir; depth++; bool missed = rayHit.Index == 0xffffffffu; if (missed || PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth) { if (missed) { //Radiance += this.scene.SampleEnvironment(ref wo) * Throughput; var sampledEnvironment = this.scene.SampleEnvironment(ref wo); Radiance.MAdd(ref sampledEnvironment, ref Throughput); } Splat(consumer); return; } //var mesh = scene.GetMeshByTriangleIndex(currentTriangleIndex); //rayHit.Index += (uint)mesh.StartTriangle; // Something was hit if (hitInfo == null) { hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit); } else { SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, ref hitInfo); } currentTriangleIndex = (int)rayHit.Index; if (hitInfo == null) { Debugger.Break(); } //If Hit light) if (hitInfo.IsLight) { if (specularBounce || depth == 1) { var lt = scene.GetLightByIndex(currentTriangleIndex); if (lt != null) { float pdf; var le = hitInfo.Color * lt.Emittance(ref wo, out pdf); //Radiance += Throughput * le; Radiance.MAdd(ref Throughput, ref le); } } Splat(consumer); return; } var hitPoint = PathRay.Point(rayHit.Distance); if (inVolume && !hitInfo.isVolume) { Throughput *= Math.Exp(-rayHit.Distance*0.1f); } inVolume = false; if (hitInfo.isVolume) { //if (Sample.GetLazyValue() <= scene.VolumeIntegrator.GetRRProbability()) //{ // RayData volumeRay = new RayData(ref PathRay.Org, ref PathRay.Dir, 0f, // rayHit.Miss() ? 1e10f : rayHit.Distance); // scene.VolumeIntegrator.GenerateLiRays(scene, Sample, ref volumeRay, volumeComp); // Radiance += volumeComp.GetEmittedLight(); // if (volumeComp.GetRayCount() > 0) // { // PathState = PathTracerPathState.EyeVolume; // rayHit = (rayBuffer.rayHits[RayIndex]); // } //} inVolume = true; RgbSpectrum sigma_s = hitInfo.VolumeData.Scattering; RgbSpectrum sigma_a = hitInfo.VolumeData.Absorbance; RgbSpectrum sigma_e = hitInfo.VolumeData.Emittance; var distance = SampleDistance(Sample.GetLazyValue(), sigma_s.y()); hitPoint = PathRay.Point(rayHit.Distance + distance); var eventEps = Sample.GetLazyValue(); if (eventEps > (sigma_a.y() + sigma_e.y() + sigma_e.y())) { Throughput *= RgbSpectrum.Exp(-distance * sigma_s); PathRay.Org = hitPoint; PathState = PathTracerPathState.NextVertex; return; } if (sigma_e.y() > 0f && eventEps > sigma_e.y()) { Radiance += Throughput * sigma_e; Splat(consumer); return; } if (eventEps < sigma_a.y()) { Radiance += Throughput * sigma_a; if (tracedShadowRayCount > 0) { PathState = PathTracerPathState.ShadowRaysOnly; } else { Splat(consumer); return; } } else //if (eventEps > sigma_a.y() ) { var pdf = 1f - MathLab.Exp(-sigma_s.y() * distance); var vwi = new Vector(Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue()); var fp = PhaseFunctions.PhaseIsotropic(ref wo, ref vwi); Throughput *= (fp * ((sigma_s+sigma_a)*0.5f) ); PathRay.Org = hitPoint + wo * distance; PathRay.Dir = vwi.Normalize(); PathState = PathTracerPathState.NextVertex; return; } } tracedShadowRayCount = 0; var bsdf = hitInfo.MMaterial; if (!hitInfo.TextureData.Alpha.IsBlack()) { Throughput *= (RgbSpectrum.UnitSpectrum() - (RgbSpectrum)hitInfo.TextureData.Alpha); PathRay = new RayData(hitPoint, -wo); return; } if (bsdf.IsDiffuse()) { float lightStrategyPdf = LightSampler.StrategyPdf; //scene.ShadowRaysPerSample/(float)scene.Lights.Length; RgbSpectrum lightTroughtput = Throughput * hitInfo.Color; LightSampler.EvaluateShadow(ref hitPoint, ref hitInfo.Normal, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), ref ls); for (int index = 0; index < ls.Length; index++) { if (ls[index].Pdf <= 0f) continue; secRays[tracedShadowRayCount].Throughput = ls[index].Spectrum.GetType() == typeof(RgbSpectrumInfo) ? (RgbSpectrum)(RgbSpectrumInfo)ls[index].Spectrum : (RgbSpectrum)ls[index].Spectrum; secRays[tracedShadowRayCount].Pdf = ls[index].Pdf; secRays[tracedShadowRayCount].ShadowRay = ls[index].LightRay; Vector lwi = secRays[tracedShadowRayCount].ShadowRay.Dir; RgbSpectrum fs; hitInfo.MMaterial.f(ref secRays[tracedShadowRayCount].ShadowRay.Dir, ref wo, ref hitInfo.ShadingNormal, ref Throughput, out fs, types: BrdfType.Diffuse); secRays[tracedShadowRayCount].Throughput *= lightTroughtput * Vector.AbsDot(ref hitInfo.Normal, ref lwi) * fs; if (!secRays[tracedShadowRayCount].Throughput.IsBlack()) { #if DEBUG RayDen.Library.Core.Components.Assert.IsNotNaN(secRays[tracedShadowRayCount].Pdf); #endif secRays[tracedShadowRayCount].Pdf /= lightStrategyPdf; tracedShadowRayCount++; } } } float fPdf = 0f; var wi = new Vector(); RgbSpectrum f; hitInfo.TextureData.Throughput = Throughput; f = bsdf.Sample_f(ref wo, out wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref Throughput, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue() , ref hitInfo.TextureData, out fPdf, out specularBounce); if ((fPdf <= 0.0f) || f.IsBlack()) { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } pathWeight *= fPdf; Throughput *= (f * hitInfo.Color) / fPdf; if (depth > scene.MaxPathDepth) { float prob = Math.Max(Throughput.Filter(), scene.RussianRuletteImportanceCap); if (prob >= Sample.GetLazyValue()) { Throughput /= prob; pathWeight *= prob; } else { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } } PathRay.Org = hitPoint; PathRay.Dir = wi.Normalize(); PathState = PathTracerPathState.NextVertex; #if VERBOSE } catch (Exception ex) { RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Advance path exception"); RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Error triangle {0}", currentTriangleIndex); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace); } #endif }
public override sealed void Advance(RayBuffer rayBuffer, SampleBuffer consumer) { int currentTriangleIndex = 0; #if VERBOSE try { #endif if (((PathState == PathTracerPathState.ShadowRaysOnly) || (PathState == PathTracerPathState.NextVertex)) && (tracedShadowRayCount > 0)) { for (int i = 0; i < tracedShadowRayCount; ++i) { RayHit shadowRayHit = rayBuffer.rayHits[secRays[i].ShadowRayIndex]; RgbSpectrum attenuation; bool continueTrace; if (this.ShadowRayTest(ref shadowRayHit, ref secRays[i].ShadowRay, out attenuation, out continueTrace)) { Radiance += attenuation * ((secRays[i].Throughput) / secRays[i].Pdf); pathWeight *= secRays[i].Pdf; } if (continueTrace) { continueRays[contCount++] = secRays[i]; //continueRays.Add(secRays[i]); } } if (PathState == PathTracerPathState.ShadowRaysOnly) { Splat(consumer); return; } Array.Copy(continueRays, secRays, contCount); tracedShadowRayCount = contCount; contCount = 0; } RayHit rayHit = rayBuffer.rayHits[RayIndex]; Vector wo = -PathRay.Dir; depth++; bool missed = rayHit.Index == 0xffffffffu; if (missed || PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth) { if (missed) { //Radiance += this.scene.SampleEnvironment(ref wo) * Throughput; var sampledEnvironment = this.scene.SampleEnvironment(ref wo); Radiance.MAdd(ref sampledEnvironment , ref Throughput); } Splat(consumer); return; } //var mesh = scene.GetMeshByTriangleIndex(currentTriangleIndex); //rayHit.Index += (uint)mesh.StartTriangle; // Something was hit if (hitInfo == null) { hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit); } else { SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, ref hitInfo); } currentTriangleIndex = (int)rayHit.Index; if (hitInfo == null) { Debugger.Break(); } //If Hit light) if (hitInfo.IsLight) { if (specularBounce || depth == 1) { var lt = scene.GetLightByIndex(currentTriangleIndex); if (lt != null) { float pdf; var le = hitInfo.Color * lt.Emittance(ref wo, out pdf); //Radiance += Throughput * le; Radiance.MAdd(ref Throughput, ref le); } } Splat(consumer); return; } var hitPoint = PathRay.Point(rayHit.Distance); tracedShadowRayCount = 0; var bsdf = hitInfo.MMaterial; if (!hitInfo.TextureData.Alpha.IsBlack()) { Throughput *= (RgbSpectrum.UnitSpectrum() - (RgbSpectrum) hitInfo.TextureData.Alpha); PathRay = new RayData(hitPoint, -wo); return; } if (bsdf.IsDiffuse()) { float lightStrategyPdf = LightSampler.StrategyPdf; //scene.ShadowRaysPerSample/(float)scene.Lights.Length; RgbSpectrum lightTroughtput = Throughput * hitInfo.Color; LightSampler.EvaluateShadow(ref hitPoint, ref hitInfo.Normal, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), ref ls); for (int index = 0; index < ls.Length; index++) { if (ls[index].Pdf <= 0f) continue; secRays[tracedShadowRayCount].Throughput = ls[index].Spectrum.GetType() == typeof(RgbSpectrumInfo) ? (RgbSpectrum) (RgbSpectrumInfo)ls[index].Spectrum : (RgbSpectrum)ls[index].Spectrum; secRays[tracedShadowRayCount].Pdf = ls[index].Pdf; secRays[tracedShadowRayCount].ShadowRay = ls[index].LightRay; Vector lwi = secRays[tracedShadowRayCount].ShadowRay.Dir; RgbSpectrum fs; hitInfo.MMaterial.f(ref secRays[tracedShadowRayCount].ShadowRay.Dir, ref wo, ref hitInfo.ShadingNormal, ref Throughput, out fs, types: BrdfType.Diffuse); secRays[tracedShadowRayCount].Throughput *= lightTroughtput * Vector.AbsDot(ref hitInfo.Normal, ref lwi) * fs; if (!secRays[tracedShadowRayCount].Throughput.IsBlack()) { #if DEBUG RayDen.Library.Core.Components.Assert.IsNotNaN(secRays[tracedShadowRayCount].Pdf); #endif secRays[tracedShadowRayCount].Pdf /= lightStrategyPdf; LightSample = ls[index]; tracedShadowRayCount++; } } } float fPdf = 0f; var wi = new Vector(); RgbSpectrum f; hitInfo.TextureData.Throughput = Throughput; f = bsdf.Sample_f(ref wo, out wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref Throughput, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue() , ref hitInfo.TextureData, out fPdf, out specularBounce); if ((fPdf <= 0.0f) || f.IsBlack()) { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } CurrentVertices.Add(new PathVertex() { BsdfPdf = fPdf, Throughput = Throughput, GeoNormal = hitInfo.Normal, HitPoint = hitPoint, HitType = PathVertexType.Geometry, IncomingDirection = wi, Material = bsdf, OutgoingDirection = wo, RayDistance = rayHit.Distance, SampleU = rayHit.U, SampleV = rayHit.V, ShadingNormal = hitInfo.ShadingNormal, TexCoords = hitInfo.TexCoords, rrWeight = 1f, }); pathWeight *= fPdf; Throughput *= (f * hitInfo.Color) / fPdf; if (depth > scene.MaxPathDepth) { float prob = Math.Max(Throughput.Filter(), scene.RussianRuletteImportanceCap); if (prob >= Sample.GetLazyValue()) { CurrentVertices[CurrentVertices.Count - 1].rrWeight = 1f/prob; Throughput /= prob; pathWeight *= prob; } else { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } } PathRay.Org = hitPoint; PathRay.Dir = wi.Normalize(); PathState = PathTracerPathState.NextVertex; #if VERBOSE } catch (Exception ex) { RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Advance path exception"); RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Error triangle {0}", currentTriangleIndex); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace); } #endif }
public override void Advance(RayBuffer rayBuffer, SampleBuffer consumer) { int currentTriangleIndex = 0; #if VERBOSE try { #endif if (((PathState == PathTracerPathState.ShadowRaysOnly) || (PathState == PathTracerPathState.NextVertex)) && (tracedShadowRayCount > 0)) { for (int i = 0; i < tracedShadowRayCount; ++i) { RayHit shadowRayHit = rayBuffer.rayHits[secRays[i].ShadowRayIndex]; RgbSpectrum attenuation; bool continueTrace; if (this.ShadowRayTest(ref shadowRayHit, ref secRays[i].ShadowRay, out attenuation, out continueTrace)) { //if (prevEvent.Has(BsdfEvent.Transmit) && bsdfEvent.Has(BsdfEvent.Transmit)) //{ // attenuation*= hitInfo.Color * MathLab.Exp(-Math.Max(shadowRayHit.Distance, Sample.GetLazyValue()*10f)); //} Radiance += attenuation * ((secRays[i].Throughput) / secRays[i].Pdf); } if (continueTrace) { continueRays[contCount++] = secRays[i]; //continueRays.Add(secRays[i]); } } if (PathState == PathTracerPathState.ShadowRaysOnly) { Splat(consumer); return; } Array.Copy(continueRays, secRays, contCount); tracedShadowRayCount = contCount; contCount = 0; } RayHit rayHit = rayBuffer.rayHits[RayIndex]; Vector wo = -PathRay.Dir; depth++; bool missed = rayHit.Index == 0xffffffffu; if (missed || PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth) { if (missed) { //Radiance += this.scene.SampleEnvironment(ref wo) * Throughput; var sampledEnvironment = this.scene.SampleEnvironment(ref wo); Radiance.MAdd(ref sampledEnvironment , ref Throughput); } Splat(consumer); return; } var bsdf = SurfaceSampler.GetBsdf(ref PathRay, ref rayHit, ref currentMedium, false, this.Sample.GetLazyValue()); //var mesh = scene.GetMeshByTriangleIndex(currentTriangleIndex); //rayHit.Index += (uint)mesh.StartTriangle; // Something was hit currentTriangleIndex = (int)rayHit.Index; //If Hit light) if (bsdf.IsLightSource()) { //if (bsdfEvent.Has(BsdfEvent.Specular) || depth == 1) { var lt = scene.GetLightByIndex(currentTriangleIndex); if (lt != null) { float pdf; var le = lt.Emittance(ref wo, out pdf); //Radiance += Throughput * le; Radiance.MAdd(ref Throughput, ref le); } } Splat(consumer); return; } var hitPoint = PathRay.Point(rayHit.Distance); tracedShadowRayCount = 0; if (bsdf.IsDiffuse()) { float lightStrategyPdf = LightSampler.StrategyPdf; //scene.ShadowRaysPerSample/(float)scene.Lights.Length; RgbSpectrum lightTroughtput = Throughput*(RgbSpectrum) bsdf.TexData.Diffuse; LightSampler.EvaluateShadow(bsdf, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), ref ls); for (int index = 0; index < ls.Length; index++) { if (ls[index].Pdf <= 0f) continue; secRays[tracedShadowRayCount].Throughput = ls[index].Spectrum.GetType() == typeof(RgbSpectrumInfo) ? (RgbSpectrum) (RgbSpectrumInfo)ls[index].Spectrum : (RgbSpectrum)ls[index].Spectrum; secRays[tracedShadowRayCount].Pdf = ls[index].Pdf; secRays[tracedShadowRayCount].ShadowRay = ls[index].LightRay; Vector lwi = secRays[tracedShadowRayCount].ShadowRay.Dir; BsdfEvent devent; float pdfw, ipdfw; var fs = (RgbSpectrum)bsdf.Evaluate(ref lwi, out devent, out pdfw, out ipdfw); if (pdfw < MathLab.Epsilon) continue; secRays[tracedShadowRayCount].Throughput *= lightTroughtput * ((fs * Vector.AbsDot(ref bsdf.HitPoint.ShadingNormal, ref lwi))); if (!secRays[tracedShadowRayCount].Throughput.IsBlack()) { #if DEBUG RayDen.Library.Core.Components.Assert.IsNotNaN(secRays[tracedShadowRayCount].Pdf); #endif secRays[tracedShadowRayCount].Pdf *= lightStrategyPdf * pdfw; secRays[tracedShadowRayCount].Pdf *= scene.ShadowRayCount; tracedShadowRayCount++; } } } float fPdf, frPdf; Vector wi; RgbSpectrum f; prevEvent = bsdfEvent; f = bsdf.Sample(out wi, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), out fPdf, out frPdf, out bsdfEvent); //if (prevEvent.Has(BsdfEvent.Transmit)) //{ // Throughput *= MathLab.Exp(-rayHit.Distance)*0.1f; //} if (prevEvent.Has(BsdfEvent.Transmit) && bsdfEvent.Has(BsdfEvent.Transmit)) { Throughput *= MathLab.Exp(-rayHit.Distance)*0.2f; } if ((fPdf <= 0.0f) || f.IsBlack()) { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } Throughput *= (f * (RgbSpectrum)bsdf.HitPoint.Color) / fPdf;//* (RgbSpectrum)bsdf.HitPoint.Color if (depth > scene.MaxPathDepth) { float prob = Math.Max(Throughput.Filter(), scene.RussianRuletteImportanceCap); if (prob >= Sample.GetLazyValue()) { Throughput /= prob; } else { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } } PathRay.Org = hitPoint; PathRay.Dir = wi.Normalize(); PathState = PathTracerPathState.NextVertex; #if VERBOSE } catch (Exception ex) { RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Advance path exception"); RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Error triangle {0}", currentTriangleIndex); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace); } #endif }
public override void Advance(RayBuffer rayBuffer, SampleBuffer consumer) { int currentTriangleIndex = 0; SurfaceIntersectionData hitInfo = null; #if VERBOSE try { #endif base.Advance(rayBuffer, consumer); RayHit rayHit = rayBuffer.rayHits[RayIndex]; if (((PathState == PathTracerPathState.ShadowRaysOnly) || (PathState == PathTracerPathState.NextVertex)) && (tracedShadowRayCount > 0)) { for (int i = 0; i < tracedShadowRayCount; ++i) { RayHit shadowRayHit = rayBuffer.rayHits[secRays[i].currentShadowRayIndex]; RgbSpectrum attenuation; if (this.ShadowRayTest(ref shadowRayHit, out attenuation)) { // Radiance.MADD() mutate = true; Radiance += attenuation * ((secRays[i].color)); pathWeight *= secRays[i].pdf; } } Splat(consumer); return; } depth++; bool missed = rayHit.Index == 0xffffffffu; if (missed || PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth) { if (specularBounce && missed) { Radiance += this.SampleEnvironment(PathRay.Dir) * Throughput; } Splat(consumer); return; } // Something was hit hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit); currentTriangleIndex = (int)rayHit.Index; if (hitInfo == null) { Debugger.Break(); } //If Hit light) if (hitInfo.IsLight) { if (specularBounce) { var lt = scene.GetLightByIndex(currentTriangleIndex); if (lt != null) { var le = (RgbSpectrum)(lt.Le(ref PathRay.Dir)); Radiance += Throughput * le; mutate = true; } } Splat(consumer); return; } var hitPoint = PathRay.Point(rayHit.Distance); Vector wo = -PathRay.Dir; tracedShadowRayCount = 0; if (hitInfo.MMaterial.IsDiffuse()) { float lightStrategyPdf = 1f;// scene.ShadowRayCount / (float)scene.Lights.Length; RgbSpectrum lightTroughtput = Throughput * hitInfo.Color; for (int i = 0; i < scene.ShadowRayCount; ++i) { int currentLightIndex = scene.SampleLights(Sample.GetLazyValue(depth * 0)); var light = scene.Lights[currentLightIndex]; var ls = new LightSample(); light.EvaluateShadow(ref hitPoint, ref hitInfo.ShadingNormal, Sample.GetLazyValue(depth * 1), Sample.GetLazyValue(depth * 2), Sample.GetLazyValue(depth * 3), ref ls); if (ls.Pdf <= 0f) { continue; } secRays[tracedShadowRayCount].color = (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, ref Throughput, out fs, types: BrdfType.Diffuse); secRays[tracedShadowRayCount].color *= lightTroughtput * Vector.AbsDot(ref hitInfo.ShadingNormal, ref lwi) * fs; if (!secRays[tracedShadowRayCount].color.IsBlack()) { secRays[tracedShadowRayCount].pdf *= lightStrategyPdf; tracedShadowRayCount++; } } } float fPdf; Vector wi; RgbSpectrum f = hitInfo.MMaterial.Sample_f(ref wo, out wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref Throughput, Sample.GetLazyValue(depth * 4), Sample.GetLazyValue(depth * 5), Sample.GetLazyValue(depth * 6), ref hitInfo.TextureData, out fPdf, out specularBounce); if ((fPdf <= 0.0f) || f.IsBlack()) { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } pathWeight *= fPdf; Throughput *= f / fPdf; if (!mutate) mutate = Throughput.Filter() > Sample.GetLazyValue(depth*7); if (depth > scene.MaxPathDepth) { float prob = Math.Max(Throughput.Filter(), scene.RussianRuletteImportanceCap); if (prob >= Sample.GetLazyValue(depth * 8)) { Throughput /= prob; pathWeight *= prob; } else { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } } PathRay.Org = hitPoint; PathRay.Dir = wi.Normalize(); PathState = PathTracerPathState.NextVertex; #if VERBOSE } catch (Exception ex) { RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Advance path exception"); RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Error triangle {0}", currentTriangleIndex); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace); } #endif }
public override void InitPath(IPathProcessor buffer) { base.InitPath(buffer); this.scene = pathIntegrator.Scene; this.Radiance = new RgbSpectrum(0f); this.Throughput = new RgbSpectrum(1f); this.PathState = PathTracerPathState.EyeVertex; this.secRays = new ShadowRayInfo[scene.ShadowRayCount]; this.sampler = (MCMCSampler)pathIntegrator.Sampler; switch (this.SamplerState) { case MCMCSamplerState.LargeStep: case MCMCSamplerState.Initialized: time = 0; this.mutationsCount = 0; this.rejectCount = 0; //this.sampleCache.Clear(); this.Sample = pathIntegrator.Sampler.GetSample(null); break; case MCMCSamplerState.SmallStep: { //if (rejectCount > 0) //{ // Print("Rejects : " + rejectCount); //} this.time++; this.Sample = this.sampler.SmallStep(this.Sample); ; } break; } IRay ray; pathIntegrator.Scene.Camera.GetRay(Sample.imageX, Sample.imageY, out ray); this.PathRay = (RayData)ray; this.RayIndex = -1; this.pathWeight = 1.0f; this.tracedShadowRayCount = 0; this.depth = 0; this.specularBounce = true; }
public override sealed void Advance(RayBuffer rayBuffer, SampleBuffer consumer) { int currentTriangleIndex = 0; #if VERBOSE try { #endif if (((PathState == PathTracerPathState.ShadowRaysOnly) || (PathState == PathTracerPathState.NextVertex)) && (tracedShadowRayCount > 0)) { var continueRays = new List<ShadowRayInfo>(); for (int i = 0; i < tracedShadowRayCount; ++i) { RayHit shadowRayHit = rayBuffer.rayHits[secRays[i].ShadowRayIndex]; RgbSpectrum attenuation; bool continueTrace; if (this.ShadowRayTest(ref shadowRayHit, ref secRays[i].ShadowRay, out attenuation, out continueTrace)) { //Radiance += attenuation * ((secRays[i].Throughput) / secRays[i].Pdf); waveRadiance += secRays[i].Throughput[0]/secRays[i].Pdf; //pathWeight *= secRays[i].Pdf; } if (continueTrace) { continueRays.Add(secRays[i]); } } if (PathState == PathTracerPathState.ShadowRaysOnly) { Splat(consumer); return; } Array.Copy(continueRays.ToArray(), secRays, continueRays.Count); tracedShadowRayCount = continueRays.Count; } RayHit rayHit = rayBuffer.rayHits[RayIndex]; Vector wo = -PathRay.Dir; depth++; bool missed = rayHit.Index == 0xffffffffu; if (missed || PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth) { if (missed) { //Radiance += this.scene.SampleEnvironment(ref wo) * Throughput; //var sampledEnvironment = this.scene.SampleEnvironment(ref wo); //! waveRadiance += wlSampler.SampleEnvironment(HeroWavelength, ref wo); //Radiance.MAdd(ref sampledEnvironment, ref Throughput); } Splat(consumer); return; } //var mesh = scene.GetMeshByTriangleIndex(currentTriangleIndex); //rayHit.Index += (uint)mesh.StartTriangle; // Something was hit if (hitInfo == null) { hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit); } else { SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, ref hitInfo); } currentTriangleIndex = (int)rayHit.Index; if (hitInfo == null) { System.Diagnostics.Debugger.Break(); } //If Hit light) if (hitInfo.IsLight) { if (specularBounce || depth == 1) { var lt = scene.GetLightByIndex(currentTriangleIndex); if (lt != null) { waveRadiance += wlSampler.SampleLight(lt, HeroWavelength); //var le = hitInfo.Color * (RgbSpectrum)(lt.Le(ref wo)); //! //Radiance += Throughput * le; //Radiance.MAdd(ref Throughput, ref le); } } Splat(consumer); return; } var hitPoint = PathRay.Point(rayHit.Distance); tracedShadowRayCount = 0; var bsdf = wlSampler.GetBrdf(scene.GetMeshByTriangleIndex(currentTriangleIndex).MaterialID); //if (!hitInfo.TextureData.Alpha.IsBlack()) //{ // Throughput *= (RgbSpectrum.UnitSpectrum() - hitInfo.TextureData.Alpha); // PathRay = new RayData(hitPoint, -wo); // return; //} if (bsdf.IsDiffuse()) { float lightStrategyPdf = LightSampler.StrategyPdf; //scene.ShadowRaysPerSample/(float)scene.Lights.Length; //RgbSpectrum lightTroughtput = Throughput * hitInfo.Color; float ltThroughput = waveThroughput*bsdf.Kd.Sample(HeroWavelength); LightSampler.EvaluateShadow(ref hitPoint, ref hitInfo.Normal, Sample.GetLazyValue(depth), Sample.GetLazyValue(2*depth+1), Sample.GetLazyValue(3*depth+2), ref ls); for (int index = 0; index < ls.Length; index++) { if (ls[index].Pdf <= 0f) continue; ls[index].Lambda = wlSampler.SampleLight(scene.Lights[ls[index].LightIndex], HeroWavelength); secRays[tracedShadowRayCount].Throughput[0] = ls[index].Lambda; secRays[tracedShadowRayCount].Pdf = ls[index].Pdf; secRays[tracedShadowRayCount].ShadowRay = ls[index].LightRay; Vector lwi = secRays[tracedShadowRayCount].ShadowRay.Dir; float fs; bsdf.F(ref secRays[tracedShadowRayCount].ShadowRay.Dir, ref wo, ref hitInfo.ShadingNormal, HeroWavelength, out fs); secRays[tracedShadowRayCount].Throughput[0] *= ltThroughput* Vector.AbsDot(ref hitInfo.Normal, ref lwi) * fs; if (secRays[tracedShadowRayCount].Throughput[0] > 0f) { #if DEBUG RayDen.Library.Core.Components.Assert.IsNotNaN(secRays[tracedShadowRayCount].Pdf); #endif secRays[tracedShadowRayCount].Pdf /= lightStrategyPdf; tracedShadowRayCount++; } } } float fPdf = 0f; var wi = new Vector(); float f; BsdfSampleData bsdfSample; bsdf.Sample_f(ref wo, ref hitInfo.Normal, ref hitInfo.ShadingNormal, HeroWavelength, ref hitInfo.TextureData, Sample.GetLazyValue(4 * depth + 3), Sample.GetLazyValue(5 * depth + 4), Sample.GetLazyValue(6 * depth + 5) , out bsdfSample); f = bsdfSample.Lambda; fPdf = bsdfSample.Pdf; wi = bsdfSample.Wi; specularBounce = bsdfSample.SpecularBounce; if ((fPdf <= 0.0f))// || f.IsBlack() { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } waveThroughput *= f/fPdf; pathWeight *= fPdf; //Throughput *= (f * hitInfo.Color) / fPdf; if (depth > scene.MaxPathDepth) { float prob = Math.Max(waveThroughput, scene.RussianRuletteImportanceCap); if (prob >= Sample.GetLazyValue(7 * depth + 5)) { //Throughput /= prob; waveThroughput /= prob; pathWeight *= prob; } else { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } } PathRay.Org = hitPoint; PathRay.Dir = wi.Normalize(); PathState = PathTracerPathState.NextVertex; #if VERBOSE } catch (Exception ex) { RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Advance path exception"); RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Error triangle {0}", currentTriangleIndex); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace); } #endif }
public override void Advance(Core.Types.RayBuffer rayBuffer, Core.Types.SampleBuffer consumer) { int currentTriangleIndex = 0; #if VERBOSE try { #endif if (((PathState == PathTracerPathState.ShadowRaysOnly) || (PathState == PathTracerPathState.NextVertex)) && (tracedShadowRayCount > 0)) { for (int i = 0; i < tracedShadowRayCount; ++i) { RayHit shadowRayHit = rayBuffer.rayHits[secRays[i].ShadowRayIndex]; RgbSpectrum attenuation; bool continueTrace; if (this.ShadowRayTest(ref shadowRayHit, ref secRays[i].ShadowRay, out attenuation, out continueTrace)) { float weight = 1f;//tracedShadowRayCount; // Radiance.MADD() Radiance += attenuation * (secRays[i].Throughput /(weight*secRays[i].Pdf))*100f; pathWeight *= secRays[i].Pdf; } } if (PathState == PathTracerPathState.ShadowRaysOnly) { Splat(consumer); return; } tracedShadowRayCount = 0; } RayHit eyeRayHit = rayBuffer.rayHits[RayIndex]; Vector wo = -PathRay.Dir; depth++; bool eyeMissed = eyeRayHit.Index == 0xffffffffu; if (eyeMissed && lightDepth > 0 && tracedShadowRayCount > 0) { Console.WriteLine("!"); } if (eyeMissed || PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth) { if (eyeMissed) { Radiance += this.scene.SampleEnvironment(ref wo) * Throughput; } Splat(consumer); return; } // Something was hit if (hitInfo == null) { hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref eyeRayHit); } else { SurfaceSampler.GetIntersection(ref PathRay, ref eyeRayHit, ref hitInfo); } currentTriangleIndex = (int)eyeRayHit.Index; if (hitInfo == null) { Debugger.Break(); } //If Hit light) if (hitInfo.IsLight) { if (specularBounce || depth == 1) { var lt = scene.GetLightByIndex(currentTriangleIndex); if (lt != null) { #if !NOIMPLICIT var le = (RgbSpectrumInfo)(lt.Le(ref wo)); Radiance += Throughput * (RgbSpectrum)le; #endif } } Splat(consumer); return; } if (!lightStoped) { RayHit lightRayHit = rayBuffer.rayHits[LightRayIndex]; if (lightRayHit.Miss()) { this.RestartLight(); } else { lightDepth++; if (lightHitInfo == null) { lightHitInfo = SurfaceSampler.GetIntersection(ref LightRay, ref lightRayHit, IntersectionOptions.ResolveSurfaceComplete | IntersectionOptions.ResumeOnLight); } else { SurfaceSampler.GetIntersection(ref LightRay, ref lightRayHit, ref lightHitInfo, IntersectionOptions.ResolveSurfaceComplete | IntersectionOptions.ResumeOnLight); } float lPdf = 0f; var lwi = new Vector(); var lhp = LightRay.Point(lightRayHit.Distance); var lf = lightHitInfo.MMaterial.Sample_f(ref wo, out lwi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref Throughput, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), ref hitInfo.TextureData, out lPdf, out specularBounce); var scatteringCorrection = Vector.AbsDot(ref wo, ref hitInfo.Normal) / Vector.AbsDot(ref wo, ref hitInfo.ShadingNormal); scatteringCorrection *= Vector.AbsDot(ref lwi, ref hitInfo.ShadingNormal); if (lPdf <= 0f || lf.IsBlack()) { this.RestartLight(); goto eyeCont; } if (lightDepth #if DIRECT_EXPLICIT > 1) #else > 0) #endif { float da = (currentLightVertex > 0 ? this.lightVertices[currentLightVertex - 1].dAWeight : 1.0f)*lightWeight; this.lightVertices[currentLightVertex] = new LightVertex() { HitPoint = lhp, Normal = lightHitInfo.ShadingNormal, BsdfWeight = lPdf, BsdfSample = lf*scatteringCorrection, dAWeight = da*(currentLightVertex > 0 ? lPdf*Geometry.G(ref lhp, ref lightVertices[currentLightVertex-1].HitPoint,ref hitInfo.ShadingNormal,ref lightVertices[currentLightVertex-1].Normal) : lPdf)*scatteringCorrection, Throughput = LightThroughtput, Wi = LightRay.Dir, }; currentLightVertex++; } LightThroughtput *= (lf / lPdf)*scatteringCorrection; LightRay = new RayData(ref lhp, ref lwi); } lightStoped = currentLightVertex > scene.MaxPathDepth || LightThroughtput.IsBlack(); } //if (currentLightVertex > 3) //{ // Debugger.Break(); //} eyeCont: var hitPoint = PathRay.Point(eyeRayHit.Distance); tracedShadowRayCount = 0; var bsdf = hitInfo.MMaterial; if (bsdf.IsDiffuse()) { #if DIRECT_EXPLICIT float lightStrategyPdf = LightSampler.StrategyPdf; //scene.ShadowRaysPerSample/(float)scene.Lights.Length; RgbSpectrum lightTroughtput = Throughput * hitInfo.Color; LightSampler.EvaluateShadow(ref hitPoint, ref hitInfo.Normal, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), ref ls); for (int index = 0; index < ls.Length; index++) { if (ls[index].Pdf <= 0f) continue; secRays[tracedShadowRayCount].Throughput = (RgbSpectrum)(RgbSpectrumInfo)(ls[index].Spectrum); secRays[tracedShadowRayCount].Pdf = ls[index].Pdf; secRays[tracedShadowRayCount].ShadowRay = ls[index].LightRay; Vector lwi = secRays[tracedShadowRayCount].ShadowRay.Dir; RgbSpectrum fs; hitInfo.MMaterial.f(ref secRays[tracedShadowRayCount].ShadowRay.Dir, ref wo, ref hitInfo.ShadingNormal, ref lightTroughtput, out fs, BrdfType.Diffuse); secRays[tracedShadowRayCount].Throughput *= lightTroughtput * Vector.AbsDot(ref hitInfo.Normal, ref lwi) * fs; if (!secRays[tracedShadowRayCount].Throughput.IsBlack()) { secRays[tracedShadowRayCount].Pdf /= lightStrategyPdf; tracedShadowRayCount++; } } #endif for (int index = 0; index < currentLightVertex; index++) { if (lightVertices[index].Throughput.IsBlack()) continue; var lwi = lightVertices[index].Wi; RgbSpectrum fs; hitInfo.MMaterial.f(ref lwi, ref wo, ref hitInfo.ShadingNormal, ref Throughput, out fs, types: BrdfType.Diffuse); var dir = lightVertices[index].HitPoint - hitPoint; var dirLength = dir.Length; dir.NormalizeSelf(); secRays[tracedShadowRayCount].Throughput = Throughput*lightVertices[index].Throughput *fs *lightVertices[index].BsdfSample //* Vector.AbsDot(ref hitInfo.Normal, ref lwi) *Geometry.G(ref hitPoint, ref lightVertices[index].HitPoint,ref hitInfo.Normal,ref lightVertices[index].Normal); secRays[tracedShadowRayCount].Pdf = (pathWeight*lightVertices[index].dAWeight) ; // * Geometry.G(ref hitPoint, ref lightVertices[index].HitPoint, ref hitInfo.Normal, ref lightVertices[index].Normal); //1f/(depth+index) * (pathWeight*lightVertices[index].dAWeight); secRays[tracedShadowRayCount].ShadowRay = new RayData(ref hitPoint, ref dir, 1e-4f, dirLength-1e-4f); tracedShadowRayCount++; } } float fPdf = 0f; var wi = new Vector(); RgbSpectrum f; f = bsdf.Sample_f(ref wo, out wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref Throughput, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), ref hitInfo.TextureData, out fPdf, out specularBounce); if ((fPdf <= 0.0f) || f.IsBlack()) { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } pathWeight *= fPdf; Throughput *= (f) / fPdf; if (depth > scene.MaxPathDepth) { float prob = Math.Max(Throughput.Filter(), scene.RussianRuletteImportanceCap); if (prob >= Sample.GetLazyValue()) { Throughput /= prob; pathWeight *= prob; } else { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } } PathRay.Org = hitPoint; PathRay.Dir = wi.Normalize(); PathState = PathTracerPathState.NextVertex; #if VERBOSE } catch (Exception ex) { RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Advance path exception"); RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Error triangle {0}", currentTriangleIndex); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace); } #endif }
public override void Advance(RayBuffer rayBuffer, SampleBuffer consumer) { int currentTriangleIndex = 0; #if VERBOSE try { #endif if (((PathState == PathTracerPathState.ShadowRaysOnly) || (PathState == PathTracerPathState.NextVertex)) && (tracedShadowRayCount > 0)) { for (int i = 0; i < tracedShadowRayCount; ++i) { RayHit shadowRayHit = rayBuffer.rayHits[secRays[i].ShadowRayIndex]; RgbSpectrum attenuation; bool continueTrace; if (this.ShadowRayTest(ref shadowRayHit, ref secRays[i].ShadowRay, out attenuation, out continueTrace)) { Radiance += ((secRays[i].Throughput) / secRays[i].Pdf); } } if (PathState == PathTracerPathState.ShadowRaysOnly) { Splat(consumer); return; } tracedShadowRayCount = 0; } var rayHit = rayBuffer.rayHits[RayIndex]; var wo = -PathRay.Dir; depth++; var missed = rayHit.Index == 0xffffffffu; if (missed || depth > scene.MaxPathDepth) { if (specularBounce && missed) { Radiance += this.scene.SampleEnvironment(ref wo) * Throughput; } Splat(consumer); return; } // Something was hit if (hitInfo == null) { hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit); } else { SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, ref hitInfo); } currentTriangleIndex = (int)rayHit.Index; //If Hit light) if (hitInfo.IsLight) { { var lt = scene.GetLightByIndex(currentTriangleIndex); if (lt != null) { var le = (RgbSpectrum)(RgbSpectrumInfo)(lt.Le(ref PathRay.Dir)); Radiance += Throughput * le; } } Splat(consumer); return; } var hitPoint = PathRay.Point(rayHit.Distance); tracedShadowRayCount = 0; if (hitInfo.MMaterial.IsDiffuse()) { float lightStrategyPdf = LightSampler.StrategyPdf; //scene.ShadowRaysPerSample/(float)scene.Lights.Length; RgbSpectrum lightTroughtput = Throughput * hitInfo.Color; LightSampler.EvaluateShadow(ref hitPoint, ref hitInfo.Normal, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), ref ls); for (int index = 0; index < ls.Length; index++) { if (ls[index].Pdf <= 0f || float.IsNaN(ls[index].Pdf)) continue; secRays[tracedShadowRayCount].Throughput = ls[index].Spectrum.GetType() == typeof(RgbSpectrumInfo) ? (RgbSpectrum)(RgbSpectrumInfo)ls[index].Spectrum : (RgbSpectrum)ls[index].Spectrum; secRays[tracedShadowRayCount].Pdf = ls[index].Pdf; secRays[tracedShadowRayCount].ShadowRay = ls[index].LightRay; Vector lwi = secRays[tracedShadowRayCount].ShadowRay.Dir; RgbSpectrum fs; hitInfo.MMaterial.f(ref secRays[tracedShadowRayCount].ShadowRay.Dir, ref wo, ref hitInfo.ShadingNormal, ref Throughput, out fs, types: BrdfType.Diffuse); secRays[tracedShadowRayCount].Throughput *= lightTroughtput * Vector.AbsDot(ref hitInfo.Normal, ref lwi) * fs; if (!secRays[tracedShadowRayCount].Throughput.IsBlack()) { #if DEBUG RayDen.Library.Core.Components.Assert.IsNotNaN(secRays[tracedShadowRayCount].Pdf); #endif secRays[tracedShadowRayCount].Pdf /= lightStrategyPdf * scene.ShadowRayCount; tracedShadowRayCount++; } } } float fPdf; Vector wi; var f = hitInfo.MMaterial.Sample_f(ref wo, out wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref Throughput, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), ref hitInfo.TextureData, out fPdf, out specularBounce); if ((fPdf <= 0.0f) || f.IsBlack()) { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } pathWeight *= fPdf; Throughput *= (f * hitInfo.Color) / fPdf; if (depth > scene.MaxPathDepth) { float prob = Math.Max(Throughput.Filter(), scene.RussianRuletteImportanceCap); if (prob >= Sample.GetLazyValue()) { Throughput /= prob; pathWeight *= prob; } else { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } } PathRay.Org = hitPoint; PathRay.Dir = wi.Normalize(); PathState = PathTracerPathState.NextVertex; #if VERBOSE } catch (Exception ex) { RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Advance path exception"); RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Error triangle {0}", currentTriangleIndex); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace); } #endif }
public override void Advance(RayBuffer rayBuffer, SampleBuffer consumer) { int currentTriangleIndex = 0; #if VERBOSE try { #endif var misWeight = 1.0f; base.Advance(rayBuffer, consumer); RayHit rayHit = rayBuffer.rayHits[RayIndex]; if (((PathState == PathTracerPathState.ShadowRaysOnly) || (PathState == PathTracerPathState.NextVertex)) && (tracedShadowRayCount > 0)) { for (int i = 0; i < tracedShadowRayCount; ++i) { RayHit shadowRayHit = rayBuffer.rayHits[secRays[i].currentShadowRayIndex]; RgbSpectrumInfo attenuation; if (this.ShadowRayTest(ref shadowRayHit, out attenuation)) { // Radiance.MADD() Radiance += (RgbSpectrum)(attenuation * ((secRays[i].color))); pathWeight *= secRays[i].pdf; } } tracedShadowRayCount = 0; if (PathState == PathTracerPathState.ShadowRaysOnly) { Splat(consumer); return; } } depth++; bool missed = rayHit.Index == 0xffffffffu; Vector wo = -PathRay.Dir; if (missed || PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth) { if (depth > 0 && !specularBounce) { misWeight = Mis2(lastPdfW, 1f / MathLab.INVPI); } if (specularBounce) { Radiance += this.SampleEnvironment(wo) * Throughput * misWeight; } Splat(consumer); return; } // Something was hit if (hitInfo == null) { hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit); } else { SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, ref hitInfo); } currentTriangleIndex = (int)rayHit.Index; if (hitInfo == null) { Debugger.Break(); } //If Hit light) if (hitInfo.IsLight) { var lt = scene.GetLightByIndex(currentTriangleIndex); if (lt !=null) { float wpdf; var l =(RgbSpectrum)lt.Emittance(ref wo, out wpdf)*Throughput; if (!specularBounce & depth > 0) { var dpdf = MathLab.PdfAtoW(wpdf, rayHit.Distance, Vector.AbsDot(ref wo, ref hitInfo.Normal)); var lightPickProb = 1.0f/scene.Lights.Length; misWeight = Mis2(lastPdfW, dpdf*lightPickProb); } Radiance += Throughput*l*misWeight; } else { float pdf; var le = hitInfo.Color * lt.Emittance(ref wo, out pdf); //Radiance += Throughput * le; Radiance.MAdd(ref Throughput, ref le); } Splat(consumer); return; } var hitPoint = PathRay.Point(rayHit.Distance); tracedShadowRayCount = 0; var bsdf = hitInfo.MMaterial; float contProb = bsdf.ContinuationProbability; if (bsdf.IsDiffuse()) { float lightStrategyPdf = scene.ShadowRayCount / (float)scene.Lights.Length; RgbSpectrum lightTroughtput = Throughput * hitInfo.Color; for (int i = 0; i < scene.ShadowRayCount; ++i) { int currentLightIndex = scene.SampleLights(Sample.GetLazyValue()); var light = scene.Lights[currentLightIndex]; int tries = RejectionSamplingMaxLighTries; light_restart: light.EvaluateShadow(ref hitPoint, ref hitInfo.ShadingNormal, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), ref ls); if (ls.Pdf <= 0f) { tries--; if (tries == 0) continue; goto light_restart; } RgbSpectrum f_s; bsdf.f(ref secRays[tracedShadowRayCount].shadowRay.Dir, ref wo, ref hitInfo.ShadingNormal, ref Throughput, out f_s); if (f_s.IsBlack()) { continue; } var fs = (RgbSpectrumInfo) f_s; var bsdfPdfW = bsdf.Pdf(ref secRays[tracedShadowRayCount].shadowRay.Dir, ref wo); float weight = 1f; secRays[tracedShadowRayCount].color = (RgbSpectrumInfo)(RgbSpectrum)(ls.Spectrum); secRays[tracedShadowRayCount].pdf = ls.Pdf; secRays[tracedShadowRayCount].shadowRay = ls.LightRay; Vector lwi = -secRays[tracedShadowRayCount].shadowRay.Dir; var lightPdf = ls.Pdf * lightStrategyPdf; if (!light.IsDelta) { bsdfPdfW *= contProb; weight = Mis2(lightPdf, bsdfPdfW); secRays[tracedShadowRayCount].pdf = 1f; secRays[tracedShadowRayCount].color = (weight * Vector.AbsDot(ref hitInfo.ShadingNormal, ref lwi) / (lightPdf)) * (lightTroughtput * fs); } else { secRays[tracedShadowRayCount].color *= (lightTroughtput * Vector.AbsDot(ref hitInfo.ShadingNormal, ref lwi) * fs); secRays[tracedShadowRayCount].color /= lightPdf; } if (!secRays[tracedShadowRayCount].color.IsBlack()) { tracedShadowRayCount++; } } } float fPdf; Vector wi; int btries = RejectionSamplingMaxBsdfTries; bsdf_restart: RgbSpectrum f = bsdf.Sample_f(ref wo, out wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref Throughput, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), ref hitInfo.TextureData, out fPdf, out specularBounce)*hitInfo.Color; if ((fPdf <= 0.0f) || f.IsBlack()) { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { btries--; if (btries == 0) { Splat(consumer); } else { goto bsdf_restart; } } return; } pathWeight *= fPdf; Throughput *= (f*hitInfo.Color) / fPdf; lastPdfW = fPdf * contProb; if (depth > scene.MaxPathDepth) { float prob = Math.Max(contProb, scene.RussianRuletteImportanceCap); if (prob >= Sample.GetLazyValue()) { Throughput /= prob; pathWeight *= prob; } else { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } } PathRay.Org = hitPoint; PathRay.Dir = wi.Normalize(); PathState = PathTracerPathState.NextVertex; #if VERBOSE } catch (Exception ex) { RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Advance path exception"); RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Error triangle {0}", currentTriangleIndex); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace); } #endif }
public override void Advance(RayBuffer rayBuffer, SampleBuffer consumer) { #if VERBOSE try { #endif base.Advance(rayBuffer, consumer); var rayHit = new RayHit(); Vector wo = -PathRay.Dir; switch (PathState) { case PathTracerPathState.EyeVertex: float t, t1; if (scene.VolumeIntegrator != null && scene.VolumeIntegrator.GetBounds().Intersect(PathRay, out t, out t1)) { rayHit = rayBuffer.rayHits[RayIndex]; // Use Russian Roulette to check if I have to do participating media computation or not if (Sample.GetLazyValue() <= scene.VolumeIntegrator.GetRRProbability()) { RayData volumeRay = new RayData(ref PathRay.Org, ref PathRay.Dir, 0f, rayHit.Miss() ? 1e10f : rayHit.Distance); scene.VolumeIntegrator.GenerateLiRays(scene, Sample, ref volumeRay, volumeComp); Radiance += volumeComp.GetEmittedLight(); if (volumeComp.GetRayCount() > 0) { // Do the EYE_VERTEX_VOLUME_STEP PathState = PathTracerPathState.EyeVolume; eyeHit = (rayBuffer.rayHits[RayIndex]); return; } } } else { rayHit = rayBuffer.rayHits[RayIndex]; } break; case PathTracerPathState.NextVertex: rayHit = rayBuffer.rayHits[RayIndex]; break; case PathTracerPathState.EyeVolume: Radiance += Throughput * volumeComp.CollectResults(rayBuffer) / scene.VolumeIntegrator.GetRRProbability(); rayHit = eyeHit; break; } if (((PathState == PathTracerPathState.ShadowRaysOnly) || (PathState == PathTracerPathState.NextVertex)) && (tracedShadowRayCount > 0)) { for (int i = 0; i < tracedShadowRayCount; ++i) { RayHit shadowRayHit = rayBuffer.rayHits[secRays[i].currentShadowRayIndex]; RgbSpectrum attenuation; if (this.ShadowRayTest(ref shadowRayHit, out attenuation)) { // Radiance.MADD() Radiance += attenuation * ((secRays[i].color) / secRays[i].pdf); pathWeight *= secRays[i].pdf; } } tracedShadowRayCount = 0; if (PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth) { Splat(consumer); return; } } depth++; bool missed = rayHit.Index == 0xffffffffu; if (missed || PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth) { if (specularBounce && missed) { Radiance += this.SampleEnvironment(-PathRay.Dir) * Throughput; } Splat(consumer); return; } // Something was hit if (_hitInfo == null) _hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit); else { SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, ref _hitInfo); } var currentTriangleIndex = (int)rayHit.Index; //If Hit light) if (_hitInfo.IsLight) { if (specularBounce) { var lt = scene.GetLightByIndex(currentTriangleIndex); if (lt == null) { goto errro; } var le = (RgbSpectrum)(RgbSpectrumInfo)(lt.Le(ref wo)); Radiance += Throughput * le; } Splat(consumer); return; } @errro: var hitPoint = PathRay.Point(rayHit.Distance); tracedShadowRayCount = 0; if (_hitInfo.MMaterial.IsDiffuse()) { float lightStrategyPdf = scene.ShadowRayCount / (float)scene.Lights.Length; RgbSpectrum lightTroughtput = Throughput * _hitInfo.Color; for (int i = 0; i < scene.ShadowRaysPerSample; ++i) { int currentLightIndex = scene.SampleLights(Sample.GetLazyValue()); var light = scene.Lights[currentLightIndex]; var ls = new LightSample(); light.EvaluateShadow(ref hitPoint, ref _hitInfo.ShadingNormal, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), ref ls); if (ls.Pdf <= 0f) { continue; } secRays[tracedShadowRayCount].color = ls.Spectrum.GetType() == typeof(RgbSpectrumInfo) ? (RgbSpectrum)(RgbSpectrumInfo)ls.Spectrum : (RgbSpectrum)ls.Spectrum; secRays[tracedShadowRayCount].pdf = ls.Pdf; secRays[tracedShadowRayCount].shadowRay = ls.LightRay; RgbSpectrum fs; _hitInfo.MMaterial.f( ref secRays[tracedShadowRayCount].shadowRay.Dir, ref wo, ref _hitInfo.ShadingNormal, ref Throughput, out fs); Vector lwi = secRays[tracedShadowRayCount].shadowRay.Dir; secRays[tracedShadowRayCount].color *= lightTroughtput * Vector.AbsDot(ref _hitInfo.ShadingNormal, ref lwi) * fs; if (!secRays[tracedShadowRayCount].color.IsBlack()) { secRays[tracedShadowRayCount].pdf *= lightStrategyPdf; tracedShadowRayCount++; } } } float fPdf; Vector wi; RgbSpectrum f = _hitInfo.MMaterial.Sample_f(ref wo, out wi, ref _hitInfo.Normal, ref _hitInfo.ShadingNormal, ref Throughput, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), ref _hitInfo.TextureData, out fPdf, out specularBounce); if ((fPdf <= 0.0f) || f.IsBlack()) { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } pathWeight *= fPdf; Throughput *= f / fPdf; if (depth > scene.MaxPathDepth) { float prob = Math.Max(Throughput.Filter(), scene.RussianRuletteImportanceCap); if (prob >= Sample.GetLazyValue()) { Throughput /= prob; pathWeight *= prob; } else { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } } PathRay.Org = hitPoint; PathRay.Dir = wi.Normalize(); PathState = PathTracerPathState.NextVertex; #if VERBOSE } catch (Exception ex) { RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace); throw; } #endif }
public override sealed void Advance(RayBuffer rayBuffer, SampleBuffer consumer) { int currentTriangleIndex = 0; #if VERBOSE try { #endif if (((PathState == PathTracerPathState.ShadowRaysOnly) || (PathState == PathTracerPathState.NextVertex)) && (tracedShadowRayCount > 0)) { for (int i = 0; i < tracedShadowRayCount; ++i) { RayHit shadowRayHit = rayBuffer.rayHits[secRays[i].ShadowRayIndex]; RgbSpectrum attenuation; bool continueTrace; if (this.ShadowRayTest(ref shadowRayHit, ref secRays[i].ShadowRay, out attenuation, out continueTrace)) { // Radiance.MADD() Radiance += attenuation * ((secRays[i].Throughput) / secRays[i].Pdf); pathWeight *= secRays[i].Pdf; } } if (PathState == PathTracerPathState.ShadowRaysOnly) { Splat(consumer); return; } tracedShadowRayCount = 0; } RayHit rayHit = rayBuffer.rayHits[RayIndex]; Vector wo = -PathRay.Dir; depth++; bool missed = rayHit.Index == 0xffffffffu; if (missed || PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth) { if (missed) { Radiance += this.scene.SampleEnvironment(ref wo) * Throughput; } Splat(consumer); return; } // Something was hit if (hitInfo == null) { hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit); } else { SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, ref hitInfo); } currentTriangleIndex = (int)rayHit.Index; if (hitInfo == null) { Debugger.Break(); } //If Hit light) if (hitInfo.IsLight) { if (specularBounce || depth == 1) { var lt = scene.GetLightByIndex(currentTriangleIndex); if (lt != null) { var le = (RgbSpectrum)(lt.Le(ref wo)); Radiance += Throughput * le; } } Splat(consumer); return; } var hitPoint = PathRay.Point(rayHit.Distance); tracedShadowRayCount = 0; var bsdf = hitInfo.MMaterial; if (!hitInfo.TextureData.Alpha.IsBlack()) { Throughput *= (RgbSpectrum.UnitSpectrum() - (RgbSpectrum) hitInfo.TextureData.Alpha); PathRay = new RayData(hitPoint, -wo); return; } if (bsdf.IsDiffuse()) { float lightStrategyPdf = LightSampler.StrategyPdf; //scene.ShadowRaysPerSample/(float)scene.Lights.Length; RgbSpectrum lightTroughtput = Throughput * hitInfo.Color; int rs = 0; @lstart: LightSampler.EvaluateShadow(ref hitPoint, ref hitInfo.Normal, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), ref ls); for (int index = 0; index < ls.Length; index++) { if (ls[index].Pdf <= 0f) continue; secRays[tracedShadowRayCount].Throughput = (RgbSpectrum)(ls[index].Spectrum); secRays[tracedShadowRayCount].Pdf = ls[index].Pdf; secRays[tracedShadowRayCount].ShadowRay = ls[index].LightRay; Vector lwi = secRays[tracedShadowRayCount].ShadowRay.Dir; RgbSpectrum fs; hitInfo.MMaterial.f(ref secRays[tracedShadowRayCount].ShadowRay.Dir, ref wo, ref hitInfo.ShadingNormal, ref Throughput, out fs, types: BrdfType.Diffuse); secRays[tracedShadowRayCount].Throughput *= lightTroughtput * Vector.AbsDot(ref hitInfo.Normal, ref lwi) * fs; if (!secRays[tracedShadowRayCount].Throughput.IsBlack()) { secRays[tracedShadowRayCount].Pdf /= lightStrategyPdf; tracedShadowRayCount++; } } if (tracedShadowRayCount == 0 && rs < lightResampling) { rs++; goto @lstart; } if (rs > 0) { for (int index = 0; index < secRays.Length; index++) { secRays[index].Pdf /= (1f+rs); } } } float fPdf = 0f; var wi = new Vector(); RgbSpectrum f; if (depth > 1) { f = bsdf.Sample_f(ref wo, out wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref Throughput, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), ref hitInfo.TextureData, out fPdf, out specularBounce); } else { int samplesCount = 4; var bsdfData = new Tuple<Vector, float, RgbSpectrum>[samplesCount]; var totalF = new RgbSpectrum(); float totalPdf =0; for (int i = 0; i < samplesCount; i++) { Vector Wi; float pdf; var Fr = bsdf.Sample_f(ref wo, out Wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref Throughput, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), ref hitInfo.TextureData, out pdf, out specularBounce); totalF += Fr; totalPdf += pdf; bsdfData[i] = new Tuple<Vector, float, RgbSpectrum>(Wi, pdf, Fr); } var bsdfSamples = bsdfData.OrderBy(i => i.Item2).ToArray(); fPdf = bsdfSamples[0].Item2; wi = bsdfSamples[0].Item1; f = totalF/4f; } if ((fPdf <= 0.0f) || f.IsBlack()) { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } pathWeight *= fPdf; Throughput *= (f * hitInfo.Color) / fPdf; if (depth > scene.MaxPathDepth) { float prob = Math.Max(Throughput.Filter(), scene.RussianRuletteImportanceCap); if (prob >= Sample.GetLazyValue()) { Throughput /= prob; pathWeight *= prob; } else { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } } PathRay.Org = hitPoint; PathRay.Dir = wi.Normalize(); PathState = PathTracerPathState.NextVertex; #if VERBOSE } catch (Exception ex) { RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Advance path exception"); RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Error triangle {0}", currentTriangleIndex); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace); } #endif }
public override void Advance(RayBuffer rayBuffer, SampleBuffer consumer) { int currentTriangleIndex = 0; #if VERBOSE try { #endif base.Advance(rayBuffer, consumer); RayHit rayHit = rayBuffer.rayHits[RayIndex]; if (((PathState == PathTracerPathState.ShadowRaysOnly) || (PathState == PathTracerPathState.NextVertex)) && (tracedShadowRayCount > 0)) { for (int i = 0; i < tracedShadowRayCount; ++i) { RayHit shadowRayHit = rayBuffer.rayHits[secRays[i].currentShadowRayIndex]; RgbSpectrum attenuation; bool continueTrace; if (this.ShadowRayTest(ref shadowRayHit, ref secRays[i].shadowRay, out attenuation, out continueTrace)) { // Radiance.MADD() Radiance += ((secRays[i].color) / secRays[i].pdf); pathWeight *= secRays[i].pdf; var d = secRays[i].shadowRay.Point(shadowRayHit.Distance); var pix = scene.Camera.UnProject(ref d); this.Splat(consumer, pix.x, 720f - pix.y, ref Radiance ); } } if (PathState == PathTracerPathState.ShadowRaysOnly) { Splat(consumer); return; } tracedShadowRayCount = 0; } depth++; bool missed = rayHit.Index == 0xffffffffu; if (missed || PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth) { if (missed) { RgbSpectrum env; this.SampleEnvironment(ref PathRay.Dir, out env); Radiance += env * Throughput; } Splat(consumer); return; } // Something was hit if (hitInfo == null) { hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, IntersectionOptions.ResolveObject); } else { SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, ref hitInfo, IntersectionOptions.ResolveObject); } currentTriangleIndex = (int)rayHit.Index; if (hitInfo == null) { Debugger.Break(); } Vector wo = -PathRay.Dir; var hitPoint = PathRay.Point(rayHit.Distance); //If Hit light) if (hitInfo.IsLight) { //if (specularBounce || depth == 1) { var lt = scene.GetLightByIndex(currentTriangleIndex); if (lt != null) { var le = (RgbSpectrum)(lt.Le(ref wo)); Throughput *= le; AddEyeRay(ref hitPoint, ref wo, ref Throughput, 1f); PathState = PathTracerPathState.ShadowRaysOnly; return; } } } var bsdf = hitInfo.MMaterial; if (bsdf.IsDiffuse()) { float lightStrategyPdf = 1f; //scene.ShadowRaysPerSample/(float)scene.Lights.Length; var lightTroughtput = Throughput*hitInfo.Color; AddEyeRay(ref hitPoint, ref wo, ref lightTroughtput, lightStrategyPdf ); } float fPdf = 0f; var wi = new Vector(); RgbSpectrum f; f = bsdf.Sample_f(ref wo, out wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref Throughput, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), ref hitInfo.TextureData, out fPdf, out specularBounce)*hitInfo.Color; if ((fPdf <= 0.0f) || f.IsBlack()) { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } pathWeight *= fPdf; Throughput *= f / fPdf; if (depth > scene.MaxPathDepth) { float prob = Math.Max(Throughput.Filter(), scene.RussianRuletteImportanceCap); if (prob >= Sample.GetLazyValue()) { Throughput /= prob; pathWeight *= prob; } else { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } } PathRay.Org = hitPoint; PathRay.Dir = wi.Normalize(); PathState = PathTracerPathState.NextVertex; #if VERBOSE } catch (Exception ex) { RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Advance path exception"); RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Error triangle {0}", currentTriangleIndex); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message); RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace); } #endif }
private void AdvanceNewPath(RayBuffer rayBuffer, SampleBuffer consumer) { int currentTriangleIndex; RayHit rayHit = rayBuffer.rayHits[RayIndex]; Vector wo = -PathRay.Dir; PathVertex vertex = null; if (Vertices[depth] == null) { vertex = new PathVertex(); Vertices[depth] = vertex; } else { vertex = Vertices[depth]; } depth++; bool missed = rayHit.Index == 0xffffffffu; if (missed || PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth) { if (missed) { //Radiance += this.scene.SampleEnvironment(ref wo) * Throughput; var sampledEnvironment = this.scene.SampleEnvironment(ref wo); Radiance.MAdd(ref sampledEnvironment, ref Throughput); if (scene.EnvironmentMap != null) { mutate = true; } } Splat(consumer); return; } //var mesh = scene.GetMeshByTriangleIndex(currentTriangleIndex); //rayHit.Index += (uint)mesh.StartTriangle; // Something was hit var bsdf = EvalIntersection(ref rayHit); currentTriangleIndex = (int)rayHit.Index; vertex.Bsdf = bsdf; vertex.TriangleIndex = currentTriangleIndex; if (hitInfo == null) { Debugger.Break(); } //If Hit light) if (hitInfo.IsLight) { //if (bsdfEvent.Has(BsdfEvent.Specular) || depth == 1) { var lt = scene.GetLightByIndex(currentTriangleIndex); if (lt != null) { float pdf; var le = hitInfo.Color * lt.Emittance(ref wo, out pdf); //Radiance += Throughput * le; if (!le.IsBlack()) mutate = true; Radiance.MAdd(ref Throughput, ref le); } } Splat(consumer); return; } var hitPoint = PathRay.Point(rayHit.Distance); vertex.HitPoint = hitPoint; tracedShadowRayCount = 0; if (!hitInfo.TextureData.Alpha.IsBlack()) { Throughput *= (RgbSpectrum.UnitSpectrum() - (RgbSpectrum)hitInfo.TextureData.Alpha); PathRay = new RayData(hitPoint, -wo); return; } float fPdf; Vector wi; RgbSpectrum f; hitInfo.TextureData.Throughput = Throughput; prevEvent = bsdfEvent; f = bsdf.Sample_f(ref wo, out wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref Throughput, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue() , ref hitInfo.TextureData, out fPdf, out bsdfEvent); //if (prevEvent.Has(BsdfEvent.Transmit) && bsdfEvent.Has(BsdfEvent.Transmit)) //{ // Throughput *= MathLab.Exp(-rayHit.Distance) * 0.2f; //} vertex.BsdfSample = f; vertex.BsdfWeight = fPdf; vertex.Event = bsdfEvent; vertex.Wo = wo; vertex.Wi = wi; vertex.ShadeNormal = hitInfo.ShadingNormal; if ((fPdf <= 0.0f) || f.IsBlack()) { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } Throughput *= (f * hitInfo.Color) / fPdf; pathDensity *= fPdf; if (depth > scene.MaxPathDepth) { float prob = Math.Max(Throughput.Filter(), scene.RussianRuletteImportanceCap); if (prob >= Sample.GetLazyValue()) { Throughput /= prob; pathDensity *= prob; } else { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } } PathRay.Org = hitPoint; PathRay.Dir = wi.Normalize(); PathState = PathTracerPathState.NextVertex; }