Example #1
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 #2
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);
        }