protected void Init(IIntersectionEngine device, bool lowLatency, ImageFilmBase pixelDevice, IPrimarySpaceSampler sampler, SurfaceSampler ss) { intersectionDevice = device; // Sample buffer var sampleBufferSize = lowLatency ? (SAMPLE_BUFFER_SIZE / 4) : SAMPLE_BUFFER_SIZE; sampleBuffer = new SampleBuffer(sampleBufferSize); width = sampler.Width; height = sampler.Height; var rayBufferSize = lowLatency ? (RayBuffer.RayBufferSize / 8) : RayBuffer.RayBufferSize; this.sampler = sampler; _pathRayProcessors = new PathIntegrator[DeviceRenderBufferCount]; rayBuffers = new RayBuffer[DeviceRenderBufferCount]; for (int i = 0; i < DeviceRenderBufferCount; i++) { rayBuffers[i] = new RayBuffer(rayBufferSize); rayBuffers[i].UserData = threadIndex; _pathRayProcessors[i] = this.CreatePathBuffer(scene.MaxPaths, scene, pixelDevice, sampler, ss); } renderThread = null; }
public void FillRayBuffer(RayBuffer rayBuffer) { if (paths.Count == 0) { // Need at least 2 paths paths.Add(this.CreatePathSampler()); paths.Add(this.CreatePathSampler()); paths.Add(this.CreatePathSampler()); paths[0].InitPath(this); paths[1].InitPath(this); paths[2].InitPath(this); firstPath = 0; } bool allPathDone = true; lastPath = firstPath; for (; ; ) { if (!paths[lastPath].FillRayBuffer(rayBuffer)) { // Not enough free space in the RayBuffer allPathDone = false; break; } lastPath = (lastPath + 1) % paths.Count; if (lastPath == firstPath) break; } if (allPathDone) { var newPaths = 0; var maxNewPaths = maxPaths; for (; ; ) { newPaths++; if (newPaths > maxNewPaths) { firstPath = 0; lastPath = paths.Count - 1; break; } var p = this.CreatePathSampler(); paths.Add(p); p.InitPath(this); if (!p.FillRayBuffer(rayBuffer)) { firstPath = 0; lastPath = paths.Count - 2; break; } } } }
public override bool FillRayBuffer(RayBuffer rayBuffer) { var leftSpace = rayBuffer.LeftSpace(); if (leftSpace < MaxRaysPerPath) return false; RayIndex = rayBuffer.AddRay(ref PathRay); return true; }
public virtual bool FillRayBuffer(RayBuffer rayBuffer) { var leftSpace = rayBuffer.LeftSpace(); if (leftSpace < 1) return false; RayIndex = rayBuffer.AddRay(ref PathRay); return true; }
public override bool FillRayBuffer(RayBuffer rayBuffer) { var leftSpace = rayBuffer.LeftSpace(); if((1 > leftSpace)) { return false; } RayIndex = rayBuffer.AddRay(PathRay); return true; }
public override bool FillRayBuffer(RayBuffer rayBuffer) { var leftSpace = rayBuffer.LeftSpace(); if (((PathState == PathTracerPathState.EyeVertex) && (1 > leftSpace)) || ((PathState == PathTracerPathState.ShadowRaysOnly) && (tracedShadowRayCount > leftSpace)) || ((PathState == PathTracerPathState.NextVertex) && (tracedShadowRayCount + 1 > leftSpace))) return false; if (PathState != PathTracerPathState.ShadowRaysOnly) RayIndex = rayBuffer.AddRay(PathRay); return true; }
public override void Trace(RayBuffer rayBuffer) { var rb = rayBuffer.RaysInfo; var hb = rayBuffer.rayHits; var rayCount = rayBuffer.RaysInfo.Length; for (int i = 0; i < rayCount; ++i) this.Intersect(ref rb[i], ref hb[i]); statsTotalRayCount += rayCount; rayBuffer.traced = true; doneRayBuffers.Enqueue(rayBuffer); }
public override void PushRayBuffer(RayBuffer rayBuffer, int clientIdx) { if (clientIdx + 1 > doneRayBuffers.Count) { while (doneRayBuffers.Count < (clientIdx + 1)) { doneRayBuffers.Add(new ConcurrentQueue<RayBuffer>()); } } todoRayBuffers.Enqueue(new Tuple<int, RayBuffer>(clientIdx, rayBuffer)); }
public override bool FillRayBuffer(RayBuffer rayBuffer) { var leftSpace = rayBuffer.LeftSpace(); if (((this.PathState == GenericPathSamplerState.Initialize) && (1 > leftSpace)) || ((PathState == GenericPathSamplerState.Connection | PathState == GenericPathSamplerState.Evaluation) && (tracedShadowRayCount > leftSpace)) || ((this.PathState == GenericPathSamplerState.Sampling) && (1 > leftSpace))) return false; if (PathState == GenericPathSamplerState.Evaluation || PathState == GenericPathSamplerState.Connection) { for (int i = 0; i < tracedShadowRayCount; ++i) connections[i].currentShadowRayIndex = rayBuffer.AddRay(connections[i].Ray); } RayIndex = rayBuffer.AddRay(PathRay); return true; }
public override bool FillRayBuffer(RayBuffer rayBuffer) { var leftSpace = rayBuffer.LeftSpace(); if (((PathState == PathTracerPathState.EyeVertex) && (1 > leftSpace)) || ((PathState == PathTracerPathState.ShadowRaysOnly) && (tracedShadowRayCount > leftSpace)) || ((PathState == PathTracerPathState.NextVertex) && (tracedShadowRayCount + 1 > leftSpace))) return false; if (PathState != PathTracerPathState.ShadowRaysOnly) RayIndex = rayBuffer.AddRay(ref PathRay); if (PathState == PathTracerPathState.NextVertex || PathState == PathTracerPathState.ShadowRaysOnly) { for (int i = 0; i < tracedShadowRayCount; ++i) secRays[i].currentShadowRayIndex = rayBuffer.AddRay(ref secRays[i].shadowRay); } return true; }
public override bool FillRayBuffer(RayBuffer rayBuffer) { var leftSpace = rayBuffer.LeftSpace(); if (((State == RayTracerPathState.Eye) && (1 > leftSpace)) || ((State == RayTracerPathState.OnlyShadow) && (tracedShadowRayCount > leftSpace)) || ((State == RayTracerPathState.Reflection || State == RayTracerPathState.Refraction) && (tracedShadowRayCount + 1 > leftSpace))) return false; if (State != RayTracerPathState.OnlyShadow) RayIndex = rayBuffer.AddRay(ref PathRay); if (State == RayTracerPathState.Reflection || State == RayTracerPathState.Refraction || State == RayTracerPathState.OnlyShadow) { for (int i = 0; i < tracedShadowRayCount; ++i) secRays[i].ShadowRayIndex = rayBuffer.AddRay(ref secRays[i].ShadowRay); } return true; }
public RenderManager() { rayBufferLeftRight = new RayBuffer[BUFFER_COUNT]; rayBufferTopDown = new RayBuffer[BUFFER_COUNT]; blitMeshes = new Mesh[BUFFER_COUNT]; screenWidth = Screen.width; screenHeight = Screen.height; for (int i = 0; i < BUFFER_COUNT; i++) { rayBufferLeftRight[i] = new RayBuffer(screenWidth, 2 * screenWidth + screenHeight); rayBufferTopDown[i] = new RayBuffer(screenHeight, screenWidth + 2 * screenHeight); blitMeshes[i] = new Mesh(); } commandBuffer = new CommandBuffer(); }
public override bool FillRayBuffer(RayBuffer rayBuffer) { var leftSpace = rayBuffer.LeftSpace(); if (((PathState == BDPTSamplerState.InitPath) && (2 > leftSpace)) || ((PathState == BDPTSamplerState.ConnectOnly) && (tracedConnectRayCount > leftSpace)) || ((PathState == BDPTSamplerState.PropagatePath) && (tracedConnectRayCount + 2 > leftSpace))) return false; if (PathState != BDPTSamplerState.ConnectOnly) { RayIndex = rayBuffer.AddRay(ref PathRay); LightRayIndex = rayBuffer.AddRay(ref LightRay); } if (PathState == BDPTSamplerState.PropagatePath || PathState == BDPTSamplerState.ConnectOnly) { for (int i = 0; i < tracedConnectRayCount; ++i) connectRays[i].ConnectRayIndex = rayBuffer.AddRay(ref connectRays[i].ConnectRay); } return true; }
private void Init(IIntersectionEngine device, bool lowLatency, CorrectorImageFilm pixelDevice, GlobalSamplingContext sc) { this.samplers = sc; intersectionDevice = device; width = pixelDevice.Width; height = pixelDevice.Height; var rayBufferSize = lowLatency ? (RayBuffer.RayBufferSize / 8) : RayBuffer.RayBufferSize; rayBuffers = new RayBuffer[DeviceRenderBufferCount]; this.pixelDevice = pixelDevice; for (int i = 0; i < DeviceRenderBufferCount; i++) { rayBuffers[i] = new RayBuffer(rayBufferSize); rayBuffers[i].UserData = threadIndex; } _pathRayProcessors = new PathSampleProcessor(scene.MaxPaths, (RayEngineScene)scene, pixelDevice, samplers); //_pathRayProcessors.RequestSamplesFunc = (f)=>{ GenerateIm} renderThread = null; }
public NativeRenderThread(int index, CpuBvhIntersectionEngine device, RayEngineScene scn, bool lowLatency, ImageFilm pixelDevice, ISampler sampler, SurfaceSampler ss) : base(index, scn) { intersectionDevice = device; // Allocate buffers // Sample buffer var sampleBufferSize = lowLatency ? (SAMPLE_BUFFER_SIZE / 4) : SAMPLE_BUFFER_SIZE; sampleBuffer = new SampleBuffer(sampleBufferSize); // Ray buffer (small buffers work well with CPU) var rayBufferSize = 1024; this.sampler = sampler; _pathRayProcessor = new PathBuffer(scn.MaxPaths, scn, pixelDevice, new SamplingContext() { PrimarySpaceSampler = sampler, SurfaceSampler = ss, LightSampler = new LightSampler(scn)}); this.pixelDevice = pixelDevice; rayBuffer = new RayBuffer(rayBufferSize); renderThread = null; }
public virtual void Advance(RayBuffer rb, SampleBuffer sb) { }
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 }
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 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 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 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 += attenuation * ((secRays[i].color) / secRays[i].pdf); pathWeight *= secRays[i].pdf; } } Splat(consumer); return; } depth++; bool missed = rayHit.Index == 0xffffffffu; if (missed || PathState == PathTracerPathState.ShadowRaysOnly || depth > sceneMaxPathDepth) { if (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); } 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; } } Splat(consumer); return; } var hitPoint = PathRay.Point(rayHit.Distance); Vector wo = -PathRay.Dir; tracedShadowRayCount = 0; var bsdf = hitInfo.MMaterial; if (bsdf.IsDiffuse()) { float lightStrategyPdf = scene.ShadowRayCount; RgbSpectrum lightTroughtput = Throughput * hitInfo.Color; LightSampler.EvaluateShadow(ref hitPoint, ref hitInfo.Normal, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), ref ls); foreach (var lightSample in ls) { if (lightSample.Pdf <= 0f) continue; secRays[tracedShadowRayCount].color = (RgbSpectrum)(lightSample.Spectrum); secRays[tracedShadowRayCount].pdf = lightSample.Pdf; secRays[tracedShadowRayCount].shadowRay = lightSample.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.Normal, ref lwi) * fs; if (!secRays[tracedShadowRayCount].color.IsBlack()) { secRays[tracedShadowRayCount].pdf *= lightStrategyPdf; tracedShadowRayCount++; } } } float fPdf; Vector wi; 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); if ((fPdf <= 0.0f) || f.IsBlack()) { if (tracedShadowRayCount > 0) PathState = PathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } pathWeight *= fPdf; Throughput *= (f) / fPdf; if (depth > sceneMaxPathDepth) { 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 virtual void Advance(RayBuffer rayBuffer, SampleBuffer<IColorType> consumer) { Splat(consumer); InitPath(this.Processor); }
public void Trace(RayBuffer rayBuffer) { cudaContext.Context.SetCurrent(); var raysArg = rayBuffer.RaysInfo; this.rays.CopyToDevice(raysArg); GCHandle raysHandle = GCHandle.Alloc(raysArg, GCHandleType.Pinned); intersectKernel.BlockDimensions = threadsPerBlock; intersectKernel.GridDimensions = (raysArg.Length + threadsPerBlock - 1) / threadsPerBlock; intersectKernel.Run(this.rays.DevicePointer, this.hits.DevicePointer, this.verts.DevicePointer, this.tris.DevicePointer, this.bvh.DevicePointer, this.scene.Triangles.Count, nodesCount, raysArg.Length); this.hits.CopyToHost(rayBuffer.rayHits); rayBuffer.traced = true; raysHandle.Free(); }
public override void Trace(RayBuffer rayBuffer) { //if (rayBuffer.RaysInitialized == 0) //{ // Debugger.Break(); //} var raysArg = rayBuffer.RaysInfo; var raysHandle = GCHandle.Alloc(raysArg, GCHandleType.Pinned); uint size = lowLatency ? (uint)(Math.Sqrt(RayBuffer.RayBufferSize / 8)) : (uint)(Math.Sqrt(RayBuffer.RayBufferSize)); trav.SetRayData(rayBuffer.RaysInfo); trav.Traverse(); var result = new TraversalResult[rayBuffer.RaysInfo.Length]; var coords = new Vector2[rayBuffer.RaysInfo.Length]; trav.GetResults(result); trav.GetBaryCentricOutput(coords); rayBuffer.rayHits = result.Select((rh, i) => new RayHit { Distance = rh.T, Index = (uint)rh.T, U = coords[i].X, V = coords[i].Y, }).ToArray(); rayBuffer.traced = true; raysHandle.Free(); }
static unsafe void DrawSegments( NativeArray <SegmentData> segments, World *worldLODs, CameraData camera, int screenWidth, int screenHeight, float2 vanishingPointScreenSpace, RayBuffer.Native rayBufferTopDown, RayBuffer.Native rayBufferLeftRight, RayBuffer rayBufferTopDownManaged, RayBuffer rayBufferLeftRightManaged ) { float2 screen = new float2(screenWidth, screenHeight); Profiler.BeginSample("Segment setup overhead"); DrawSegmentRayJob.DrawContext drawContext = new DrawSegmentRayJob.DrawContext { camera = camera, screen = screen, worldLODs = worldLODs }; NativeArray <DrawSegmentRayJob.SegmentContext> segmentContexts = new NativeArray <DrawSegmentRayJob.SegmentContext>(4, Allocator.TempJob, NativeArrayOptions.ClearMemory); DrawSegmentRayJob.SegmentContext *segmentContextPtr = (DrawSegmentRayJob.SegmentContext *)segmentContexts.GetUnsafePtr(); int totalRays = 0; for (int segmentIndex = 0; segmentIndex < segments.Length; segmentIndex++) { DrawSegmentRayJob.SegmentContext *context = segmentContextPtr + segmentIndex; context->segment = segments[segmentIndex]; totalRays += segments[segmentIndex].RayCount; if (segments[segmentIndex].RayCount <= 0) { continue; } context->axisMappedToY = (segmentIndex > 1) ? 0 : 1; context->segmentRayIndexOffset = 0; if (segmentIndex == 1) { context->segmentRayIndexOffset = segments[0].RayCount; } if (segmentIndex == 3) { context->segmentRayIndexOffset = segments[2].RayCount; } int2 nextFreePixel; if (segmentIndex < 2) { context->activeRayBufferFull = rayBufferTopDown; if (segmentIndex == 0) // top segment { nextFreePixel = int2(clamp(Mathf.RoundToInt(vanishingPointScreenSpace.y), 0, screenHeight - 1), screenHeight - 1); } else // bottom segment { nextFreePixel = int2(0, clamp(Mathf.RoundToInt(vanishingPointScreenSpace.y), 0, screenHeight - 1)); } } else { context->activeRayBufferFull = rayBufferLeftRight; if (segmentIndex == 3) // left segment { nextFreePixel = int2(0, clamp(Mathf.RoundToInt(vanishingPointScreenSpace.x), 0, screenWidth - 1)); } else // right segment { nextFreePixel = int2(clamp(Mathf.RoundToInt(vanishingPointScreenSpace.x), 0, screenWidth - 1), screenWidth - 1); } } context->originalNextFreePixelMin = nextFreePixel.x; context->originalNextFreePixelMax = nextFreePixel.y; context->seenPixelCacheLength = (int)ceil(drawContext.screen[context->axisMappedToY]); } Profiler.EndSample(); rayBufferTopDownManaged.Prepare(segments[0].RayCount + segments[1].RayCount); rayBufferLeftRightManaged.Prepare(segments[2].RayCount + segments[3].RayCount); NativeArray <DrawSegmentRayJob.RayContext> rayContext = new NativeArray <DrawSegmentRayJob.RayContext>( totalRays, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeArray <DrawSegmentRayJob.RayDDAContext> rayDDAContext = new NativeArray <DrawSegmentRayJob.RayDDAContext>( totalRays, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); NativeList <DrawSegmentRayJob.RayContinuation> rayContinuations = new NativeList <DrawSegmentRayJob.RayContinuation>( totalRays, Allocator.TempJob); DrawSegmentRayJob.RaySetupJob raySetupJob = new DrawSegmentRayJob.RaySetupJob() { contexts = segmentContexts, rays = rayContext }; DrawSegmentRayJob.DDASetupJob ddaSetupJob = new DrawSegmentRayJob.DDASetupJob() { raysInput = rayContext, raysOutput = rayDDAContext, drawContext = drawContext, }; DrawSegmentRayJob.TraceToFirstColumnJob firstColumnJob = new DrawSegmentRayJob.TraceToFirstColumnJob { drawContext = drawContext, inRays = rayDDAContext, outRays = rayContinuations.AsParallelWriter() }; DrawSegmentRayJob.RenderJob renderJob = new DrawSegmentRayJob.RenderJob { rays = rayContinuations, DrawingContext = drawContext, }; JobHandle setup = raySetupJob.Schedule(totalRays, 64); JobHandle ddaSetup = ddaSetupJob.Schedule(totalRays, 64, setup); JobHandle firstColumn = firstColumnJob.Schedule(totalRays, 4, ddaSetup); JobHandle render = renderJob.Schedule(totalRays, 1, firstColumn); render.Complete(); rayContext.Dispose(); segmentContexts.Dispose(); rayDDAContext.Dispose(); rayContinuations.Dispose(); rayBufferTopDownManaged.UploadCompletes(); rayBufferLeftRightManaged.UploadCompletes(); }
public virtual void FillRayBuffer(RayBuffer rb) { }
public unsafe void DrawWorld(Material blitMaterial, World[] worldLODs, Camera camera, Camera actualCamera, float[] LODDistances) { Mesh blitMesh = blitMeshes[bufferIndex]; Debug.DrawLine(new Vector2(0f, 0f), new Vector2(screenWidth, 0f)); Debug.DrawLine(new Vector2(screenWidth, 0f), new Vector2(screenWidth, screenHeight)); Debug.DrawLine(new Vector2(screenWidth, screenHeight), new Vector2(0f, screenHeight)); Debug.DrawLine(new Vector2(0f, screenHeight), new Vector2(0f, 0f)); Profiler.BeginSample("Setup VP"); float3 vanishingPointWorldSpace = CalculateVanishingPointWorld(camera); float2 vanishingPointScreenSpace = ProjectVanishingPointScreenToWorld(camera, vanishingPointWorldSpace); Profiler.EndSample(); float2 screen = new float2(screenWidth, screenHeight); NativeArray <SegmentData> segments = new NativeArray <SegmentData>(4, Allocator.Temp, NativeArrayOptions.ClearMemory); Profiler.BeginSample("Setup segment params"); if (vanishingPointScreenSpace.y < screenHeight) { segments[0] = GetGenericSegmentParameters(camera, screen, vanishingPointScreenSpace, screenHeight - vanishingPointScreenSpace.y, new float2(0, 1), 1, worldLODs[0].DimensionY); } if (vanishingPointScreenSpace.y > 0f) { segments[1] = GetGenericSegmentParameters(camera, screen, vanishingPointScreenSpace, vanishingPointScreenSpace.y, new float2(0, -1), 1, worldLODs[0].DimensionY); } if (vanishingPointScreenSpace.x < screenWidth) { segments[2] = GetGenericSegmentParameters(camera, screen, vanishingPointScreenSpace, screenWidth - vanishingPointScreenSpace.x, new float2(1, 0), 0, worldLODs[0].DimensionY); } if (vanishingPointScreenSpace.x > 0f) { segments[3] = GetGenericSegmentParameters(camera, screen, vanishingPointScreenSpace, vanishingPointScreenSpace.x, new float2(-1, 0), 0, worldLODs[0].DimensionY); } Profiler.EndSample(); RayBuffer activeRaybufferTopDown = rayBufferTopDown[bufferIndex]; RayBuffer activeRaybufferLeftRight = rayBufferLeftRight[bufferIndex]; RayBuffer.Native topDownNative = activeRaybufferTopDown.GetNativeData(Allocator.TempJob); RayBuffer.Native leftRightNative = activeRaybufferLeftRight.GetNativeData(Allocator.TempJob); commandBuffer.Clear(); CameraData camData = new CameraData(camera, LODDistances, screen); Profiler.BeginSample("Draw planes"); fixed(World *worldPtr = worldLODs) { DrawSegments(segments, worldPtr, camData, screenWidth, screenHeight, vanishingPointScreenSpace, topDownNative, leftRightNative, activeRaybufferTopDown, activeRaybufferLeftRight ); } Profiler.EndSample(); topDownNative.Dispose(); leftRightNative.Dispose(); Profiler.BeginSample("Apply textures"); activeRaybufferTopDown.ApplyPartials(commandBuffer); activeRaybufferLeftRight.ApplyPartials(commandBuffer); Profiler.EndSample(); Profiler.BeginSample("Blit raybuffer"); BlitSegments( camera, blitMaterial, blitMesh, activeRaybufferTopDown.FinalTexture, activeRaybufferLeftRight.FinalTexture, segments, vanishingPointScreenSpace, screen, commandBuffer ); Profiler.EndSample(); actualCamera.RemoveAllCommandBuffers(); actualCamera.AddCommandBuffer(CameraEvent.AfterForwardOpaque, commandBuffer); }
public void RebuildGraph() { HitBuffer.RebuildGraph(); RayBuffer.RebuildGraph(); }
public override void Trace(RayBuffer rayBuffer) { //if (rayBuffer.RaysInitialized == 0) //{ // Debugger.Break(); //} var raysArg = rayBuffer.RaysInfo; var raysHandle = GCHandle.Alloc(raysArg, GCHandleType.Pinned); uint size = lowLatency ? (uint)(Math.Sqrt(RayBuffer.RayBufferSize / 8)) : (uint)(Math.Sqrt(RayBuffer.RayBufferSize)); trav.SetRayData(rayBuffer.RaysInfo.Select(r=>new RayMinMax(ToVec3(ref r.Org), ToVec3(ref r.Dir), r.maxT, r.maxT)).ToArray()); trav.Traverse(); rayBuffer.rayHits = trav.GetHitData().Select((rh, i) => new RayHit { Distance = rh.Distance, Index = (uint)rh.Index, U = rh.U, V = rh.V, }).ToArray(); rayBuffer.traced = true; raysHandle.Free(); }
public override void PushRayBuffer(RayBuffer rayBuffer, int clientIdx) { if (clientIdx + 1 > doneRayBuffers.Count) { while (doneRayBuffers.Count < (clientIdx + 1)) { doneRayBuffers.AddBuffer(); } } todoRayBuffers.Put(new Tuple<int, RayBuffer>(clientIdx, rayBuffer)); }
public override void Advance(RayBuffer rayBuffer, SampleBuffer consumer) { int currentTriangleIndex = 0; #if VERBOSE try { #endif base.Advance(rayBuffer, consumer); RayHit rayHit = rayBuffer.rayHits[RayIndex]; depth++; bool missed = rayHit.Index == 0xffffffffu; if (missed || depth > scene.MaxPathDepth) { if (missed) { vertices[currentVertex].Event = BsdfEvent.Environment; vertices[currentVertex++].ThroughtPut = this.SampleEnvironment(PathRay.Dir); } 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; if (hitInfo.IsLight) { { var lt = scene.GetLightByIndex(currentTriangleIndex); //if (lt != null) { var le = (RgbSpectrum)(RgbSpectrumInfo)(lt.Le(ref PathRay.Dir)); vertices[currentVertex].Event = BsdfEvent.Light; vertices[currentVertex++].ThroughtPut = le; } } Splat(consumer); return; } var hitPoint = PathRay.Point(rayHit.Distance); vertices[currentVertex].HitPoint = hitPoint; Vector wo = -PathRay.Dir; tracedShadowRayCount = 0; float fPdf; Vector wi; BsdfEvent @evt; 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 @evt); specularBounce = evt.Has(BsdfEvent.Specular); if ((fPdf <= 0.0f) || f.IsBlack()) { if (tracedShadowRayCount > 0) PathState = PurePathTracerPathState.ShadowRaysOnly; else { vertices[currentVertex].Event = BsdfEvent.Absorb; Splat(consumer); } return; } pathWeight *= fPdf; Throughput *= (f * hitInfo.Color) / fPdf; vertices[currentVertex].HitPoint = hitPoint; vertices[currentVertex].Wi = wi; vertices[currentVertex].Wo = wo; vertices[currentVertex].ShadeNormal = hitInfo.ShadingNormal; vertices[currentVertex].TriangleIndex = currentTriangleIndex; vertices[currentVertex].Bsdf = hitInfo.MMaterial; vertices[currentVertex].Event = @evt; vertices[currentVertex].BsdfSample = f; vertices[currentVertex].BsdfWeight = fPdf; vertices[currentVertex].ThroughtPut = (f * hitInfo.Color) / fPdf; if (depth > scene.MaxPathDepth) { float prob = Math.Max(Throughput.Filter(), scene.RussianRuletteImportanceCap); if (prob >= Sample.GetLazyValue()) { Throughput /= prob; vertices[currentVertex].ThroughtPut/=prob; vertices[currentVertex].RRProbability = 1f / prob; pathWeight *= prob; } else { if (tracedShadowRayCount > 0) PathState = PurePathTracerPathState.ShadowRaysOnly; else { vertices[currentVertex].Event = BsdfEvent.Absorb; Splat(consumer); } return; } } PathRay.Org = hitPoint; PathRay.Dir = wi.Normalize(); PathState = PurePathTracerPathState.NextVertex; currentVertex++; #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 void Update() { HitBuffer.Update(); RayBuffer.Update(); }
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 base.Advance(rayBuffer, consumer); RayHit rayHit = rayBuffer.rayHits[RayIndex]; Depth++; bool missed = rayHit.Index == 0xffffffffu; var wo = -PathRay.Dir; if (missed || Depth > maxDepth) { if (specularBounce && missed) { Radiance.Add(Throughput.Mul(ColorManager.Instance.Convert(this.SampleEnvironment(ref wo)))); } Splat(consumer); return; } HitManager.Instance.EvalHit(ref PathRay, ref rayHit, ref hitInfo); currentTriangleIndex = (int)rayHit.Index; //If Hit light) if (hitInfo.PointType == ShadePointType.Light) { float lpdf; var lt = this.Buffer.SceneManager.GetLightById(hitInfo.ObjectId); var le = lt.Light.Emit(ref wo, out lpdf); Radiance.Add(Throughput.Mul(le)); Splat(consumer); return; } var hitPoint = PathRay.Point(rayHit.Distance); tracedShadowRayCount = 0; float fPdf; Vector wi; float f; BsdfEvent @event; hitInfo.Brdf.Sample_f(hitInfo, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), out wi, out f, out fPdf, out @event); if ((fPdf <= 0.0f) || f<=0f) { if (tracedShadowRayCount > 0) PathState = PurePathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } Throughput.Mul(hitInfo.GetColorInstance()).Mul(f / fPdf); if (Depth > maxDepth) { float prob = Math.Max(Throughput.Filter(), RussianRuletteImportanceCap); if (prob >= Sample.GetLazyValue()) { Throughput.Mul(1f / prob); } else { if (tracedShadowRayCount > 0) PathState = PurePathTracerPathState.ShadowRaysOnly; else { Splat(consumer); } return; } } PathRay.Org = hitPoint; PathRay.Dir = wi.Normalize(); PathState = PurePathTracerPathState.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)) { 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 }