public override void InitPath(IPathProcessor buffer) { base.InitPath(buffer); this.scene = pathIntegrator.Scene; if (this.secRays == null) { this.secRays = new ShadowRayInfo[scene.ShadowRaysPerSample]; } if (State == RayTracerPathState.Eye || State == RayTracerPathState.OnlyShadow || depth >= scene.MaxPathDepth) { 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.Throughput = new RgbSpectrum(1f); this.Radiance = Ambient; this.specularBounce = true; this.State = RayTracerPathState.Eye; this.finished = false; } else if (State == RayTracerPathState.Reflection) { this.RayIndex = -1; this.pathWeight = 1.0f; this.tracedShadowRayCount = 0; this.specularBounce = true; } else if (State == RayTracerPathState.Refraction) { this.RayIndex = -1; this.pathWeight = 1.0f; this.tracedShadowRayCount = 0; this.specularBounce = true; } }
public override void Advance(RayBuffer rayBuffer, SampleBuffer consumer) { int currentTriangleIndex = 0; #if VERBOSE try { #endif if ((State != RayTracerPathState.Eye) && (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 (State == RayTracerPathState.OnlyShadow) { Splat(consumer); return; } tracedShadowRayCount = 0; } var rayHit = rayBuffer.rayHits[RayIndex]; var wo = -PathRay.Dir; depth++; var missed = rayHit.Index == 0xffffffffu; if (missed || State == RayTracerPathState.OnlyShadow || 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; } if (hitInfo == null) { hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit); } else { SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, ref hitInfo); } currentTriangleIndex = (int) rayHit.Index; var hitPoint = PathRay.Point(rayHit.Distance); tracedShadowRayCount = 0; var bsdf = hitInfo.MMaterial; 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++; } } } if (bsdf.IsSpecular() || bsdf.IsRefractive() && depth < scene.MaxPathDepth) { var 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) State = RayTracerPathState.OnlyShadow; else { Splat(consumer); } return; } pathWeight *= fPdf; Throughput *= (f)/fPdf; State = RayTracerPathState.Reflection; PathRay.Org = hitPoint; PathRay.Dir = wi.Normalize(); //Radiance += Throughput; } else { if (tracedShadowRayCount > 0) State = RayTracerPathState.OnlyShadow; else Splat(consumer); } #if VERBOSE } catch (Exception ex) { Tracer.TraceLine(ex.Message); throw; } #endif }