예제 #1
0
        public static Color32 GetColor(Ray r, HitableList hitableList, Hitable importance, int depth)
        {
            var hrec = new HitRecord();

            if (hitableList.Hit(r, 0.00001f, float.MaxValue, ref hrec))
            {
                var srec    = new ScatterRecord();
                var emitted = hrec.shader.emitted(r, hrec, hrec.u, hrec.v, hrec.p);
                if (depth < Configuration.MAX_SCATTER_TIME)
                {
                    if (hrec.shader.scatter(r, ref hrec, ref srec))
                    {
                        if (srec.is_specular)
                        {
                            return(srec.attenuation *
                                   GetColor(srec.specular_ray, Scene.main.world, importance, depth + 1));
                        }
                        var p         = new MixturePdf(new HitablePdf(importance, hrec.p), srec.pdf);
                        var scattered = new Ray(hrec.p, p.Generate(), r.time);
                        var pdf       = p.Value(scattered.direction);
                        return(emitted + srec.attenuation * hrec.shader.scattering_pdf(r, hrec, scattered) *
                               GetColor(scattered, Scene.main.world, importance, depth + 1) / pdf);
                    }
                    else
                    {
                        return(depth == 0 ? emitted.Aravge() : emitted);
                    }
                }
                else
                {
                    return(depth == 0?emitted.Aravge():emitted);
                }
            }
            return(Scene.main.Skybox ? Scene.main.sky.Value(r.direction.Normalized()) : Color32.Black);

#pragma warning disable CS0162 // 检测到无法访问的代码
            var t = 0.5f * r.normal_direction.y + 1f;
#pragma warning restore CS0162 // 检测到无法访问的代码
            return(Scene.main.Skybox ? (1 - t) * new Color32(2, 2, 2) + t * new Color32(0.5f, 0.7f, 1) : Color32.Black);
        }
예제 #2
0
        private ColorVector GetRayColor(Ray ray, IHitable world, PixelData pixelData, int depth)
        {
            Debug.WriteLine($"Depth: {depth}");
            pixelData.SetDepth(depth);
            try
            {
                // the 0.001 corrects for the "shadow acne"
                HitRecord hr = world.Hit(ray, 0.001f, float.MaxValue);
                if (hr != null)
                {
                    var emitted = hr.Material.Emitted(ray, hr, hr.UvCoords, hr.P);

                    if (hr.Material is DiffuseLight)
                    {
                        Debug.WriteLine($"HIT A LIGHT. Emitted: {emitted}");
                    }

                    if (depth < _renderConfig.RayTraceDepth)
                    {
                        var scatterResult = hr.Material.Scatter(ray, hr);
                        if (scatterResult.IsScattered)
                        {
                            if (scatterResult.IsSpecular)
                            {
                                return(scatterResult.Attenuation * GetRayColor(scatterResult.SpecularRay, world, pixelData, depth + 1));
                            }
                            else
                            {
                                var   p0        = new HitablePdf(_lightHitable, hr.P);
                                var   p         = new MixturePdf(p0, scatterResult.Pdf);
                                var   scattered = new Ray(hr.P, p.Generate());
                                float pdfValue  = p.GetValue(scattered.Direction);

                                var scatteringPdf = hr.Material.ScatteringPdf(ray, hr, scattered);
                                if (scatteringPdf < 0.01f)
                                {
                                    scatteringPdf = 0.01f;
                                    //    //pdfValue = 1.0f;
                                }

                                {
                                    //pdfValue = 1.0f;
                                }

                                var         depthRayColor = GetRayColor(scattered, world, pixelData, depth + 1);
                                ColorVector recurseColor  = ((scatterResult.Attenuation * scatteringPdf * depthRayColor) / pdfValue);
                                Debug.WriteLine($"Attenuation ({scatterResult.Attenuation}) ScatteringPdf ({scatteringPdf}) DepthRayColor({depthRayColor}) PdfValue({pdfValue})");
                                Debug.WriteLine($"emitted: {emitted}");
                                Debug.WriteLine($"RecurseColor: {recurseColor}");
                                return(emitted + recurseColor);
                            }
                        }
                        else
                        {
                            Debug.WriteLine("NOT SCATTERED");
                        }
                    }

                    return(emitted);
                }

                if (depth == 0)
                {
                    Debug.WriteLine("depth at 0...");
                }

                Debug.WriteLine("returning backgroundfunc");
                return(_backgroundFunc(ray));
            }
            finally
            {
                Debug.WriteLine($"Exiting Depth: {depth}");
            }
        }