Example #1
0
        public override Color Tracing(Ray ray, Sky sky, SamplerBase sampler, int depth = 0)
        {
            if (depth > tracingTimes)
            {
                return(Color.black);
            }

            RayCastHit hit;

            hit.distance = double.MaxValue;

            if (sceneData.Raycast(ray, m_Epsilon, out hit))
            {
                hit.depth = depth;
                if (hit.shader == null)
                {
                    return(new Color(1, 0, 1));
                }
                return(hit.shader.Render(this, sky, sampler, ray, hit, m_Epsilon));
            }
            else
            {
                if (sky != null)
                {
                    return(sky.RenderColor(ray.direction));
                }
                return(Color.black);
            }
        }
Example #2
0
        /// <summary>
        /// 根据焦距和透镜半径计算光线
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="sampler"></param>
        /// <returns></returns>
        private Ray GetThinLensRayFromPixel(int x, int y, SamplerBase sampler)
        {
            if (renderTarget == null)
            {
                throw new System.NullReferenceException();
            }
            var    sample = sampler.SampleUnitSquare();
            double px     = (renderTarget.width - 1 - (sample.x + x)) / renderTarget.width * 2 - 1;
            double py     = (sample.y + y) / renderTarget.height * 2 - 1;

            px *= m_Width;
            py *= m_Height;
            double per = focal / near;

            px = px * per;
            py = py * per;
            Vector3 p = position + right * px + up * py + forward * focal;

            Vector2 disk = sampler.SampleUnitDisk();

            Vector3 ori = position + right * disk.x * radius + up * disk.y * radius;

            Vector3 dir = (p - ori).normalized;

            return(new Ray(ori, dir));
        }
Example #3
0
        private Vector3 SampleLocalPosition(SamplerBase sampler)
        {
            double rand = sampler.GetRandom();

            double areaRand = rand * (m_Area0 * 2.0 + m_Area1 * 2.0 + m_Area2 * 2.0);

            Vector2 sample = sampler.SampleUnitSquare();

            if (areaRand < m_Area0)
            {
                return(new Vector3(-scale.x * 0.5 + scale.x * sample.x, -scale.y * 0.5 + scale.y * sample.y, -scale.z * 0.5));
            }
            else if (areaRand >= m_Area0 && areaRand < m_Area0 * 2.0)
            {
                return(new Vector3(-scale.x * 0.5 + scale.x * sample.x, -scale.y * 0.5 + scale.y * sample.y, scale.z * 0.5));
            }
            else if (areaRand >= m_Area0 * 2.0 && areaRand < m_Area0 * 2.0 + m_Area1)
            {
                return(new Vector3(-scale.x * 0.5, -scale.y * 0.5 + scale.y * sample.x, -scale.z * 0.5 + scale.z * sample.y));
            }
            else if (areaRand >= m_Area0 * 2.0 + m_Area1 && areaRand < m_Area0 * 2.0 + m_Area1 * 2.0)
            {
                return(new Vector3(scale.x * 0.5, -scale.y * 0.5 + scale.y * sample.x, -scale.z * 0.5 + scale.z * sample.y));
            }
            else if (areaRand >= m_Area0 * 2.0 + m_Area1 * 2.0 && areaRand < m_Area0 * 2.0 + m_Area1 * 2.0 + m_Area2)
            {
                return(new Vector3(-scale.x * 0.5 + scale.x * sample.x, -scale.y * 0.5, -scale.z * 0.5 + scale.z * sample.y));
            }
            else
            {
                return(new Vector3(-scale.x * 0.5 + scale.x * sample.x, scale.y * 0.5, -scale.z * 0.5 + scale.z * sample.y));
            }
        }
Example #4
0
        public override float SampleBRDF(SamplerBase sampler, Vector3 wo, Vector3 wi, Vector3 position, Vector3 normal, float roughness)
        {
            double denominator = 4.0 * Math.Max(Vector3.Dot(normal, wi), 0.0) * Math.Max(Vector3.Dot(normal, wo), 0.0) + 0.001;
            //float nominator = D_GGX((wi + wo).normalized, normal, roughness) * G_SmithGGX(wi, wo, normal, roughness);
            float nominator = G_SmithGGX(wi, wo, normal, roughness);

            return(nominator / (float)denominator);
        }
Example #5
0
 internal void RenderPixel(int x, int y, SamplerBase sampler, Scene scene)
 {
     for (int k = 0; k < sampler.numSamples; k++)
     {
         var sample = sampler.Sample();
         Ray ray    = GetRayFromPixel(x + sample.x, y + sample.y);
         m_RenderTarget.SetPixel(x, y, scene.tracer.Tracing(ray, scene.sky, sampler));
     }
 }
Example #6
0
 public RenderJob(int x, int y, SamplerBase sampler, Scene scene, Camera camera)
 {
     this.x          = x;
     this.y          = y;
     this.sampler    = sampler;
     this.scene      = scene;
     this.camera     = camera;
     this.resetEvent = new ManualResetEvent(false);
 }
Example #7
0
        public override Color Render(Tracer tracer, Sky sky, SamplerBase sampler, Ray ray, RayCastHit hit, double epsilon)
        {
            Vector3 refl = Vector3.Reflect(ray.direction, hit.normal);

            if (sky != null)
            {
                return(sky.RenderColor(refl));
            }
            return(Color.white);
        }
Example #8
0
        public override Ray GetRay(int x, int y, SamplerBase sampler)
        {
            if (useThinLens)
            {
                return(GetThinLensRayFromPixel(x, y, sampler));
            }
            var sample = sampler.SampleUnitSquare();

            return(GetRayFromPixel(sample.x + x, sample.y + y));
        }
Example #9
0
        public PathTracerRenderJobResult Render(Scene scene, PathTracer renderer, SamplerBase sampler)
        {
            //int tileWidth = m_Width - m_TileX;
            //if (tileWidth > 32)
            //    tileWidth = 32;
            //int tileHeight = m_Height - m_TileY;
            //if (tileHeight > 32)
            //    tileHeight = 32;
            //PathTracerRenderJobResult result = new PathTracerRenderJobResult(m_I, m_J, tileWidth, tileHeight);

            //for (; m_J < m_Height && m_J - m_TileY < 32;m_J++)
            //{
            //    for(; m_I < m_Width && m_I - m_TileX < 32;m_I++)
            //    {
            //        Color col = Color.black;
            //        sampler.ResetSampler(); //重置采样器状态
            //        while (sampler.NextSample())
            //        {
            //            Ray ray = scene.camera.GetRay(m_I, m_J, sampler);
            //            col += renderer.PathTracing(ray, sampler);
            //        }
            //        col /= sampler.numSamples;

            //        col.a = 1.0f;

            //        result.SetPixel(m_I, m_J, col);
            //    }
            //    if (m_I >= m_Width || m_I - m_TileX >= 32)
            //    {
            //        m_I = m_TileX;
            //    }
            //}
            Color col = Color.black;

            sampler.ResetSampler(); //重置采样器状态
            while (sampler.NextSample())
            {
                Ray ray = scene.camera.GetRay(m_I, m_J, sampler);
                col += renderer.PathTracing(ray, sampler);
            }
            col  /= sampler.numSamples;
            col.a = 1.0f;

            PathTracerRenderJobResult result = new PathTracerRenderJobResult(m_I, m_J, col);

            m_I++;
            if (m_I >= m_Width || m_I - m_TileX >= 32)
            {
                m_I = m_TileX;
                m_J++;
            }

            return(result);
        }
Example #10
0
            public Job(RenderConfig config, Scene scene, W renderer, ConcurrentQueue <IRenderWork <T, W> > works, ConcurrentQueue <T> results, ManualResetEvent resetEvent)
            {
                m_Works      = works;
                m_Results    = results;
                m_ResetEvent = resetEvent;

                m_Scene    = scene;
                m_Renderer = renderer;

                m_Sampler = SamplerFactory.Create(config.samplerType, config.numSamples, config.numSets);
            }
Example #11
0
        public override Vector3 Sample(SamplerBase sampler)
        {
            Vector3 localPoint = SampleLocalPosition(sampler);

            if (m_IsRotated)
            {
                return(m_LocalToWorld.TransformPoint(localPoint));
            }
            else
            {
                return(position + localPoint);
            }
        }
Example #12
0
        public Color Shade(Material skyMaterial, SamplerBase sampler, Ray ray)
        {
            if (skyMaterial == null)
            {
                return(Color.black);
            }

            RayCastHit hit = default(RayCastHit);

            hit.normal = ray.direction;

            return(skyMaterial.GetEmissive(hit));
        }
Example #13
0
        public override float SampleBRDF(SamplerBase sampler, Vector3 wo, Vector3 wi, Vector3 position, Vector3 normal, float roughness)
        {
            double oneMinusCosL    = 1.0 - Vector3.Dot(wi, normal);
            double oneMinusCosLSqr = oneMinusCosL * oneMinusCosL;
            double oneMinusCosV    = 1.0 - Vector3.Dot(wo, normal);
            double oneMinusCosVSqr = oneMinusCosV * oneMinusCosV;

            // Roughness是粗糙度,IDotH的意思会在下一篇讲Microfacet模型时提到
            double IDotH = Vector3.Dot(wi, (wi + wo).normalized);
            double F_D90 = 0.5 + 2.0 * IDotH * IDotH * roughness;

            return((float)((1.0 / Math.PI) * (1.0 + (F_D90 - 1.0) * oneMinusCosLSqr * oneMinusCosLSqr * oneMinusCosL) *
                           (1.0 + (F_D90 - 1.0) * oneMinusCosVSqr * oneMinusCosVSqr * oneMinusCosV)));
        }
Example #14
0
        public Color PathTracing(Ray ray, SamplerBase sampler, int depth = 0)
        {
            if (scene == null)
            {
                return(Color.black);
            }

            RayCastHit hit;

            hit.distance = double.MaxValue;

            Color color = Color.black;

            if (scene.sceneData.Raycast(ray, out hit))
            {
                hit.depth = depth;
                if (hit.material == null)
                {
                    color = new Color(1, 0, 1);
                }
                else
                {
                    color = m_Shader.Shade(hit.material, sampler, ray, hit);
                }
            }
            else
            {
                if (depth > tracingTimes)
                {
                    color = Color.black;
                }
                else if (scene.skyLight != null)
                {
                    color = m_SkyShader.Shade(scene.skyLight.material, sampler, ray);
                }
            }

            color.FixColor();

#if DEBUG
            if (isDebugging)
            {
                Log.AddLog(LogType.Debugging, $"深度:{depth},射线:{ray},颜色:{color}");
            }
#endif
            return(color);
        }
Example #15
0
 public override Vector3 Sample(SamplerBase sampler)
 {
     throw new NotImplementedException();
 }
Example #16
0
 public abstract Ray GetRay(int x, int y, SamplerBase sampler);
Example #17
0
 public override float SampleBRDF(SamplerBase sampler, Vector3 wo, Vector3 wi, Vector3 position, Vector3 normal, float roughness)
 {
     return((float)(1.0f / Math.PI));
 }
Example #18
0
 public override Vector3 Sample(SamplerBase sampler, Vector3 hitPoint)
 {
     return(default(Vector3));
 }
Example #19
0
 public abstract Vector3 Sample(SamplerBase sampler, Vector3 hitPoint);
Example #20
0
 public override Vector3 Sample(SamplerBase sampler, Vector3 hitPoint)
 {
     if (m_Geometry == null)
         return Vector3.zero;
     return m_Geometry.Sample(sampler);
 }
Example #21
0
 public abstract Color Render(Tracer tracer, Sky sky, SamplerBase sampler, Ray ray, RayCastHit hit, double epsilon);
Example #22
0
 public override Vector3 Sample(SamplerBase sampler)
 {
     return(position + sampler.SampleSphere() * radius);
 }
Example #23
0
        public override Vector3 Sample(SamplerBase sampler)
        {
            Vector2 pos = sampler.SampleUnitDisk();

            return(position + right * (pos.x) + up * (pos.y));
        }
Example #24
0
 public override Vector3 Sample(SamplerBase sampler, Vector3 hitPoint)
 {
     return(hitPoint + (sunDirection * -1.0) * kEarthSurfaceToSun + sampler.SampleSphere() * kSunRadius);
 }
Example #25
0
        public Color Shade(Material material, SamplerBase sampler, Ray ray, RayCastHit hit)
        {
            if (hit.depth > m_PathTracer.tracingTimes)
            {
                if (material.IsEmissive() && m_PathTracer.sampleDirectLight && ray.isDiffuseRay)
                {
                    return(Color.black);
                }
                return(material.GetEmissive(hit));
            }
            if (material.IsEmissive())
            {
                if (m_PathTracer.sampleDirectLight && hit.depth != 0 && ray.isDiffuseRay)
                {
                    return(Color.black);
                }
                return(material.GetEmissive(hit));
            }

            float   refractive  = material.GetRefractive(hit);
            float   metallic    = material.GetMetallic(hit);
            float   roughness   = material.GetRoughness(hit);
            float   opacity     = material.GetOpacity(hit);
            Color   albedo      = material.GetAlbedo(hit);
            Vector3 worldNormal = material.GetWorldNormal(hit);

            float ndv = (float)Math.Max(0.0f, Vector3.Dot(worldNormal, -1.0 * ray.direction));

            if (hit.isBackFace)
            {
                refractive = 1.0f / refractive;
            }

            float F0 = (1.0f - refractive) / (1.0f + refractive);

            F0 = F0 * F0;
            if (F0 > 0.04f)
            {
                F0 = 0.04f;
            }
            Color F0Col = Color.Lerp(new Color(F0, F0, F0), albedo, metallic);

            Color fresnel = Fresnel.FresnelSchlick(ndv, F0Col, roughness);

            float fl = fresnel.Average();

            ShadingType shadingType = ShadingType.Reflect;

            double russianRoulette = sampler.GetRandom();

            if (fl > russianRoulette)
            {
                shadingType = ShadingType.Reflect;
            }
            else if (fl + (1.0f - fl) * (1.0f - opacity) > russianRoulette)
            {
                shadingType = ShadingType.Refract;
            }
            else
            {
                shadingType = ShadingType.Diffuse;
            }

            if (shadingType == ShadingType.Diffuse)
            {
                if (1.0f - metallic < float.Epsilon)
                {
                    return(Color.black);
                }

                if (albedo.IsCloseToZero())
                {
                    return(Color.black);
                }

                Vector3 sp  = sampler.SampleHemiSphere();
                Vector3 wi  = Vector3.ONB(worldNormal, sp);
                float   pdf = (float)(sp.z / Math.PI);

                double ndl = Vector3.Dot(worldNormal, wi);

                if (ndl <= 0.0)
                {
                    return(Color.black);
                }

                float brdf = (roughness < float.Epsilon ? m_LambertaianBRDF : m_DisneyDiffuseBRDF).SampleBRDF(sampler, ray.direction * -1.0, wi, hit.hit, worldNormal, roughness);

                if (brdf < float.Epsilon)
                {
                    return(Color.black);
                }

                Ray diffuseRay = new Ray(hit.hit, wi, true);

                Color L = m_PathTracer.PathTracing(diffuseRay, sampler, hit.depth + 1);

                return(albedo * L * brdf * (1.0f - metallic) * (float)ndl / pdf);
            }
            if (shadingType == ShadingType.Reflect)
            {
                if (albedo.IsCloseToZero())
                {
                    return(Color.black);
                }

                Vector3 sp       = sampler.SampleHemiSphere(roughness);
                Vector3 spnormal = Vector3.ONB(worldNormal, sp);
                Vector3 wo       = ray.direction * -1.0;
                Vector3 wi       = Vector3.Reflect(wo, spnormal);
                float   pdf      = (float)(sp.z / Math.PI);

                double ndl = Vector3.Dot(worldNormal, wi);

                if (ndl <= 0.0)
                {
                    return(Color.black);
                }

                float brdf = m_CookTorranceBRDF.SampleBRDF(sampler, wo, wi, hit.hit, worldNormal, roughness);

                if (brdf < float.Epsilon)
                {
                    return(Color.black);
                }

                Ray specularRay = new Ray(hit.hit, wi, false);

                Color L = m_PathTracer.PathTracing(specularRay, sampler, hit.depth + 1);

                return(Color.Lerp(Color.white, fresnel, metallic) * L * brdf * (float)ndl / pdf);
            }
            if (shadingType == ShadingType.Refract)
            {
            }
            return(Color.black);

            //MaterialProperty property;

            //property.worldNormal = material.GetWorldNormal(hit);
            //property.opacity = material.GetOpacity(hit);
            //property.metallic = material.GetMetallic(hit);
            //property.roughness = material.GetRoughness(hit);
            //property.albedo = material.GetAlbedo(hit);

            //if (m_PathTracer.sampleDirectLight)
            //    result += ShadeDirectLights(property, sampler, ray, hit);

            //result += material.GetOcclusion(hit) * ShadeAmbientLight(property, sampler, ray, hit);

            //return result + material.GetEmissive(hit);
        }
Example #26
0
 /// <summary>
 ///
 /// </summary>
 /// <returns></returns>
 public abstract float SampleBRDF(SamplerBase sampler, Vector3 wo, Vector3 wi, Vector3 position, Vector3 normal, float roughness);
Example #27
0
 public abstract Vector3 Sample(SamplerBase sampler);
Example #28
0
 public abstract Color Tracing(Ray ray, Sky sky, SamplerBase sampler, int depth = 0);