示例#1
0
        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;
        }
示例#2
0
        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;
                    }
                }
            }
        }
示例#3
0
 public override bool FillRayBuffer(RayBuffer rayBuffer)
 {
     var leftSpace = rayBuffer.LeftSpace();
     if (leftSpace < MaxRaysPerPath)
         return false;
     RayIndex = rayBuffer.AddRay(ref PathRay);
     return true;
 }
示例#4
0
        public virtual bool FillRayBuffer(RayBuffer rayBuffer)
        {
            var leftSpace = rayBuffer.LeftSpace();
            if (leftSpace < 1)
                return false;

            RayIndex = rayBuffer.AddRay(ref PathRay);

            return true;
        }
示例#5
0
 public override bool FillRayBuffer(RayBuffer rayBuffer)
 {
     var leftSpace = rayBuffer.LeftSpace();
     if((1 > leftSpace))
     {
         return false;
     }
     RayIndex = rayBuffer.AddRay(PathRay);
     return true;
 }
示例#6
0
 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;
 }
示例#10
0
 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;
 }
示例#11
0
 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;
 }
示例#12
0
    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();
    }
示例#13
0
 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;
 }
示例#14
0
        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;
        }
示例#15
0
        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;
        }
示例#16
0
 public virtual void Advance(RayBuffer rb, SampleBuffer sb)
 {
     
 }
示例#17
0
        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
        }
示例#18
0
        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
        }
示例#19
0
        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
        }
示例#20
0
        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
        }
示例#21
0
        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
        }
示例#22
0
 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();
        }
示例#25
0
    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();
    }
示例#26
0
 public virtual void FillRayBuffer(RayBuffer rb)
 {
     
 }
示例#27
0
    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);
    }
示例#28
0
 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));
 }
示例#31
0
        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
        }
示例#32
0
 public void Update()
 {
     HitBuffer.Update();
     RayBuffer.Update();
 }
示例#33
0
        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
        }
示例#34
0
        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
        }
示例#35
0
        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
        }