예제 #1
0
        public Color Integrate(Ray ray, IIntersectable objects, List <ILight> lights, ISampler sampler, List <List <Sample> > subPathSamples, LightSample lightSample)
        {
            shadowIntegrator = new ShadowIntegrator();
            Color     returnColor = new Color(0, 0, 0);
            HitRecord record      = objects.Intersect(ray);

            if (record != null)
            {
                if (!(record.Material is MirrorMaterial))
                {
                    returnColor.Append(shadowIntegrator.Integrate(ray, objects, lights, sampler, subPathSamples, lightSample));
                }
                if (record.Material is MirrorMaterial && record.Material.Specular.R > 0 && record.Material.Specular.G > 0 && record.Material.Specular.B > 0)
                {
                    returnColor.Append(Reflection(ray, record, 0, returnColor, objects, lights, sampler, subPathSamples, lightSample));
                }
            }
            else
            {
                if (SkyBox.IsSkyBoxLoaded())
                {
                    returnColor = SkyBox.GetSkyBoxColor(ray);
                }
            }
            return(returnColor);
        }
예제 #2
0
        /// <summary>
        /// Generates the Texture3D
        /// </summary>
        /// <param name="sourceTexture">The source texture asset</param>
        /// <returns>True if parameters were valid, false otherwise</returns>
        public bool GenerateVolumetricTexture(Texture2D sourceTexture)
        {
            if (AreParametersValid)
            {
                Texture3D volumetricTexture = new Texture3D(_referenceSize, _referenceSize, _referenceSize, sourceTexture.format, false);
                volumetricTexture.wrapMode   = sourceTexture.wrapMode;
                volumetricTexture.wrapModeU  = sourceTexture.wrapModeU;
                volumetricTexture.wrapModeV  = sourceTexture.wrapModeV;
                volumetricTexture.wrapModeW  = sourceTexture.wrapModeW;
                volumetricTexture.filterMode = sourceTexture.filterMode;
                volumetricTexture.mipMapBias = 0;
                volumetricTexture.anisoLevel = 0;

                Color[] colorArray = new Color[0];
                switch (_readingOrder)
                {
                case Texture3DReadingOrderEnum.RowMajor:
                {
                    for (int i = 0; i < HorizontalTilesCount; ++i)
                    {
                        for (int j = 0; j < VerticalTilesCount; ++j)
                        {
                            colorArray = colorArray.Append(sourceTexture.GetPixels(i * _referenceSize, j * _referenceSize, _referenceSize, _referenceSize));
                        }
                    }
                }

                break;

                case Texture3DReadingOrderEnum.ColumnMajor:
                {
                    for (int i = VerticalTilesCount - 1; i >= 0; --i)
                    {
                        for (int j = 0; j < HorizontalTilesCount; ++j)
                        {
                            colorArray = colorArray.Append(sourceTexture.GetPixels(j * _referenceSize, i * _referenceSize, _referenceSize, _referenceSize));
                        }
                    }
                }

                break;
                }

                volumetricTexture.SetPixels(colorArray);
                volumetricTexture.Apply();

                AssetDatabase.CreateAsset(volumetricTexture, System.IO.Directory.GetParent(AssetDatabase.GetAssetPath(sourceTexture)) + "\\" + sourceTexture.name + "_Texture3D.asset");

                return(true);
            }

            return(false);
        }
예제 #3
0
 public void Render()
 {
     if (sampler != null)
     {
         for (int i = 0; i < camera.ScreenWidth; i++)
         {
             for (int j = threadId; j < camera.ScreenHeight; j += Constants.NumberOfThreads)
             {
                 Color pixelColor = new Color(0, 0, 0);
                 List <List <Sample> > subPathSamples = new List <List <Sample> >();
                 List <Sample>         samples        = sampler.CreateSamples();
                 List <LightSample>    lightSamples   = new List <LightSample>();
                 if (integrator is PathTraceIntegrator)
                 {
                     lightSamples = sampler.GetLightSamples(Constants.MaximalPathLength);
                     for (int s = 0; s < Constants.MaximalPathLength; s++)
                     {
                         subPathSamples.Add(sampler.CreateSamples());
                     }
                     foreach (Sample sample in samples)
                     {
                         Ray ray = camera.CreateRay(i + sample.X, j + sample.Y);
                         pixelColor.Append(integrator.Integrate(ray, objects, lights, sampler, subPathSamples, Randomizer.PickRandomLightSample(lightSamples)));
                     }
                 }
                 else
                 {
                     lightSamples = sampler.GetLightSamples();
                     foreach (Sample sample in samples)
                     {
                         Ray ray = camera.CreateRay(i + sample.X, j + sample.Y);
                         pixelColor.Append(integrator.Integrate(ray, objects, lights, sampler, subPathSamples, Randomizer.PickRandomLightSample(lightSamples)));
                     }
                 }
                 pixelColor.VoidDiv(samples.Count);
                 film.SetPixel(i, j, pixelColor);
             }
         }
     }
     else
     {
         for (int i = 0; i < camera.ScreenWidth; i++)
         {
             for (int j = threadId; j < camera.ScreenHeight; j += Constants.NumberOfThreads)
             {
                 Ray   ray        = camera.CreateRay(i, j);
                 Color pixelColor = integrator.Integrate(ray, objects, lights, null, null, null);
                 film.SetPixel(i, j, pixelColor);
             }
         }
     }
     ThreadDone(this, new EventArgs());
 }
        /// <summary>
        /// Generates the Texture3D composed out of the candidate textures (already handles NeedsToUpdateVolumeTexture parameter check)
        /// </summary>
        public void Generate()
        {
            if (NeedsToUpdateVolumeTexture)
            {
                if (_texturesList.Count > 0)
                {
                    Color[] colorArray = new Color[0];
                    VolumeTexture = new Texture3D(_requiredSize, _requiredSize, _requiredSize * _texturesList.Count, _requiredTextureFormat, false);

                    for (int i = 0; i < _texturesList.Count; ++i)
                    {
                        // TODO : DO WITH GRAPHICS.COPYTEXTURES NOW THAT TEXTURE3D COPY ACTUALLY WORKS
                        colorArray = colorArray.Append(_texturesList[i].GetPixels());
                    }

                    VolumeTexture.SetPixels(colorArray);
                    VolumeTexture.Apply();

                    HasVolumeTexture = true;
                }
                else
                {
                    VolumeTexture    = null;
                    HasVolumeTexture = false;
                }

                NeedsToUpdateVolumeTexture = false;

                RaiseTextureUpdatedEvent();
            }
        }
예제 #5
0
        private Color Reflection(Ray ray, HitRecord record, int noOfBounce, Color color, IIntersectable objects, List <ILight> lights, ISampler sampler, List <List <Sample> > subPathSamples, LightSample lightSample)
        {
            Color ks = record.Material.Specular;

            if (noOfBounce == Constants.MaximumRecursionDepth)
            {
                return(shadowIntegrator.Integrate(ray, objects, lights, sampler, subPathSamples, lightSample).Mult(ks));
            }

            Ray       reflectedRay  = record.CreateReflectedRay();
            HitRecord reflectRecord = objects.Intersect(reflectedRay);

            if (reflectRecord.HitObject != null)
            {
                if (reflectRecord.Material is MirrorMaterial)
                {
                    Color c = Reflection(reflectedRay, reflectRecord, ++noOfBounce, color, objects, lights, sampler, subPathSamples, lightSample);
                    c.Append(shadowIntegrator.Integrate(reflectedRay, objects, lights, sampler, subPathSamples, lightSample).Mult(ks));
                    return(c);
                }
                else
                {
                    return(shadowIntegrator.Integrate(reflectedRay, objects, lights, sampler, subPathSamples, lightSample).Mult(ks));
                }
            }
            else
            {
                if (SkyBox.IsSkyBoxLoaded())
                {
                    color = SkyBox.GetSkyBoxColor(ray);
                }
            }
            return(color);
        }
예제 #6
0
        public Color Integrate(Ray ray, IIntersectable objects, List <ILight> lights, ISampler sampler, List <List <Sample> > subPathSamples, LightSample lightSample)
        {
            HitRecord record = objects.Intersect(ray);

            Color returnColor = new Color(0, 0, 0);

            if (record != null)
            {
                foreach (ILight light in lights)
                {
                    Vector3 lightDirection = light.GetLightDirection(record.IntersectionPoint);
                    Vector3 hitPos         = record.IntersectionPoint;
                    Vector3 offset         = record.RayDirection;
                    offset  = -offset;
                    offset *= 0.001f;
                    hitPos += offset;
                    Ray       shadowRay = new Ray(hitPos, lightDirection);
                    HitRecord shadowHit = objects.Intersect(shadowRay);
                    Vector3   distance  = Vector3.Subtract(light.Position, hitPos);

                    //DEBUGGING

                    /*if (shadowHit != null && (shadowHit.Distance > distance.Length))
                     * {
                     *  returnColor.Append(record.HitObject.Material.Shade(record, light.GetLightDirection(record.IntersectionPoint)).Mult(light.GetIncidentColor(record.IntersectionPoint)));
                     * }*/
                    returnColor.Append(record.HitObject.Material.Shade(record, light.GetLightDirection(record.IntersectionPoint)).Mult(light.GetIncidentColor(record.IntersectionPoint)));
                }
            }
            return(returnColor);
        }
예제 #7
0
        public Color Integrate(Ray ray, IIntersectable objects, List <ILight> lights, ISampler sampler, List <List <Sample> > subPathSamples, LightSample lightSample)
        {
            HitRecord record   = objects.Intersect(ray);
            Color     retColor = new Color(0, 0, 0);

            this.objects = objects;
            this.lights  = lights;
            this.sampler = sampler;
            retColor.Append(GetShadeColor(record, 0));
            return(retColor);
        }
예제 #8
0
        private Color Shade(HitRecord record, LightSample sample)
        {
            Color pixelColor = new Color(0, 0, 0);

            if (record.Material is LambertMaterial || record.Material is BlinnPhongMaterial)
            {
                if (sample.LightColor.Power > 0 && IsVisible(record, sample))
                {
                    pixelColor.Append(record.Material.Shade(record, sample.Wi).Mult(sample.LightColor));
                }
            }
            return(pixelColor);
        }
예제 #9
0
        public Color Integrate(Ray ray, IIntersectable objects, List <ILight> lights, ISampler sampler, List <List <Sample> > subPathSamples, LightSample lightSample)
        {
            Color returnColor = new Color(0, 0, 0);

            /*
             * Core Ray Tracing algorithm
             */
            HitRecord record = objects.Intersect(ray);

            if (record != null && record.Distance > 0 && record.Distance < float.PositiveInfinity)
            {
                foreach (ILight light in lights)
                {
                    returnColor.Append(record.Material.Shade(record, light.GetLightDirection(record.IntersectionPoint)).Mult(light.GetIncidentColor(record.IntersectionPoint)));
                }
            }
            return(returnColor);
        }
예제 #10
0
        public void Render()
        {
            DepthOfFieldCamera cam = ((DepthOfFieldCamera)scene.Camera);

            for (int i = 0; i < scene.Film.Width; i++)
            {
                for (int j = 0; j < scene.Film.Height; j++)
                {
                    Color         pixelColor       = new Color(0, 0, 0);
                    List <Sample> appertureSamples = ((ISampler)Activator.CreateInstance(Constants.Sampler)).CreateSamples();
                    for (int s = 0; s < 24; s++)
                    {
                        Ray ray = cam.CreateRay(i, j, appertureSamples);

                        pixelColor.Append(scene.Integrator.Integrate(ray, scene.Objects, scene.Lights, null, null, null));
                    }
                    pixelColor.VoidDiv(24f);
                    scene.Film.SetPixel(i, j, pixelColor);
                }
            }
            Tonemapper.SaveImage("C:\\Test\\" + scene.FileName, scene.Film);
        }
예제 #11
0
        private Color GetShadeColor(HitRecord record, int currentDepth)
        {
            if (record != null && record.Distance > 0 && record.Distance < float.MaxValue)
            {
                if (record.Material is MirrorMaterial && currentDepth <= Constants.MaximumRecursionDepth) //Shade Mirror Objects
                {
                    HitRecord mirrorRecord = objects.Intersect(record.CreateReflectedRay());
                    return(GetShadeColor(mirrorRecord, ++currentDepth).Mult(record.Material.Ks));
                }
                if (record.Material is RefractiveMaterial && currentDepth <= Constants.MaximumRecursionDepth) //Shade Reflective Objects
                {
                    float     r              = Reflectance(record);
                    HitRecord reflectionHit  = objects.Intersect(record.CreateReflectedRay());
                    Color     reflectedColor = GetShadeColor(reflectionHit, ++currentDepth).Mult(record.Material.Ks);
                    HitRecord refractedHit   = objects.Intersect(CreateRefractedRay(record));
                    Color     refractedColor = GetShadeColor(refractedHit, ++currentDepth).Mult(record.Material.Ks);
                    Color     retColor       = reflectedColor.Mult(r);
                    retColor.Append(refractedColor.Mult(1 - r));
                    return(retColor);
                }

                if (record.HitObject.Light != null && Constants.IsLightSamplingOn)
                {
                    return(record.HitObject.Light.LightColor);
                }

                Color returnColor = new Color(0, 0, 0);
                foreach (ILight light in lights)
                {
                    Color lightColor = new Color(0, 0, 0);

                    if (Constants.IsLightSamplingOn && Constants.NumberOfLightSamples > 0)
                    {
                        List <LightSample> lightSamples = sampler.GetLightSamples();
                        for (int i = 0; i < Constants.NumberOfLightSamples; i++)
                        {
                            LightSample sample = lightSamples[(int)(random.NextDouble() * lightSamples.Count)];
                            lightSamples.Remove(sample);
                            light.Sample(record, sample);
                            if (IsVisible(record, sample) && sample.LightColor.Power > 0)
                            {
                                if (!(light is AreaLight))
                                {
                                    lightColor.Append(record.Material.Shade(record, sample.Wi).Mult(sample.LightColor));
                                }
                                else
                                {
                                    lightColor.Append(record.Material.Shade(record, sample.Wi).Mult(sample.LightColor).Div(sample.Pdf));
                                }
                            }
                        }
                        returnColor.Append(lightColor.Div(Constants.NumberOfLightSamples));
                    }

                    if (!(light is AreaLight) && IsVisible(record, light))
                    {
                        returnColor.Append(record.HitObject.Material.Shade(record, light.GetLightDirection(record.IntersectionPoint)).Mult(light.GetIncidentColor(record.IntersectionPoint)));
                    }
                }
                return(returnColor);
            }
            return(new Color(0, 0, 0));
        }
예제 #12
0
        public Color PathTrace(Ray ray, HitRecord record, List <List <Sample> > subPathSamples, LightSample lightSample)
        {
            float q          = 0f;
            int   depth      = 0;
            Color pixelColor = new Color(0, 0, 0);
            Color alpha      = new Color(1, 1, 1);

            bool isGeneratedFromRefraction = false;

            while (depth < Constants.MaximalPathLength)
            {
                if (record == null)
                {
                    return(pixelColor);
                }
                //Select one light at random
                ILight light = Randomizer.PickRandomLight(lights);
                //Sample that light
                light.Sample(record, lightSample);

                if (isGeneratedFromRefraction && record.HitObject.Light != null)
                {
                    isGeneratedFromRefraction = false;
                    pixelColor.Append(record.HitObject.Light.LightColor);
                }

                pixelColor.Append(alpha.Mult(Shade(record, lightSample)).Div(lightSample.Pdf));

                //Break with Russian roulette
                if (depth > 2)
                {
                    q = 0.5f;
                    if (random.NextDouble() <= q)
                    {
                        return(pixelColor);
                    }
                }

                List <Sample> directionSamples = subPathSamples[depth];
                //Create the next Ray
                if (record.Material is LambertMaterial || record.Material is BlinnPhongMaterial)
                {
                    Sample  directionSample = Randomizer.PickRandomSample(directionSamples);
                    Vector3 direction       = UniformHemisphereSample(directionSample.X, directionSample.Y, record.SurfaceNormal);
                    record = scene.Intersect(new Ray(record.IntersectionPoint, direction));
                    if (record == null)
                    {
                        break;
                    }
                    alpha = alpha.Mult(record.Material.Diffuse.Div(1 - q));
                }
                else if (record.Material is MirrorMaterial)
                {
                    record = scene.Intersect(record.CreateReflectedRay());
                    isGeneratedFromRefraction = true;
                }
                else if (record.Material is RefractiveMaterial)
                {
                    isGeneratedFromRefraction = true;
                    float fresnel = Reflectance(record);
                    //Pick refraction / reflection path with p=0.5 each
                    if (random.NextDouble() < fresnel)
                    {
                        record = scene.Intersect(record.CreateReflectedRay());
                        alpha  = alpha.Mult(fresnel);
                    }
                    else
                    {
                        record = scene.Intersect(record.CreateRefractedRay());
                        alpha  = alpha.Mult(1 - fresnel);
                    }
                }

                depth++;
            }
            return(pixelColor);
        }
예제 #13
0
        public Color Shade(HitRecord record, Vector3 wi)
        {
            Color   pixelColor = new Color(0, 0, 0);
            Vector3 normal     = record.SurfaceNormal;

            normal.Normalize();
            wi.Normalize();

            float noiseCoefficient = 0f;

            switch (Noise)
            {
            case Noise.Turbulence:
                noiseCoefficient = Turbulence(record.IntersectionPoint);
                break;

            case Noise.Marble:
                noiseCoefficient = Marble(record.IntersectionPoint);
                break;

            case Noise.Bumb:
                noiseCoefficient = 1f;
                normal           = Bump(record.IntersectionPoint, normal);
                break;

            case Noise.None:
                noiseCoefficient = 1f;
                break;

            default:
                noiseCoefficient = 1f;
                break;
            }

            if (BumpTexture != null)
            {
                Color   displacementColor  = BumpTexture.GetColorFromTexCoordinate(record.HitObject.GetTextudeCoordinates(record));
                Vector3 displacementNormal = normal;
                displacementNormal.X = ((displacementColor.R * 2) - 1);
                displacementNormal.Y = ((displacementColor.G * 2) - 1);
                displacementNormal.Z = displacementColor.B;
                normal = (Vector3.Dot(displacementNormal, normal) < 0) ? -displacementNormal : displacementNormal;
            }

            float nDotL = Vector3.Dot(normal, wi);

            if (nDotL > 0)
            {
                Color diffuse;

                if (Constants.TextureMapping && ColorTexture != null && !(record.HitObject is Plane))
                {
                    diffuse = ColorTexture.GetColorFromTexCoordinate(record.HitObject.GetTextudeCoordinates(record));
                }
                else
                {
                    diffuse = Diffuse;
                }

                //add Diffuse Light
                pixelColor.Append(diffuse.Mult(nDotL).Mult(noiseCoefficient));
                pixelColor.Append(pixelColor.Mult(1f - noiseCoefficient));
                //Calculate the Blinn halfVector
                Vector3 h = wi;
                h = Vector3.Add(h, wi);
                h.Normalize();


                float hDotN = Vector3.Dot(h, normal);
                if (hDotN > 0)
                {
                    float pow = (float)Math.Pow(hDotN, Shininess);
                    pixelColor.Append(Specular.Mult(pow));
                }
            }
            pixelColor.Append(Ambient);
            pixelColor.Clamp(0f, 1f);
            return(pixelColor);
        }
예제 #14
0
        public void Render()
        {
            stopwatch = new Stopwatch();
            stopwatch.Reset();
            if (Constants.NumberOfThreads == 1) //One Thread
            {
                stopwatch.Start();
                ISampler sampler = (ISampler)Activator.CreateInstance(Constants.Sampler);
                if (Constants.IsSamplingOn && Constants.NumberOfSamples > 0)
                {
                    Console.WriteLine("Using Supersampling with: " + Constants.NumberOfSamples + " samples!");

                    for (int i = 0; i < scene.Film.Width; i++)
                    {
                        for (int j = 0; j < scene.Film.Height; j++)
                        {
                            Color pixelColor = new Color(0, 0, 0);
                            List <List <Sample> > subPathSamples = new List <List <Sample> >();
                            List <LightSample>    lightSamples   = new List <LightSample>();
                            List <Sample>         samples        = sampler.CreateSamples();
                            if (scene.Integrator is PathTraceIntegrator)
                            {
                                lightSamples = sampler.GetLightSamples(Constants.MaximalPathLength);
                                for (int s = 0; s < Constants.MaximalPathLength; s++)
                                {
                                    subPathSamples.Add(sampler.CreateSamples());
                                }
                                foreach (Sample sample in samples)
                                {
                                    Ray ray = scene.Camera.CreateRay(i + sample.X, j + sample.Y);
                                    pixelColor.Append(scene.Integrator.Integrate(ray, scene.Objects, scene.Lights, sampler, subPathSamples, Randomizer.PickRandomLightSample(lightSamples)));
                                }
                            }
                            else
                            {
                                lightSamples = sampler.GetLightSamples();
                                foreach (Sample sample in samples)
                                {
                                    Ray ray = scene.Camera.CreateRay(i + sample.X, j + sample.Y);
                                    pixelColor.Append(scene.Integrator.Integrate(ray, scene.Objects, scene.Lights, sampler, subPathSamples, Randomizer.PickRandomLightSample(lightSamples)));
                                }
                            }

                            pixelColor.VoidDiv(samples.Count);
                            scene.Film.SetPixel(i, j, pixelColor);
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < scene.Film.Width; i++)
                    {
                        for (int j = 0; j < scene.Film.Height; j++)
                        {
                            Ray   ray   = scene.Camera.CreateRay(i, j);
                            Color color = scene.Integrator.Integrate(ray, scene.Objects, scene.Lights, null, null, null);
                            scene.Film.SetPixel(i, j, color);
                        }
                    }
                }
                stopwatch.Stop();
                Debug.WriteLine("Finished rendering in: " + stopwatch.ElapsedMilliseconds + " ms.");
                Tonemapper.SaveImage("C:\\Test\\" + scene.FileName, scene.Film);
            }
            else //More than 1 thread
            {
                if (Constants.IsSamplingOn && Constants.NumberOfSamples > 0)
                {
                    Debug.WriteLine("Start rendering with: " + Constants.NumberOfThreads + " Threads");
                    stopwatch.Start();
                    finishedThreads = 0;
                    for (int i = 0; i < Constants.NumberOfThreads; i++)
                    {
                        ISampler sampler = new StratifiedSampler();
                        MultiThreadingRenderer renderer = new MultiThreadingRenderer(i, scene.Objects, scene.Lights,
                                                                                     scene.Camera,
                                                                                     scene.Film);
                        renderer.ThreadDone += HandleThreadDone;
                        Thread t = new Thread(renderer.Render);
                        t.Start();
                    }
                }
                else
                {
                    stopwatch.Start();
                    finishedThreads = 0;
                    for (int i = 0; i < Constants.NumberOfThreads; i++)
                    {
                        MultiThreadingRenderer renderer = new MultiThreadingRenderer(i, scene.Objects, scene.Lights,
                                                                                     scene.Camera,
                                                                                     scene.Film);
                        renderer.ThreadDone += HandleThreadDone;
                        Thread t = new Thread(renderer.Render);
                        t.Start();
                    }
                }
            }
        }