Пример #1
0
        public bool NextVertex(ref SurfaceIntersectionData hit, ref RayData pathRay, ref RgbSpectrum throughput, int depth, out float pdf)
        {
            var currentTriangleIndex = (int)hit.Hit.Index;
            var lt = Scene.GetLightByIndex(currentTriangleIndex);
            var wo = -pathRay.Dir;
            pdf = 1f;
            if (hit.Brdf.IsSpecular() || depth == 1)
            {
                if (lt != null)
                {
                    var le = hit.Color * lt.Emittance(ref wo, out pdf);
                    throughput.MAdd(ref throughput, ref le);
                }
            }

            return false;
        }
Пример #2
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
        }
Пример #3
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];

            if (((PathState == PathTracerPathState.ShadowRaysOnly) || (PathState == PathTracerPathState.NextVertex)) &&
                (tracedShadowRayCount > 0))
            {
                for (int i = 0; i < tracedShadowRayCount; ++i)
                {
                    RayHit shadowRayHit = rayBuffer.rayHits[secRays[i].currentShadowRayIndex];
                    RgbSpectrum attenuation;
                    bool continueTrace;
                    if (this.ShadowRayTest(ref shadowRayHit, ref secRays[i].shadowRay, out attenuation, out continueTrace))
                    {
                        //                            Radiance.MADD()
                        Radiance += ((secRays[i].color) / secRays[i].pdf);
                        pathWeight *= secRays[i].pdf;
                        var d = secRays[i].shadowRay.Point(shadowRayHit.Distance);
                        var pix = scene.Camera.UnProject(ref d);
                        this.Splat(consumer, pix.x, 720f - pix.y, ref Radiance );
                    }
                }

                if (PathState == PathTracerPathState.ShadowRaysOnly)
                {
                    Splat(consumer);
                    return;
                }
                tracedShadowRayCount = 0;

            }

            depth++;
            bool missed = rayHit.Index == 0xffffffffu;
            if (missed || PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth)
            {
                if (missed)
                {
                    RgbSpectrum env;
                    this.SampleEnvironment(ref PathRay.Dir, out env);
                    Radiance += env * Throughput;
                }
                Splat(consumer);

                return;
            }

            // Something was hit
            if (hitInfo == null)
            {
                hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, IntersectionOptions.ResolveObject);
            }
            else
            {
                SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, ref hitInfo, IntersectionOptions.ResolveObject);
            }
            currentTriangleIndex = (int)rayHit.Index;

            if (hitInfo == null)
            {
                Debugger.Break();
            }
            Vector wo = -PathRay.Dir;
            var hitPoint = PathRay.Point(rayHit.Distance);

            //If Hit light)
            if (hitInfo.IsLight)
            {
                //if (specularBounce || depth == 1)
                {
                    var lt = scene.GetLightByIndex(currentTriangleIndex);
                    if (lt != null)
                    {
                        var le = (RgbSpectrum)(lt.Le(ref wo));
                        Throughput *= le;
                        AddEyeRay(ref hitPoint, ref wo, ref Throughput, 1f);
                        PathState = PathTracerPathState.ShadowRaysOnly;
                        return;
                    }
                }
           }


            var bsdf = hitInfo.MMaterial;

            if (bsdf.IsDiffuse())
            {
                float lightStrategyPdf = 1f;
                //scene.ShadowRaysPerSample/(float)scene.Lights.Length;
                var lightTroughtput = Throughput*hitInfo.Color;

                AddEyeRay(ref hitPoint, ref wo, ref lightTroughtput, lightStrategyPdf );

           }

            float fPdf = 0f;
            var wi = new Vector();
            RgbSpectrum f;
     
            f = bsdf.Sample_f(ref wo, out wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref Throughput,
                                Sample.GetLazyValue(), Sample.GetLazyValue(),
                                Sample.GetLazyValue(), ref hitInfo.TextureData,
                                out fPdf, out specularBounce)*hitInfo.Color;

            if ((fPdf <= 0.0f) || f.IsBlack())
            {
                if (tracedShadowRayCount > 0)
                    PathState = PathTracerPathState.ShadowRaysOnly;
                else
                {
                    Splat(consumer);

                }
                return;
            }
            pathWeight *= fPdf;
            Throughput *= f / fPdf;

            if (depth > scene.MaxPathDepth)
            {
                float prob = Math.Max(Throughput.Filter(), scene.RussianRuletteImportanceCap);
                if (prob >= Sample.GetLazyValue())
                {
                    Throughput /= prob;
                    pathWeight *= prob;
                }
                else
                {
                    if (tracedShadowRayCount > 0)
                        PathState = PathTracerPathState.ShadowRaysOnly;
                    else
                    {
                        Splat(consumer);

                    }

                    return;
                }
            }

            PathRay.Org = hitPoint;
            PathRay.Dir = wi.Normalize();
            PathState = PathTracerPathState.NextVertex;

#if VERBOSE
            }
            catch (Exception ex) {
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Advance path exception");
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Error triangle {0}", currentTriangleIndex);
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message);
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace);

            }
#endif
        }
Пример #4
0
        public override void Advance(RayBuffer rayBuffer, SampleBuffer consumer)
        {
            int currentTriangleIndex = 0;
#if VERBOSE

            try {
#endif

            base.Advance(rayBuffer, consumer);

            var rayHit = rayBuffer.rayHits[RayIndex];

            depth++;
            var missed = rayHit.Index == 0xffffffffu;
            var wo = -PathRay.Dir;

            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;

            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())
            {
                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
                {

                    Splat(consumer);
                    return;
                }
            }

            PathRay.Org = hitPoint;
            PathRay.Dir = wi.Normalize();

#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
        }
Пример #5
0
        public SurfaceIntersectionData GetIntersection(ref RayData PathRay, ref RayHit hit, IntersectionOptions flags)
        {
            var ii = new SurfaceIntersectionData(ref hit, false);

            EvalIntersectionAdvanced(ref PathRay, ref hit, ref ii, flags);

            return ii;
        }
Пример #6
0
 public bool Match(ref SurfaceIntersectionData hit)
 {
     return hit.Brdf.IsDiffuse();
 }
Пример #7
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
        }
Пример #8
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
        }
Пример #9
0
        public override void Advance(Core.Types.RayBuffer rayBuffer, Core.Types.SampleBuffer consumer)
        {
            int currentTriangleIndex = 0;
#if VERBOSE

            try {
#endif

            if (((PathState == PathTracerPathState.ShadowRaysOnly) || (PathState == PathTracerPathState.NextVertex)) &&
                (tracedShadowRayCount > 0))
            {
                for (int i = 0; i < tracedShadowRayCount; ++i)
                {
                    RayHit shadowRayHit = rayBuffer.rayHits[secRays[i].ShadowRayIndex];
                    RgbSpectrum attenuation;
                    bool continueTrace;
                    if (this.ShadowRayTest(ref shadowRayHit, ref secRays[i].ShadowRay, out attenuation, out continueTrace))
                    {
                        float weight = 1f;//tracedShadowRayCount;
                        //                            Radiance.MADD()
                        Radiance += attenuation * (secRays[i].Throughput /(weight*secRays[i].Pdf))*100f;
                        pathWeight *= secRays[i].Pdf;
                    }
                }

                if (PathState == PathTracerPathState.ShadowRaysOnly)
                {
                    Splat(consumer);
                    return;
                }
                tracedShadowRayCount = 0;
            }
            RayHit eyeRayHit = rayBuffer.rayHits[RayIndex];
            Vector wo = -PathRay.Dir;

            depth++;
            bool eyeMissed = eyeRayHit.Index == 0xffffffffu;
            if (eyeMissed && lightDepth > 0 && tracedShadowRayCount > 0)
            {
                Console.WriteLine("!");
                
            }

            if (eyeMissed || PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth)
            {
                if (eyeMissed)
                {
                    Radiance += this.scene.SampleEnvironment(ref wo) * Throughput;
                }
                Splat(consumer);

                return;
            }

            // Something was hit
            if (hitInfo == null)
            {
                hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref eyeRayHit);
            }
            else
            {
                SurfaceSampler.GetIntersection(ref PathRay, ref eyeRayHit, ref hitInfo);
            }
            currentTriangleIndex = (int)eyeRayHit.Index;

            if (hitInfo == null)
            {
                Debugger.Break();
            }
            //If Hit light)

            if (hitInfo.IsLight)
            {
                if (specularBounce || depth == 1)
                {
                    var lt = scene.GetLightByIndex(currentTriangleIndex);
                    if (lt != null)
                    {
#if !NOIMPLICIT
                        var le = (RgbSpectrumInfo)(lt.Le(ref wo));
                        Radiance += Throughput * (RgbSpectrum)le;
#endif
                    }
                }
                Splat(consumer);
                return;
            }

            if (!lightStoped)
            {
                RayHit lightRayHit = rayBuffer.rayHits[LightRayIndex];
                if (lightRayHit.Miss())
                {
                    this.RestartLight();
                }
                else
                {
                    lightDepth++;
                    if (lightHitInfo == null)
                    {
                        lightHitInfo = SurfaceSampler.GetIntersection(ref LightRay, ref lightRayHit,
                                                                      IntersectionOptions.ResolveSurfaceComplete |
                                                                      IntersectionOptions.ResumeOnLight);
                    }
                    else
                    {
                        SurfaceSampler.GetIntersection(ref LightRay, ref lightRayHit, ref lightHitInfo,
                                                                      IntersectionOptions.ResolveSurfaceComplete |
                                                                      IntersectionOptions.ResumeOnLight);
                    }

                    float lPdf = 0f;
                    var lwi = new Vector();
                    var lhp = LightRay.Point(lightRayHit.Distance);
                    var lf = lightHitInfo.MMaterial.Sample_f(ref wo, out lwi, ref hitInfo.Normal,
                                                             ref hitInfo.ShadingNormal, ref Throughput,
                                                             Sample.GetLazyValue(), Sample.GetLazyValue(),
                                                             Sample.GetLazyValue(), ref hitInfo.TextureData,
                                                             out lPdf, out specularBounce);
                    var scatteringCorrection = Vector.AbsDot(ref wo, ref hitInfo.Normal) /
                                                    Vector.AbsDot(ref wo, ref hitInfo.ShadingNormal);
                    scatteringCorrection *=  Vector.AbsDot(ref lwi, ref hitInfo.ShadingNormal);
                    if (lPdf <= 0f || lf.IsBlack())
                    {
                        this.RestartLight();
                        goto eyeCont;
                    }
                    if (lightDepth 
#if DIRECT_EXPLICIT
                        > 1)
#else
                        > 0)
#endif

                    {

                        float da = (currentLightVertex > 0 ? this.lightVertices[currentLightVertex - 1].dAWeight : 1.0f)*lightWeight;

                        this.lightVertices[currentLightVertex] = new LightVertex()
                            {
                                HitPoint = lhp,
                                Normal = lightHitInfo.ShadingNormal,
                                BsdfWeight = lPdf,
                                BsdfSample = lf*scatteringCorrection,
                                dAWeight = da*(currentLightVertex > 0 
                                            ?
                                                lPdf*Geometry.G(ref lhp, ref lightVertices[currentLightVertex-1].HitPoint,ref hitInfo.ShadingNormal,ref lightVertices[currentLightVertex-1].Normal)
                                            : lPdf)*scatteringCorrection,
                                Throughput = LightThroughtput,
                                Wi = LightRay.Dir,
                            };
                        currentLightVertex++;
                    }
                    
                    LightThroughtput *= (lf / lPdf)*scatteringCorrection;
                    LightRay = new RayData(ref lhp, ref lwi);
                }
                lightStoped = currentLightVertex > scene.MaxPathDepth || LightThroughtput.IsBlack();
            }

            //if (currentLightVertex > 3)
            //{
            //    Debugger.Break();
            //}
        eyeCont:
            var hitPoint = PathRay.Point(eyeRayHit.Distance);

            tracedShadowRayCount = 0;
            var bsdf = hitInfo.MMaterial;

            if (bsdf.IsDiffuse())
            {
#if DIRECT_EXPLICIT
                float lightStrategyPdf = LightSampler.StrategyPdf;
                //scene.ShadowRaysPerSample/(float)scene.Lights.Length;
                RgbSpectrum lightTroughtput = Throughput * hitInfo.Color;
                LightSampler.EvaluateShadow(ref hitPoint, ref hitInfo.Normal, Sample.GetLazyValue(),
                                            Sample.GetLazyValue(), Sample.GetLazyValue(), ref ls);
                for (int index = 0; index < ls.Length; index++)
                {

                    if (ls[index].Pdf <= 0f)
                        continue;
                    secRays[tracedShadowRayCount].Throughput = (RgbSpectrum)(RgbSpectrumInfo)(ls[index].Spectrum);
                    secRays[tracedShadowRayCount].Pdf = ls[index].Pdf;
                    secRays[tracedShadowRayCount].ShadowRay = ls[index].LightRay;
                    Vector lwi = secRays[tracedShadowRayCount].ShadowRay.Dir;
                    RgbSpectrum fs;
                    hitInfo.MMaterial.f(ref secRays[tracedShadowRayCount].ShadowRay.Dir, ref wo, ref hitInfo.ShadingNormal, ref lightTroughtput, out fs, BrdfType.Diffuse);
                    secRays[tracedShadowRayCount].Throughput *= lightTroughtput *
                                                                Vector.AbsDot(ref hitInfo.Normal, ref lwi) *
                                                                fs;
                    if (!secRays[tracedShadowRayCount].Throughput.IsBlack())
                    {
                        secRays[tracedShadowRayCount].Pdf /= lightStrategyPdf;
                        tracedShadowRayCount++;
                    }
                }
#endif
                for (int index = 0; index < currentLightVertex; index++)
                {
                    if (lightVertices[index].Throughput.IsBlack())
                        continue;

                    var lwi = lightVertices[index].Wi;
                    RgbSpectrum fs;
                    hitInfo.MMaterial.f(ref lwi, ref wo, ref hitInfo.ShadingNormal, ref Throughput, out fs, types: BrdfType.Diffuse);
                    var dir = lightVertices[index].HitPoint - hitPoint;
                    var dirLength = dir.Length;
                    dir.NormalizeSelf();

                    secRays[tracedShadowRayCount].Throughput = Throughput*lightVertices[index].Throughput
                                                               *fs
                                                               *lightVertices[index].BsdfSample
                                                               //* Vector.AbsDot(ref hitInfo.Normal, ref lwi) 
                                                               *Geometry.G(ref hitPoint, ref lightVertices[index].HitPoint,ref hitInfo.Normal,ref lightVertices[index].Normal);

                    secRays[tracedShadowRayCount].Pdf = (pathWeight*lightVertices[index].dAWeight)
                        ;
                    //    * Geometry.G(ref hitPoint, ref lightVertices[index].HitPoint, ref hitInfo.Normal, ref lightVertices[index].Normal);
                        //1f/(depth+index) * (pathWeight*lightVertices[index].dAWeight);
                    secRays[tracedShadowRayCount].ShadowRay = new RayData(ref hitPoint, ref dir, 1e-4f, dirLength-1e-4f);
                    tracedShadowRayCount++;
                }
            }

            float fPdf = 0f;
            var wi = new Vector();
            RgbSpectrum f;

            f = bsdf.Sample_f(ref wo, out wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref Throughput,
                                Sample.GetLazyValue(), Sample.GetLazyValue(),
                                Sample.GetLazyValue(), ref hitInfo.TextureData,
                                out fPdf, out specularBounce);

            if ((fPdf <= 0.0f) || f.IsBlack())
            {
                if (tracedShadowRayCount > 0)
                    PathState = PathTracerPathState.ShadowRaysOnly;
                else
                {
                    Splat(consumer);

                }
                return;
            }
            pathWeight *= fPdf;
            Throughput *= (f) / fPdf;

            if (depth > scene.MaxPathDepth)
            {
                float prob = Math.Max(Throughput.Filter(), scene.RussianRuletteImportanceCap);
                if (prob >= Sample.GetLazyValue())
                {
                    Throughput /= prob;
                    pathWeight *= prob;
                }
                else
                {
                    if (tracedShadowRayCount > 0)
                        PathState = PathTracerPathState.ShadowRaysOnly;
                    else
                    {
                        Splat(consumer);

                    }

                    return;
                }
            }

            PathRay.Org = hitPoint;
            PathRay.Dir = wi.Normalize();
            PathState = PathTracerPathState.NextVertex;

#if VERBOSE
            }
            catch (Exception ex) {
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Advance path exception");
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Error triangle {0}", currentTriangleIndex);
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message);
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace);

            }
#endif
        }
Пример #10
0
        public override void Advance(RayBuffer rayBuffer, SampleBuffer consumer)
        {
#if VERBOSE
            try
            {
#endif
                base.Advance(rayBuffer, consumer);



                var rayHit = new RayHit();

                Vector wo = -PathRay.Dir;

                switch (PathState)
                {
                    case PathTracerPathState.EyeVertex:
                        float t, t1;
                        if (scene.VolumeIntegrator != null && scene.VolumeIntegrator.GetBounds().Intersect(PathRay, out t, out t1))
                        {
                            rayHit = rayBuffer.rayHits[RayIndex];

                            // Use Russian Roulette to check if I have to do participating media computation or not
                            if (Sample.GetLazyValue() <= scene.VolumeIntegrator.GetRRProbability())
                            {
                                RayData volumeRay = new RayData(ref PathRay.Org, ref PathRay.Dir, 0f,
                                                                rayHit.Miss() ? 1e10f : rayHit.Distance);
                                scene.VolumeIntegrator.GenerateLiRays(scene, Sample, ref volumeRay, volumeComp);
                                Radiance += volumeComp.GetEmittedLight();

                                if (volumeComp.GetRayCount() > 0)
                                {
                                    // Do the EYE_VERTEX_VOLUME_STEP
                                    PathState = PathTracerPathState.EyeVolume;
                                    eyeHit = (rayBuffer.rayHits[RayIndex]);
                                    return;
                                }
                            }
                        }
                        else
                        {
                            rayHit = rayBuffer.rayHits[RayIndex];
                        }
                        break;
                    case PathTracerPathState.NextVertex:
                        rayHit = rayBuffer.rayHits[RayIndex];
                        break;
                    case PathTracerPathState.EyeVolume:
                        Radiance += Throughput * volumeComp.CollectResults(rayBuffer) /
                                    scene.VolumeIntegrator.GetRRProbability();
                        rayHit = eyeHit;
                        break;
                }

                if (((PathState == PathTracerPathState.ShadowRaysOnly) || (PathState == PathTracerPathState.NextVertex)) &&
                    (tracedShadowRayCount > 0))
                {
                    for (int i = 0; i < tracedShadowRayCount; ++i)
                    {
                        RayHit shadowRayHit = rayBuffer.rayHits[secRays[i].currentShadowRayIndex];
                        RgbSpectrum attenuation;
                        if (this.ShadowRayTest(ref shadowRayHit, out attenuation))
                        {
                            //                            Radiance.MADD()
                            Radiance += attenuation * ((secRays[i].color) / secRays[i].pdf);
                            pathWeight *= secRays[i].pdf;
                        }
                    }
                    tracedShadowRayCount = 0;
                    if (PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth)
                    {
                        Splat(consumer);
                        return;
                    }
                }

                depth++;
                bool missed = rayHit.Index == 0xffffffffu;
                if (missed || PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth)
                {
                    if (specularBounce && missed)
                    {
                        Radiance += this.SampleEnvironment(-PathRay.Dir) * Throughput;
                    }
                    Splat(consumer);
                    return;
                }

                // Something was hit
                if (_hitInfo == null)
                    _hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit);
                else
                {
                    SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, ref _hitInfo);
                }
                var currentTriangleIndex = (int)rayHit.Index;

                //If Hit light)
                if (_hitInfo.IsLight)
                {
                    if (specularBounce)
                    {
                        var lt = scene.GetLightByIndex(currentTriangleIndex);
                        if (lt == null)
                        {
                            goto errro;
                        }
                        var le = (RgbSpectrum)(RgbSpectrumInfo)(lt.Le(ref wo));
                        Radiance += Throughput * le;
                    }
                    Splat(consumer);
                    return;
                }
            @errro:

                var hitPoint = PathRay.Point(rayHit.Distance);

                tracedShadowRayCount = 0;
                if (_hitInfo.MMaterial.IsDiffuse())
                {
                    float lightStrategyPdf = scene.ShadowRayCount / (float)scene.Lights.Length;
                    RgbSpectrum lightTroughtput = Throughput * _hitInfo.Color;
                    for (int i = 0; i < scene.ShadowRaysPerSample; ++i)
                    {
                        int currentLightIndex = scene.SampleLights(Sample.GetLazyValue());
                        var light = scene.Lights[currentLightIndex];

                        var ls = new LightSample();
                        light.EvaluateShadow(ref hitPoint, ref _hitInfo.ShadingNormal, Sample.GetLazyValue(),
                                             Sample.GetLazyValue(), Sample.GetLazyValue(), ref ls);
                        if (ls.Pdf <= 0f)
                        {
                            continue;
                        }

                        secRays[tracedShadowRayCount].color = ls.Spectrum.GetType() == typeof(RgbSpectrumInfo) ? (RgbSpectrum)(RgbSpectrumInfo)ls.Spectrum : (RgbSpectrum)ls.Spectrum;
                        secRays[tracedShadowRayCount].pdf = ls.Pdf;
                        secRays[tracedShadowRayCount].shadowRay = ls.LightRay;

                        RgbSpectrum fs;
                        _hitInfo.MMaterial.f(
                            ref secRays[tracedShadowRayCount].shadowRay.Dir,
                            ref wo, ref _hitInfo.ShadingNormal, ref Throughput, out fs);
                        Vector lwi = secRays[tracedShadowRayCount].shadowRay.Dir;
                        secRays[tracedShadowRayCount].color *= lightTroughtput *
                                                               Vector.AbsDot(ref _hitInfo.ShadingNormal, ref lwi) *
                                                               fs;
                        if (!secRays[tracedShadowRayCount].color.IsBlack())
                        {
                            secRays[tracedShadowRayCount].pdf *= lightStrategyPdf;
                            tracedShadowRayCount++;
                        }
                    }
                }

                float fPdf;
                Vector wi;

                RgbSpectrum f = _hitInfo.MMaterial.Sample_f(ref wo, out wi, ref _hitInfo.Normal, ref _hitInfo.ShadingNormal, ref Throughput,
                                                          Sample.GetLazyValue(), Sample.GetLazyValue(),
                                                          Sample.GetLazyValue(), ref _hitInfo.TextureData,
                                                          out fPdf, out specularBounce);

                if ((fPdf <= 0.0f) || f.IsBlack())
                {
                    if (tracedShadowRayCount > 0)
                        PathState = PathTracerPathState.ShadowRaysOnly;
                    else
                    {
                        Splat(consumer);
                    }
                    return;
                }
                pathWeight *= fPdf;
                Throughput *= f / fPdf;

                if (depth > scene.MaxPathDepth)
                {
                    float prob = Math.Max(Throughput.Filter(), scene.RussianRuletteImportanceCap);
                    if (prob >= Sample.GetLazyValue())
                    {
                        Throughput /= prob;
                        pathWeight *= prob;
                    }
                    else
                    {
                        if (tracedShadowRayCount > 0)
                            PathState = PathTracerPathState.ShadowRaysOnly;
                        else
                        {
                            Splat(consumer);
                        }

                        return;
                    }
                }

                PathRay.Org = hitPoint;
                PathRay.Dir = wi.Normalize();
                PathState = PathTracerPathState.NextVertex;

#if VERBOSE

            }
            catch (Exception ex)
            {
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message);
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace);
                throw;
            }
#endif
        }
Пример #11
0
        public SurfaceIntersectionData GetIntersection(ref RayData PathRay, ref RayHit hit)
        {
            var ii = new SurfaceIntersectionData(ref hit, false);

            EvalIntersection(ref PathRay, ref hit, ref ii);

            return ii;
        }
Пример #12
0
        private void EvalIntersectionAdvanced(ref RayData PathRay, ref RayHit hit, ref SurfaceIntersectionData ii, IntersectionOptions options)
        {
            ITriangleMesh mesh = null;
#if VERBOSE
            try
            {
#endif



            var currentTriangleIndex = (int)hit.Index;
            bool isLight = scene.IsLight(currentTriangleIndex);
            ii.Hit = hit;
            ii.isLight = isLight;

            mesh = scene.GetMeshByTriangleIndex(currentTriangleIndex);
            if (mesh == null)
            //|| mesh.MeshName.Equals("COL254_01", StringComparison.InvariantCultureIgnoreCase))
            {
                //ii.Color = new RgbSpectrum(1f);
                //Debugger.Break();
                throw new ApplicationException("Invalid triangle index " + currentTriangleIndex + " Mesh not found");
            }
            var meshMat = mesh.MaterialID;

            ii.isVolume = scene.IsVolumeTriangle(currentTriangleIndex);
            ii.MMaterial = scene.MatLib.GetSurfMat(meshMat);
            var matInfo = scene.MaterialProvider.Get(meshMat);

            mesh.InterpolateTriUV(currentTriangleIndex, hit.U, hit.V, out ii.TexCoords);

            if (ii.isVolume)
            {
                var volumeMaterialInfo = vm.GetMaterialInfo(mesh.MaterialID);
                vmSampler.Sample(volumeMaterialInfo, ii.Hit.Distance, ref PathRay, out ii.VolumeData);
                //texSampler.SampleTexture(hit.U, hit.V, volumeMaterialInfo.Density, out ii.VolumeData.Density);
                //this.texSampler.SampleTexture(hit.U, hit.V, new NoiseTexture() ii.VolumeData.Density);
                //return;
            }

            mesh.InterpolateTriangleNormal((int)hit.Index, hit.U, hit.V, ref ii.Normal);

            //ii.Normal = scene.Triangles[currentTriangleIndex].ComputeNormal(scene.Vertices).Normalize();

            //            ii.TexCoords = new UV(hit.U, hit.V);


            if (isLight)
            {
                if (!options.Has(IntersectionOptions.ResumeOnLight))
                    return;
                var color = scene.GetLightByIndex((int)hit.Index).Profile.Evaluate(hit.U, hit.V);
                ii.Color = options.Has(IntersectionOptions.ResolveSpectralDistributions) ? ColorFactory.ToRgb(ref color) : (RgbSpectrum)(RgbSpectrumInfo)color;
            }


            if (options.Has(IntersectionOptions.ResolvePartialDerivatives))
            {
                var p1 = scene.Vertices[scene.Triangles[currentTriangleIndex].v0.VertexIndex];
                var p2 = scene.Vertices[scene.Triangles[currentTriangleIndex].v1.VertexIndex];
                var p3 = scene.Vertices[scene.Triangles[currentTriangleIndex].v2.VertexIndex];

                var mt = scene.sceneData.GeoData.TexCoords;
                var uv1 = mt[scene.sceneData.Triangles[currentTriangleIndex].v0.TexCoordIndex];
                var uv2 = mt[scene.sceneData.Triangles[currentTriangleIndex].v1.TexCoordIndex];
                var uv3 = mt[scene.sceneData.Triangles[currentTriangleIndex].v2.TexCoordIndex];

                float du1 = uv1.x - uv3.x;
                float du2 = uv2.x - uv3.x;
                float dv1 = uv1.y - uv3.y;
                float dv2 = uv2.y - uv3.y;
                Vector dp1 = Vector.Sub(ref p1, ref p3), dp2 = Vector.Sub(ref p2, ref p3);
                float determinant = du1 * dv2 - dv1 * du2;
                if (determinant.NearEqual(0f))
                {
                    // Handle zero determinant for triangle partial derivative matrix
                    Vector e1 = p2 - p1;
                    Vector e2 = p3 - p1;
                    Vector.CoordinateSystem(Vector.Normalize(Vector.Cross(ref e2, ref e1)), out ii.DpDu, out ii.DpDv);
                }
                else
                {
                    float invdet = 1f / determinant;
                    ii.DpDu = (dv2 * dp1 - dv1 * dp2) * invdet;
                    ii.DpDv = (-du2 * dp1 + du1 * dp2) * invdet;
                }

            }

            if (matInfo.Alpha is ConstTextureInfo)
            {
                ii.Alpha = (matInfo.Alpha as ConstTextureInfo).Color;
            }

            if (options.Has(IntersectionOptions.ResolveTextures))
            {

                var diffuseTex = scene.Query(meshMat, TextureType.Diffuse);
                if (diffuseTex != null)
                {

#if !TEXSAMP
                    RgbSpectrumInfo cc = diffuseTex.Sample(ii.TexCoords.U, ii.TexCoords.V);
#else

                    RgbSpectrumInfo cc;
                    texSampler.SampleTexture(ii.TexCoords.U, ii.TexCoords.V, diffuseTex, out cc);
#endif
                    ii.Color = new RgbSpectrum(cc.c1, cc.c2, cc.c3);

                    //ii.Color = diffuseTex.Sample(ii.TexCoords.U, ii.TexCoords.V);
                    //ii.Color = diffuseTex.Sample(hit.U, hit.V);
                }
                else
                {
                    ii.Color = RgbSpectrum.Max(ref matInfo.Ks, ref matInfo.Kd);
                }



                var bump = new Vector(0f);
                Vector v1, v2;
                Normal geoNormal = ii.Normal;
                Vector.CoordinateSystem(ref geoNormal, out v1, out v2);

                var bumpTex = scene.Query(meshMat, TextureType.Bump);
                if (bumpTex != null)
                {
                    var map = bumpTex;
                    var dudv = map.DUDV;
                    RgbSpectrumInfo bs;

#if TEXSAMP

                    texSampler.SampleTexture(ii.TexCoords.U, ii.TexCoords.V, bumpTex, out bs);
#else

                    bs = bumpTex.Sample(ii.TexCoords.U, ii.TexCoords.V);
                    
#endif

                    float b0 = bs.Filter();

                    UV uvdu = new UV(ii.TexCoords.U + dudv.U, ii.TexCoords.V);
#if TEXSAMP
                    texSampler.SampleTexture(uvdu.U, uvdu.V, bumpTex, out bs);
#else
                    bs = bumpTex.Sample(uvdu.U, uvdu.V);
                    
#endif

                    float bu = bs.Filter();

                    UV uvdv = new UV(ii.TexCoords.U, ii.TexCoords.V + dudv.V);
#if TEXSAMP
                    texSampler.SampleTexture(uvdv.U, uvdv.V, bumpTex, out bs);

#else

                    bs = bumpTex.Sample(uvdv.U, uvdv.V);

#endif

                    float bv = bs.Filter();

                    float scale = 1.0f; //bm->GetScale();
                    bump = new Vector(scale * (bu - b0), scale * (bv - b0), 1f);

                    ii.Normal = new Normal(
                        v1.x * bump.x + v2.x * bump.y + geoNormal.x * bump.z,
                        v1.y * bump.x + v2.y * bump.y + geoNormal.y * bump.z,
                        v1.z * bump.x + v2.z * bump.y + geoNormal.z * bump.z).Normalize();
                }

                var nfScale = 2.0f;
                var nfIscale = 0.5f;
                var normTex = scene.Query(meshMat, TextureType.Normal);
                if (normTex != null)
                {
                    RgbSpectrumInfo color;
                    texSampler.SampleTexture(ii.TexCoords.U, ii.TexCoords.V, normTex, out color);
                    float x = nfScale * (color.c1 - nfIscale);
                    float y = nfScale * (color.c2 - nfIscale);
                    float z = nfScale * (color.c3 - nfIscale);

                    ii.Normal = new Normal(
                        v1.x * x + v2.x * y + geoNormal.x * z,
                        v1.y * x + v2.y * y + geoNormal.y * z,
                        v1.z * x + v2.z * y + geoNormal.z * z).Normalize();
                }

                RgbSpectrumInfo reflectance = matInfo.Coefficients[3];
                //(RgbSpectrumInfo) matInfo.SpecularReflectance;
                var reflTex = scene.Query(meshMat, TextureType.Reflection);
                if (reflTex != null)
                {
                    texSampler.SampleTexture(ii.TexCoords.U, ii.TexCoords.V, reflTex, out reflectance);
                }

                RgbSpectrumInfo alpha = null;
                var alphaTex = scene.Query(meshMat, TextureType.Alpha);
                if (alphaTex != null)
                {
                    texSampler.SampleTexture(ii.TexCoords.U, ii.TexCoords.V, alphaTex, out alpha);
                }
                var zero = new RgbSpectrum(0f);

                if (ii.TextureData == null)
                {
                    ii.TextureData = new SurfaceTextureData()
                    {
                        T0 = 0.5f,
                        Transmittance = matInfo.Ks,
                        Exponent = matInfo.Exponent,
                        Alpha = alpha != null ? (RgbSpectrum) alpha : zero,
                        Diffuse = ii.Color,
                        Roughness = bump,
                        Bump = bump,
                        Medium = MediumInfo.Glass,
                        Specular = (RgbSpectrum) reflectance
                    };
                }
                else
                {
                    ii.TextureData.T0 = 0.5f;
                    ii.TextureData.Transmittance = matInfo.Ks;
                    ii.TextureData.Exponent = matInfo.Exponent;
                    ii.TextureData.Alpha = alpha != null ? (RgbSpectrum) alpha : zero;
                    ii.TextureData.Diffuse = ii.Color;
                    ii.TextureData.Roughness = bump;
                    ii.TextureData.Bump = bump;
                    ii.TextureData.Medium = MediumInfo.Glass;
                    ii.TextureData.Specular = (RgbSpectrum) reflectance;
                }
            }
            else
            {
                ii.Color =
                    //matInfo.Kd;
                       RgbSpectrum.Max(ref matInfo.Ks, ref matInfo.Kd);
                ii.TextureData = new SurfaceTextureData()
                {
                    T0 = 0.5f,
                    Transmittance = matInfo.Ks,
                    Exponent = matInfo.Exponent,
                    //Alpha = matInfo.Ka,
                    Diffuse = matInfo.Kd,
                    //Roughness = bump,
                    //Bump = bump,
                    Medium = MediumInfo.Glass,
                    Specular = matInfo.Ks
                };

            }

            /*
            if (mesh.MeshName.Equals("COL254_01", StringComparison.InvariantCultureIgnoreCase))
            {
                //ii.Color = new RgbSpectrum(1f);
                ii.Normal = -scene.Triangles[currentTriangleIndex].ComputeNormal(scene.Vertices).Normalize();
                //ii.ShadingNormal = ii.Normal;
            }
            */

            ii.ShadingNormal = (Normal.Dot(ref PathRay.Dir, ref ii.Normal) > 0f) ? -ii.Normal : ii.Normal;

            if (options.Has(IntersectionOptions.ResolveSpectralDistributions))
            {
                ii.Reflectance = ColorFactory.FromRgb(RgbSpectrum.Max(ref ii.Color, ref matInfo.Kd), SpectrumType.Reflectance);
            }

            //ii.ShadingNormal = ii.Normal;

            /*
            ii.Material = new DistributionBsdf(ii.Color.y(), ii.Color, 
                new FresnelConductor(FresnelApproxEta(ref matInfo.Kd), FresnelApproxK(ref matInfo.Ks))
                //new FresnelDielectric(1.5f, 1f)
                //new FresnelNoOP()
                    );
            new DistributionBsdf(bump.IsZero() ? ii.Color.Filter():bump.Avg(), ii.Color);
             * */
            //new DistributionBsdf(bump.IsZero() ? ii.Color.Filter() : bump.Avg(), ii.Color);


#if VERBOSE

            }
            catch (Exception ex)
            {
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Surface sampling error");
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message);
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace);

                throw;
            }
#endif
        }
Пример #13
0
 private void EvalIntersection(ref RayData PathRay, ref RayHit hit, ref SurfaceIntersectionData ii)
 {
     EvalIntersectionAdvanced(ref PathRay, ref hit, ref ii, IntersectionOptions.ResolveSurfaceComplete);
 }
Пример #14
0
 public void GetIntersection(ref RayData PathRay, ref RayHit hit, ref SurfaceIntersectionData idata, IntersectionOptions flags)
 {
     EvalIntersectionAdvanced(ref PathRay, ref hit, ref idata, flags);
 }
Пример #15
0
 public void GetIntersection(ref RayData PathRay, ref RayHit hit, ref SurfaceIntersectionData idata)
 {
     EvalIntersection(ref PathRay, ref hit, ref idata);
 }
Пример #16
0
        protected ISurfaceMaterial EvalIntersection(ref RayHit rayHit)
        {
            if (hitInfo == null)
            {
                hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit);
            }
            else
            {
                SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, ref hitInfo);
            }

            return hitInfo.MMaterial;
        }
Пример #17
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
        }
Пример #18
0
        public override void Advance(RayBuffer rayBuffer, SampleBuffer consumer)
        {
            int currentTriangleIndex = 0;
#if VERBOSE

            try
            {
#endif
                var misWeight = 1.0f;

                base.Advance(rayBuffer, consumer);

                RayHit rayHit = rayBuffer.rayHits[RayIndex];

                if (((PathState == PathTracerPathState.ShadowRaysOnly) || (PathState == PathTracerPathState.NextVertex)) &&
                    (tracedShadowRayCount > 0))
                {
                    for (int i = 0; i < tracedShadowRayCount; ++i)
                    {
                        RayHit shadowRayHit = rayBuffer.rayHits[secRays[i].currentShadowRayIndex];
                        RgbSpectrumInfo attenuation;
                        if (this.ShadowRayTest(ref shadowRayHit, out attenuation))
                        {
                            //                            Radiance.MADD()
                            Radiance += (RgbSpectrum)(attenuation * ((secRays[i].color)));
                            pathWeight *= secRays[i].pdf;
                        }
                    }
                    tracedShadowRayCount = 0;
                    if (PathState == PathTracerPathState.ShadowRaysOnly)
                    {
                        Splat(consumer);
                        return;
                    }
                }

                depth++;
                bool missed = rayHit.Index == 0xffffffffu;
                Vector wo = -PathRay.Dir;

                if (missed || PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth)
                {
                    if (depth > 0 && !specularBounce)
                    {
                        misWeight = Mis2(lastPdfW, 1f / MathLab.INVPI);
                    }

                    if (specularBounce)
                    {
                        Radiance += this.SampleEnvironment(wo) * Throughput * misWeight;
                    }

                    Splat(consumer);



                    return;
                }

                // Something was hit
                if (hitInfo == null)
                {
                    hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit);
                }
                else
                {
                    SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, ref hitInfo);
                }
                currentTriangleIndex = (int)rayHit.Index;

                if (hitInfo == null)
                {
                    Debugger.Break();
                }
                //If Hit light)
                if (hitInfo.IsLight)
                {
                    var lt = scene.GetLightByIndex(currentTriangleIndex);

                    if (lt !=null)
                   {
                        float wpdf;
                        var l =(RgbSpectrum)lt.Emittance(ref wo, out wpdf)*Throughput;
                        if (!specularBounce & depth > 0)
                        {
                            var dpdf = MathLab.PdfAtoW(wpdf, rayHit.Distance, Vector.AbsDot(ref wo, ref hitInfo.Normal));
                            var lightPickProb = 1.0f/scene.Lights.Length;
                            misWeight = Mis2(lastPdfW, dpdf*lightPickProb);
                        }

                        Radiance += Throughput*l*misWeight;
                    }
                    else
                    {
                        float pdf;
                        var le = hitInfo.Color * lt.Emittance(ref wo, out pdf);
                        //Radiance += Throughput * le;

                        Radiance.MAdd(ref Throughput, ref le);
                    }
                    Splat(consumer);

                    return;
                }

                var hitPoint = PathRay.Point(rayHit.Distance);

                tracedShadowRayCount = 0;
                var bsdf = hitInfo.MMaterial;
                float contProb = bsdf.ContinuationProbability;

                if (bsdf.IsDiffuse())
                {
                    float lightStrategyPdf = scene.ShadowRayCount / (float)scene.Lights.Length;
                    RgbSpectrum lightTroughtput = Throughput * hitInfo.Color;
                    for (int i = 0; i < scene.ShadowRayCount; ++i)
                    {
                        int currentLightIndex = scene.SampleLights(Sample.GetLazyValue());
                        var light = scene.Lights[currentLightIndex];
                        int tries = RejectionSamplingMaxLighTries;
                    light_restart:
                        light.EvaluateShadow(ref hitPoint, ref hitInfo.ShadingNormal, Sample.GetLazyValue(), Sample.GetLazyValue(), Sample.GetLazyValue(), ref ls);
                        if (ls.Pdf <= 0f)
                        {
                            tries--;
                            if (tries == 0)
                                continue;
                            goto light_restart;
                        }
                        RgbSpectrum f_s;
                        bsdf.f(ref secRays[tracedShadowRayCount].shadowRay.Dir, ref wo, ref hitInfo.ShadingNormal, ref Throughput, out f_s);

                        if (f_s.IsBlack())
                        {
                            continue;
                        }
                        var fs = (RgbSpectrumInfo) f_s;
                        var bsdfPdfW = bsdf.Pdf(ref secRays[tracedShadowRayCount].shadowRay.Dir, ref wo);

                        float weight = 1f;


                        secRays[tracedShadowRayCount].color = (RgbSpectrumInfo)(RgbSpectrum)(ls.Spectrum);
                        secRays[tracedShadowRayCount].pdf = ls.Pdf;
                        secRays[tracedShadowRayCount].shadowRay = ls.LightRay;
                        Vector lwi = -secRays[tracedShadowRayCount].shadowRay.Dir;
                        var lightPdf = ls.Pdf * lightStrategyPdf;

                        if (!light.IsDelta)
                        {
                            bsdfPdfW *= contProb;
                            weight = Mis2(lightPdf, bsdfPdfW);
                            secRays[tracedShadowRayCount].pdf = 1f;
                            secRays[tracedShadowRayCount].color = (weight * Vector.AbsDot(ref hitInfo.ShadingNormal, ref lwi) / (lightPdf)) * (lightTroughtput * fs);
                        }
                        else
                        {
                            secRays[tracedShadowRayCount].color *= (lightTroughtput *
                                                                   Vector.AbsDot(ref hitInfo.ShadingNormal, ref lwi) *
                                                                   fs);
                            secRays[tracedShadowRayCount].color /= lightPdf;
                        }
                        if (!secRays[tracedShadowRayCount].color.IsBlack())
                        {
                            tracedShadowRayCount++;
                        }
                    }
                }

                float fPdf;
                Vector wi;
                int btries = RejectionSamplingMaxBsdfTries;

            bsdf_restart:
                RgbSpectrum f = bsdf.Sample_f(ref wo, out wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref Throughput,
                                                          Sample.GetLazyValue(), Sample.GetLazyValue(),
                                                          Sample.GetLazyValue(), ref hitInfo.TextureData,
                                                          out fPdf, out specularBounce)*hitInfo.Color;

                if ((fPdf <= 0.0f) || f.IsBlack())
                {
                    if (tracedShadowRayCount > 0)
                        PathState = PathTracerPathState.ShadowRaysOnly;
                    else
                    {
                        btries--;
                        if (btries == 0)
                        {
                            Splat(consumer);

                        }
                        else
                        {
                            goto bsdf_restart;
                        }
                    }
                    return;
                }
                pathWeight *= fPdf;
                Throughput *= (f*hitInfo.Color) / fPdf;
                lastPdfW = fPdf * contProb;
                if (depth > scene.MaxPathDepth)
                {
                    float prob = Math.Max(contProb, scene.RussianRuletteImportanceCap);
                    if (prob >= Sample.GetLazyValue())
                    {
                        Throughput /= prob;
                        pathWeight *= prob;
                    }
                    else
                    {
                        if (tracedShadowRayCount > 0)
                            PathState = PathTracerPathState.ShadowRaysOnly;
                        else
                        {
                            Splat(consumer);

                        }

                        return;
                    }
                }

                PathRay.Org = hitPoint;
                PathRay.Dir = wi.Normalize();
                PathState = PathTracerPathState.NextVertex;

#if VERBOSE
            }
            catch (Exception ex)
            {
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Advance path exception");
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Error triangle {0}", currentTriangleIndex);
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message);
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace);

            }
#endif
        }
Пример #19
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
        }
Пример #20
0
        public override void Advance(RayBuffer rayBuffer, SampleBuffer consumer)
        {
            base.Advance(rayBuffer, consumer);

            if ((PathState == BDPTSamplerState.ConnectOnly || PathState == BDPTSamplerState.PropagatePath) &&
                tracedConnectRayCount > 0)
            {
                for (int i = 0; i < tracedConnectRayCount; ++i)
                {
                    RayHit shadowRayHit = rayBuffer.rayHits[connectRays[i].ConnectRayIndex];
                    RgbSpectrum attenuation;
                    if (this.ShadowRayTest(ref shadowRayHit, out attenuation))
                    {
                        //                            Radiance.MADD()
                        Radiance += attenuation * ((connectRays[i].Radiance) / connectRays[i].Pdf);
                        //pathWeight *= connectRays[i].pdf;
                    }
                }
                Splat(consumer);
                return;
            }

            if (!lightStop)
            {
                RayHit rayHit = rayBuffer.rayHits[LightRayIndex];
                lightDepth++;
                bool missed = rayHit.Index == 0xffffffffu;
                if (missed || lightDepth > MaxLightDepth)
                {
                    lightStop = true;
                    goto Eye;
                }
                // Something was hit
                if (hitInfo == null)
                {
                    hitInfo = SurfaceSampler.GetIntersection(ref LightRay, ref rayHit);
                }
                else
                {
                    SurfaceSampler.GetIntersection(ref LightRay, ref rayHit, ref hitInfo);
                }
                var hitPoint = LightRay.Point(rayHit.Distance);

                if (scene.IsLight((int)rayHit.Index))
                {
                    lightStop = true;
                    goto Eye;
                }

                Vector wo = -LightRay.Dir;
                var bsdf = hitInfo.MMaterial;
                float fPdf;
                Vector wi;
                bool specularBounce;
                hitInfo.Color = RgbSpectrum.UnitSpectrum();

                RgbSpectrum f = bsdf.Sample_f(ref wo,
                                                out wi,
                                                ref hitInfo.Normal,
                                                ref hitInfo.ShadingNormal, ref LightThroughput,
                                                Sample.GetLazyValue(),
                                                Sample.GetLazyValue(),
                                                Sample.GetLazyValue(),
                                                ref hitInfo.TextureData,
                                                out fPdf,
                                                out specularBounce);

                if (f.IsBlack() && fPdf <= 0f)
                {
                    this.lightStop = true;
                    goto Eye;
                }

                if (bsdf.IsDiffuse() && !f.IsBlack() && lightVertices < MaxLightDepth)
                {
                    this.lightPath[lightVertices].HitPoint = hitPoint;
                    this.lightPath[lightVertices].Wi = wo;
                    this.lightPath[lightVertices].GeoNormal = hitInfo.Normal;
                    this.lightPath[lightVertices].Throughput = LightThroughput;
                    this.lightPath[lightVertices].Pdf = this.lightPdf;
                    lightVertices++;
                }

                //this.lightPdf /= fPdf;
                this.LightThroughput *= f / fPdf;

                if (lightDepth > MaxLightDepth)
                {
                    this.lightStop = true;
                    goto Eye;
                }

                LightRay.Org = hitPoint;
                LightRay.Dir = wi.Normalize();
                PathState = BDPTSamplerState.PropagatePath;
            }

            // Eye path sampling
        Eye:
            if (!eyeStop)
            {
                RayHit rayHit = rayBuffer.rayHits[RayIndex];
                eyeDepth++;
                bool missed = rayHit.Index == 0xffffffffu;
                if (missed || eyeDepth > scene.MaxPathDepth)
                {
                    Radiance += this.SampleEnvironment(PathRay.Dir) * EyeThroughput;
                    Splat(consumer);
                    return;
                }

                // Something was hit
                if (hitInfo == null)
                {
                    hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit);
                }
                else
                {
                    SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, ref hitInfo);
                }
                var currentTriangleIndex = (int)rayHit.Index;
                if (hitInfo.IsLight)
                {
                    //if (specularBounce) 
                    {
                        var lt = scene.GetLightByIndex(currentTriangleIndex);
                        if (lt != null)
                        {
                            var le = (RgbSpectrum)(lt.Le(ref PathRay.Dir));
                            Radiance += EyeThroughput * le;
                        }
                    }
                    Splat(consumer);

                    return;
                }
                var hitPoint = PathRay.Point(rayHit.Distance);

                Vector wo = -PathRay.Dir;
                var bsdf = hitInfo.MMaterial;
                float fPdf;
                Vector wi;
                bool specularBounce;
                if (bsdf.IsDiffuse())
                {
                    float lightStrategyPdf = scene.ShadowRayCount / (float)scene.Lights.Length;
                    RgbSpectrum lightTroughtput = EyeThroughput * hitInfo.Color;
                    for (int i = 0; i < scene.ShadowRayCount; ++i)
                    {
                        int currentLightIndex = scene.SampleLights(Sample.GetLazyValue());
                        var light = scene.Lights[currentLightIndex];

                        var ls = new LightSample();
                        light.EvaluateShadow(ref hitPoint,
                                             ref hitInfo.ShadingNormal,
                                             Sample.GetLazyValue(),
                                             Sample.GetLazyValue(),
                                             Sample.GetLazyValue(),
                                             ref ls);
                        if (ls.Pdf <= 0f)
                        {
                            continue;
                        }

                        connectRays[tracedConnectRayCount].Radiance = (RgbSpectrum)(ls.Spectrum);
                        connectRays[tracedConnectRayCount].Pdf = ls.Pdf;
                        connectRays[tracedConnectRayCount].ConnectRay = ls.LightRay;
                        connectRays[tracedConnectRayCount].Direct = true;

                        Vector mwi = connectRays[tracedConnectRayCount].ConnectRay.Dir;
                        Vector lwi = connectRays[tracedConnectRayCount].ConnectRay.Dir;
                        RgbSpectrum fs;

                        hitInfo.MMaterial.f(
                            ref mwi,
                            ref wo,
                            ref hitInfo.ShadingNormal, ref lightTroughtput, 
                            out fs,
                            types: BrdfType.Diffuse);
                        connectRays[tracedConnectRayCount].Radiance *= lightTroughtput *
                                                                       Vector.AbsDot(ref hitInfo.ShadingNormal, ref lwi) *
                                                                       fs;
                        if (!connectRays[tracedConnectRayCount].Radiance.IsBlack())
                        {
                            connectRays[tracedConnectRayCount].Pdf *= lightStrategyPdf;
                            tracedConnectRayCount++;
                        }
                    }

                    for (int i = 0; i < lightVertices; i++)
                    {

                        var lightThroughtput = lightPath[i].Throughput;

                        connectRays[tracedConnectRayCount].Radiance = EyeThroughput * hitInfo.Color;
                        connectRays[tracedConnectRayCount].Pdf = 1f;
                        connectRays[tracedConnectRayCount].ConnectRay = new RayData(hitPoint, (hitPoint - lightPath[i].HitPoint).Normalize());
                        var lwi = -connectRays[tracedConnectRayCount].ConnectRay.Dir;


                        connectRays[tracedConnectRayCount].Radiance *= lightThroughtput *
                                                                       Geometry.G(ref hitPoint, ref lightPath[i].HitPoint, ref hitInfo.Normal, ref lightPath[i].GeoNormal);
                        //     Vector.AbsDot(ref hitInfo.ShadingNormal, ref lwi);
                        if (!connectRays[tracedConnectRayCount].Radiance.IsBlack())
                        {
                            connectRays[tracedConnectRayCount].Pdf *= lightPath[i].Pdf*eyePdf;
                            tracedConnectRayCount++;
                        }
                    }

                }

                RgbSpectrum f = bsdf.Sample_f(ref wo,
                                                  out wi,
                                                  ref hitInfo.Normal,
                                                  ref hitInfo.ShadingNormal, ref EyeThroughput,
                                                  Sample.GetLazyValue(),
                                                  Sample.GetLazyValue(),
                                                  Sample.GetLazyValue(),
                                                  ref hitInfo.TextureData,
                                                  out fPdf,
                                                  out specularBounce);
                if ((fPdf <= 0.0f) || f.IsBlack())
                {
                    if (tracedConnectRayCount > 0)
                        PathState = BDPTSamplerState.ConnectOnly;
                    else
                    {
                        //Splat(consumer);
                        eyeStop = true;
                    }
                    eyeStop = true;
                    goto Connect;
                }

                eyePdf *= fPdf;
                EyeThroughput *= (f) / fPdf;
                if (eyeDepth > scene.MaxPathDepth)
                {
                    float prob = Math.Max(EyeThroughput.Filter(), scene.RussianRuletteImportanceCap);
                    if (prob >= Sample.GetLazyValue())
                    {
                        EyeThroughput /= prob;
                        eyePdf *= prob;
                    }
                    else
                    {
                        if (tracedConnectRayCount > 0)
                            PathState = BDPTSamplerState.ConnectOnly;
                        else
                        {
                            eyeStop = true;
                            goto Connect;
                        }

                        eyeStop = true;
                        goto Connect;
                    }
                }

                PathRay.Org = hitPoint;
                PathRay.Dir = wi.Normalize();
                PathState = BDPTSamplerState.PropagatePath;
            }

        @Connect:
            if (eyeStop && lightStop)
            {
                this.Splat(consumer);
                return;
            }
        }
Пример #21
0
 public bool Match(ref SurfaceIntersectionData hit)
 {
     return hit.IsLight;
 }
Пример #22
0
        public override void Advance(RayBuffer rayBuffer, SampleBuffer consumer)
        {
            int currentTriangleIndex = 0;
            SurfaceIntersectionData hitInfo = null;
#if VERBOSE

            try
            {
#endif

                base.Advance(rayBuffer, consumer);


                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()
                            mutate = true;
                            Radiance += attenuation * ((secRays[i].color));
                            pathWeight *= secRays[i].pdf;
                        }
                    }
                    if (PathState == PathTracerPathState.ShadowRaysOnly)
                    {
                        Splat(consumer);
                        return;
                    }
                    tracedShadowRayCount = 0;
                }


                RayHit rayHit = rayBuffer.rayHits[RayIndex];

                depth++;
                bool missed = rayHit.Index == 0xffffffffu;
                if (missed || PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth)
                {
                    if (specularBounce && missed)
                    {
                        Radiance += this.SampleEnvironment(PathRay.Dir) * Throughput;
                    }
                    Splat(consumer);

                    return;
                }

                // Something was hit
                hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit);
                currentTriangleIndex = (int)rayHit.Index;

                if (hitInfo == null)
                {
                    Debugger.Break();
                }
                var wo = -PathRay.Dir;
                //If Hit light)
                if (hitInfo.IsLight)
                {
                    if (specularBounce)
                    {
                        var lt = scene.GetLightByIndex(currentTriangleIndex);
                        if (lt != null)
                        {
                            var le = (RgbSpectrum)(lt.Le(ref wo));
                            Radiance += Throughput * le;
                            mutate = true;
                        }
                    }
                    Splat(consumer);

                    return;
                }

                var hitPoint = PathRay.Point(rayHit.Distance);
                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(depth*2),
                                                Sample.GetLazyValue(depth * 3), Sample.GetLazyValue(depth * 4), ref ls, ltProb: Sample.GetLazyValue(depth));
                    for (int index = 0; index < ls.Length; index++)
                    {

                        if (ls[index].Pdf <= 0f)
                            continue;
                        secRays[tracedShadowRayCount].color = (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].color *= lightTroughtput *
                                                                    Vector.AbsDot(ref hitInfo.Normal, ref lwi) *
                                                                    fs;
                        if (!secRays[tracedShadowRayCount].color.IsBlack())
                        {
#if DEBUG
                            RayDen.Library.Core.Components.Assert.IsNotNaN(secRays[tracedShadowRayCount].pdf);
#endif
                            secRays[tracedShadowRayCount].pdf /= lightStrategyPdf;
                            tracedShadowRayCount++;
                        }
                    }
                }


                float fPdf;
                Vector wi;

                RgbSpectrum f = hitInfo.MMaterial.Sample_f(ref wo, out wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref Throughput,
                                                          Sample.GetLazyValue(depth * 5), Sample.GetLazyValue(depth * 6),
                                                          Sample.GetLazyValue(depth * 7), ref hitInfo.TextureData,
                                                          out fPdf, out specularBounce);

                if ((fPdf <= 0.0f) || f.IsBlack())
                {
                    Splat(consumer);
                    return;
                }
                pathWeight *= fPdf;
                Throughput *= f / fPdf;
                if (!mutate)
                    mutate = Throughput.Filter() > Sample.GetLazyValue(depth * 8);

                if (depth > scene.MaxPathDepth)
                {
                    float prob = Math.Max(Throughput.Filter(), scene.RussianRuletteImportanceCap);
                    if (prob >= Sample.GetLazyValue(depth * 9))
                    {
                        Throughput /= prob;
                        pathWeight *= prob;
                    }
                    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
        }
Пример #23
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.MADD()
                        Radiance += attenuation * ((secRays[i].Throughput) / secRays[i].Pdf);
                        pathWeight *= secRays[i].Pdf;
                    }
                }

                if (PathState == PathTracerPathState.ShadowRaysOnly)
                {
                    Splat(consumer);
                    return;
                }
                tracedShadowRayCount = 0;
            }
            RayHit rayHit = rayBuffer.rayHits[RayIndex];
            Vector wo = -PathRay.Dir;

            depth++;
            bool missed = rayHit.Index == 0xffffffffu;
            if (missed || PathState == PathTracerPathState.ShadowRaysOnly || depth > scene.MaxPathDepth)
            {
                if (missed)
                {
                    Radiance += this.scene.SampleEnvironment(ref wo) * Throughput;
                }
                Splat(consumer);

                return;
            }

            // Something was hit
            if (hitInfo == null)
            {
                hitInfo = SurfaceSampler.GetIntersection(ref PathRay, ref rayHit);
            }
            else
            {
                SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, ref hitInfo);
            }
            currentTriangleIndex = (int)rayHit.Index;

            if (hitInfo == null)
            {
                Debugger.Break();
            }
            //If Hit light)

            if (hitInfo.IsLight)
            {
                if (specularBounce || depth == 1)
                {
                    var lt = scene.GetLightByIndex(currentTriangleIndex);
                    if (lt != null)
                    {
                        var le = (RgbSpectrum)(lt.Le(ref wo));
                        Radiance += Throughput * le;
                    }
                }
                Splat(consumer);

                return;
            }

            var hitPoint = PathRay.Point(rayHit.Distance);

            tracedShadowRayCount = 0;
            var bsdf = hitInfo.MMaterial;

            if (!hitInfo.TextureData.Alpha.IsBlack())
            {
                Throughput *= (RgbSpectrum.UnitSpectrum() - (RgbSpectrum) hitInfo.TextureData.Alpha);
                PathRay = new RayData(hitPoint, -wo);
                return;
            }

            if (bsdf.IsDiffuse())
            {
                float lightStrategyPdf = LightSampler.StrategyPdf;
                //scene.ShadowRaysPerSample/(float)scene.Lights.Length;
                RgbSpectrum lightTroughtput = Throughput * hitInfo.Color;
                int rs = 0;
            @lstart:
                LightSampler.EvaluateShadow(ref hitPoint, ref hitInfo.Normal, Sample.GetLazyValue(),
                                            Sample.GetLazyValue(), Sample.GetLazyValue(), ref ls);
                for (int index = 0; index < ls.Length; index++)
                {

                    if (ls[index].Pdf <= 0f)
                        continue;
                    secRays[tracedShadowRayCount].Throughput = (RgbSpectrum)(ls[index].Spectrum);
                    secRays[tracedShadowRayCount].Pdf = ls[index].Pdf;
                    secRays[tracedShadowRayCount].ShadowRay = ls[index].LightRay;
                    Vector lwi = secRays[tracedShadowRayCount].ShadowRay.Dir;
                    RgbSpectrum fs;
                    hitInfo.MMaterial.f(ref secRays[tracedShadowRayCount].ShadowRay.Dir, ref wo, ref hitInfo.ShadingNormal, ref Throughput, out fs, types: BrdfType.Diffuse);
                    secRays[tracedShadowRayCount].Throughput *= lightTroughtput *
                                                                Vector.AbsDot(ref hitInfo.Normal, ref lwi) *
                                                                fs;
                    if (!secRays[tracedShadowRayCount].Throughput.IsBlack())
                    {
                        secRays[tracedShadowRayCount].Pdf /= lightStrategyPdf;
                        tracedShadowRayCount++;
                    }
                }
                if (tracedShadowRayCount == 0 && rs < lightResampling)
                {
                    rs++;
                    goto @lstart;
                }

                if (rs > 0)
                {
                    for (int index = 0; index < secRays.Length; index++)
                    {
                        secRays[index].Pdf /= (1f+rs);
                    }
                }
            }

            float fPdf = 0f;
            var wi = new Vector();
            RgbSpectrum f;

            if (depth > 1)
            {

                f = bsdf.Sample_f(ref wo, out wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref Throughput,
                                  Sample.GetLazyValue(), Sample.GetLazyValue(),
                                  Sample.GetLazyValue(), ref hitInfo.TextureData,
                                  out fPdf, out specularBounce);
            }
            else
            {
                int samplesCount = 4;
                var bsdfData = new Tuple<Vector, float, RgbSpectrum>[samplesCount];
                var totalF = new RgbSpectrum();
                float totalPdf =0;
                for (int i = 0; i < samplesCount; i++)
                {
                    Vector Wi;
                    float pdf;
                    var Fr = bsdf.Sample_f(ref wo, out Wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref Throughput,
                           Sample.GetLazyValue(), Sample.GetLazyValue(),
                           Sample.GetLazyValue(), ref hitInfo.TextureData,
                           out pdf, out specularBounce);
                    totalF += Fr;
                    totalPdf += pdf;

                    bsdfData[i] = new Tuple<Vector, float, RgbSpectrum>(Wi, pdf, Fr);
                }

                var bsdfSamples = bsdfData.OrderBy(i => i.Item2).ToArray();
                fPdf = bsdfSamples[0].Item2;
                wi = bsdfSamples[0].Item1;
                f = totalF/4f;
            }

            if ((fPdf <= 0.0f) || f.IsBlack())
            {
                if (tracedShadowRayCount > 0)
                    PathState = PathTracerPathState.ShadowRaysOnly;
                else
                {
                    Splat(consumer);

                }
                return;
            }
            pathWeight *= fPdf;
            Throughput *= (f * hitInfo.Color) / fPdf;

            if (depth > scene.MaxPathDepth)
            {
                float prob = Math.Max(Throughput.Filter(), scene.RussianRuletteImportanceCap);
                if (prob >= Sample.GetLazyValue())
                {
                    Throughput /= prob;
                    pathWeight *= prob;
                }
                else
                {
                    if (tracedShadowRayCount > 0)
                        PathState = PathTracerPathState.ShadowRaysOnly;
                    else
                    {
                        Splat(consumer);

                    }

                    return;
                }
            }

            PathRay.Org = hitPoint;
            PathRay.Dir = wi.Normalize();
            PathState = PathTracerPathState.NextVertex;

#if VERBOSE
            }
            catch (Exception ex) {
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Advance path exception");
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine("Error triangle {0}", currentTriangleIndex);
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.Message);
                RayDen.Library.Components.SystemComponents.Tracer.TraceLine(ex.StackTrace);

            }
#endif
        }
Пример #24
0
        public override void Advance(RayBuffer rayBuffer, SampleBuffer consumer)
        {
            base.Advance(rayBuffer, consumer);
            var rayHit = rayBuffer.rayHits[RayIndex];
            depth++;
            bool missed = rayHit.Miss();
            if (missed)
            {
                this.InitPath(pathIntegrator);
                return;
            }

            var hitPoint = PathRay.Point(rayHit.Distance);
            if (hitInfo == null)
            {
                hitInfo = new SurfaceIntersectionData(ref rayHit, true);
            }
            SurfaceSampler.GetIntersection(ref PathRay, ref rayHit, ref hitInfo);
            if (hitInfo.IsLight)
            {
                this.InitPath(pathIntegrator);
                engine.IncreasePhoton();
                return;
            }

            float fPdf;
            Vector wi, wo = -PathRay.Dir;
            var bsdf = hitInfo.MMaterial;
            RgbSpectrum f = bsdf.Sample_f(ref wo, out wi, ref hitInfo.Normal, ref hitInfo.ShadingNormal, ref ThroughtPut,
                                                    Sample.GetLazyValue(), Sample.GetLazyValue(),
                                                    Sample.GetLazyValue(), ref hitInfo.TextureData,
                                                    out fPdf, out specularBounce);
            if (fPdf <= 0f || f.IsBlack())
            {
                this.InitPath(pathIntegrator);
                engine.IncreasePhoton();
                return;
            }


            if (!specularBounce)
            {
                engine.StoreFlux(Alpha, ref hitPoint, ref hitInfo.ShadingNormal, wi, ref ThroughtPut);
                //InitPath(pathIntegrator);
                //return;
            }

            ThroughtPut *= f / fPdf;

            var p = scene.RussianRuletteImportanceCap;

            if (depth < scene.MaxPathDepth)
            {
                PathRay = new RayData(hitPoint, wi);
            }
            else if (Sample.GetLazyValue() < p)
            {
                ThroughtPut /= p;
                PathRay = new RayData(hitPoint, wi);
            }
            else
            {
                // Re-initialize the photon path
                engine.IncreasePhoton();
                InitPath(pathIntegrator);
            }
        }