Пример #1
0
        public static Spectrum SpecularReflect(RayDifferential ray, BSDF bsdf, Intersection isect, IRenderer renderer, Scene scene, Sample sample)
        {
            Vector wo = -ray.Direction, wi = new Vector ();
            double pdf = 0.0;
            Point p = bsdf.dgShading.p;
            Normal n = bsdf.dgShading.n;

            Spectrum f = bsdf.SampleF (wo, ref wi, new BSDFSample (), ref pdf, BxDFType.BSDF_REFLECTION | BxDFType.BSDF_SPECULAR);
            Spectrum L = new Spectrum ();

            if (pdf > 0.0 && !f.IsBlack && Util.AbsDot (wi, n) != 0.0)
            {
                RayDifferential rd = new RayDifferential (p, wi, ray, isect.RayEpsilon);
                if (ray.HasDifferentials)
                {
                    rd.HasDifferentials = true;
                    rd.RxOrigin = p + isect.dg.dpdx;
                    rd.RyOrigin = p + isect.dg.dpdy;

                    Normal dndx = bsdf.dgShading.dndu * bsdf.dgShading.dudx + bsdf.dgShading.dndv * bsdf.dgShading.dvdx;
                    Normal dndy = bsdf.dgShading.dndu * bsdf.dgShading.dudy + bsdf.dgShading.dndv * bsdf.dgShading.dvdy;
                    Vector dwodx = -ray.RxDirection - wo, dwody = -ray.Direction - wo;
                    double dDNdx = (dwodx ^ n) + (wo ^ dndx);
                    double dDNdy = (dwody ^ n) + (wo ^ dndy);
                    rd.RxDirection = wi - dwodx + 2 * new Vector ((wo ^ n) * dndx + dDNdx * n);
                    rd.RyDirection = wi - dwody + 2 * new Vector ((wo ^ n) * dndy + dDNdy * n);
                }

                Spectrum Li = renderer.Li (scene, rd, sample);
                L = f * Li * Util.AbsDot (wi, n) / pdf;
            }

            return L;
        }
Пример #2
0
        public void Run()
        {
            ISampler sampler = MainSampler.GetSubSampler (TaskNumber, TaskCount);
            if (sampler == null)
            {
                return;
            }

            int maxSamples = sampler.MaximumSampleCount;
            Sample[] samples = OrigSample.Duplicate (maxSamples);
            RayDifferential[] rays = new RayDifferential[maxSamples];
            Spectrum[] Ls = new Spectrum[maxSamples];
            Spectrum[] Ts = new Spectrum[maxSamples];
            Intersection[] isects = new Intersection[maxSamples];

            for (int i = 0; i < maxSamples; ++i)
            {
                samples[i] = new Sample ();
                rays[i] = new RayDifferential ();
                Ls[i] = new Spectrum ();
                Ts[i] = new Spectrum ();
                isects[i] = new Intersection ();
            }

            int sampleCount;

            while ((sampleCount = sampler.GetMoreSamples (samples)) > 0)
            {
                for (int i = 0; i < sampleCount; ++i)
                {
                    double rayWeight = Camera.GenerateRayDifferential (samples[i], ref rays[i]);
                    rays[i].ScaleDifferentials (1.0 / Math.Sqrt (sampler.SamplesPerPixel));

                    if (rayWeight > 0.0)
                        Ls[i] = rayWeight * Renderer.Li (Scene, rays[i], samples[i], ref isects[i], ref Ts[i]);
                    else
                    {
                        Ls[i] = new Spectrum ();
                        Ts[i] = new Spectrum (1.0);
                    }

                    // WARNINGS
                }

                if (sampler.ReportResults (samples, rays, Ls, isects, sampleCount))
                {
                    for (int i = 0; i < sampleCount; ++i)
                        Camera.Film.AddSample (samples[i], Ls[i]);
                }
            }

            Camera.Film.UpdateDisplay (sampler.xPixelStart, sampler.yPixelStart, sampler.xPixelEnd + 1, sampler.yPixelEnd + 1);
            Reporter.Update ();
        }
Пример #3
0
        public override bool Intersect(Ray ray, ref Intersection isect)
        {
            double thit = 0.0, rayEpsilon = 0.0;
            if (!Shape.Intersect (ray, ref thit, ref rayEpsilon, ref isect.dg))
                return false;

            isect.Primitive = this;
            isect.WorldToObject = Shape.WorldToObject;
            isect.ObjectToWorld = Shape.ObjectToWorld;
            isect.ShapeID = Shape.ShapeID;
            isect.PrimitiveID = PrimitiveID;
            isect.RayEpsilon = rayEpsilon;
            ray.MaxT = thit;

            return true;
        }
Пример #4
0
        public static Spectrum SpecularTransmit(RayDifferential ray, BSDF bsdf, Intersection isect, IRenderer renderer, Scene scene, Sample sample)
        {
            Vector wo = -ray.Direction, wi = new Vector ();
            double pdf = 0.0;
            Point p = bsdf.dgShading.p;
            Normal n = bsdf.dgShading.n;
            Spectrum f = bsdf.SampleF (wo, ref wi, new BSDFSample (), ref pdf, BxDFType.BSDF_TRANSMISSION | BxDFType.BSDF_SPECULAR);
            Spectrum L = new Spectrum ();

            if (pdf > 0.0 && !f.IsBlack && Util.AbsDot (wi, n) != 0.0)
            {
                RayDifferential rd = new RayDifferential (p, wi, ray, isect.RayEpsilon);
                if (ray.HasDifferentials)
                {
                    rd.HasDifferentials = true;
                    rd.RxOrigin = p + isect.dg.dpdx;
                    rd.RyOrigin = p + isect.dg.dpdy;

                    double eta = bsdf.Eta;
                    Vector w = -wo;

                    if ((wo ^ n) < 0.0)
                        eta = 1.0 / eta;

                    Normal dndx = bsdf.dgShading.dndu * bsdf.dgShading.dudx + bsdf.dgShading.dndv * bsdf.dgShading.dvdx;
                    Normal dndy = bsdf.dgShading.dndu * bsdf.dgShading.dudy + bsdf.dgShading.dndv * bsdf.dgShading.dvdy;

                    Vector dwodx = -ray.RxDirection - wo, dwody = -ray.RyDirection - wo;
                    double dDNdx = (dwodx ^ n) + (wo ^ dndx);
                    double dDNdy = (dwody ^ n) + (wo ^ dndy);
                    double mu = eta * (w ^ n) - (wi ^ n);
                    double dmudx = (eta - (eta * eta * (w ^ n)) / (wi ^ n)) * dDNdx;
                    double dmudy = (eta - (eta * eta * (w ^ n)) / (wi ^ n)) * dDNdy;

                    rd.RxDirection = wi + eta * dwodx - new Vector (mu * dndx + dmudx * n);
                    rd.RyDirection = wi + eta * dwody - new Vector (mu * dndy + dmudy * n);
                }

                Spectrum Li = renderer.Li (scene, rd, sample);
                L = f * Li * Util.AbsDot (wi, n) / pdf;
            }

            return L;
        }
Пример #5
0
 public abstract Spectrum Li(Scene scene, IRenderer renderer, RayDifferential ray, Intersection isect, Sample sample);
Пример #6
0
        public override bool Intersect(Ray ray, ref Intersection intersection)
        {
            double rayT = 0.0, t = 0.0;
            if (Bounds.Inside (ray.Apply (ray.MinT)))
                rayT = ray.MinT;
            else if (!Bounds.IntersectP (ray, out rayT, out t))
                return false;
            Point gridIntersect = ray.Apply (rayT);

            double[] nextCrossing = new double[3];
            double[] delta = new double[3];
            int[] Step = new int[3];
            int[] Out = new int[3];
            int[] Pos = new int[3];

            for (int axis = 0; axis < 3; ++axis)
            {
                Pos[axis] = PositionToVoxel (gridIntersect, axis);
                if (ray.Direction[axis] >= 0)
                {
                    nextCrossing[axis] = rayT + (VoxelToPos (Pos[axis] + 1, axis) - gridIntersect[axis]) / ray.Direction[axis];
                    delta[axis] = Width[axis] / ray.Direction[axis];
                    Step[axis] = 1;
                    Out[axis] = nVoxels[axis];
                }
                else
                {
                    nextCrossing[axis] = rayT + (VoxelToPos(Pos[axis], axis) - gridIntersect[axis]) / ray.Direction[axis];
                    delta[axis] = -Width[axis] / ray.Direction[axis];
                    Step[axis] = -1;
                    Out[axis] = -1;
                }
            }

            bool hitSomething = false;
            while (true)
            {
                Voxel voxel = Voxels[Offset (Pos[0], Pos[1], Pos[2])];
                if (voxel != null)
                {
                    hitSomething |= voxel.Intersect (ray, ref intersection);
                }

                int bits = (((nextCrossing[0] < nextCrossing[1]) ? 1 : 0) << 2) + (((nextCrossing[0] < nextCrossing[2]) ? 1 : 0) << 1) + (((nextCrossing[1] < nextCrossing[2]) ? 1 : 0));
                int[] cmpTpAxis = new int[] { 2, 1, 2, 1, 2, 2, 0, 0 };
                int stepAxis = cmpTpAxis[bits];
                if (ray.MaxT < nextCrossing[stepAxis])
                {
                    break;
                }
                Pos[stepAxis] += Step[stepAxis];
                if (Pos[stepAxis] == Out[stepAxis])
                    break;
                nextCrossing[stepAxis] += delta[stepAxis];
            }
            return hitSomething;
        }
Пример #7
0
 public Spectrum Li(Scene scene, RayDifferential ray, Sample sample, ref Intersection isect)
 {
     Spectrum T = new Spectrum ();
     return Li (scene, ray, sample, ref isect, ref T);
 }
Пример #8
0
 public abstract Spectrum Li(Scene scene, RayDifferential ray, Sample sample, ref Intersection isect, ref Spectrum T);
Пример #9
0
        /// <summary>
        ///     Checks if the given ray intersects the primitive.
        /// </summary>
        /// <param name="ray">
        ///     The ray to test for
        /// </param>
        /// <param name="intersection">
        ///     A pointer to an Intersection structure that'll hold
        ///     the intersection information.
        /// </param>
        /// <returns>
        ///     True if the ray intersects the primitive. False otherwise.
        /// </returns>
        public override bool Intersect(Ray ray, ref Intersection intersection)
        {
            int index = 0;

            double tMin = 0.0, tMax = 0.0;

            if (!_bounds.IntersectP (ray, out tMin, out tMax))
            {
                return false;
            }

            Vector inverseDirection = new Vector (1.0 / ray.Direction.x, 1.0 / ray.Direction.y, 1.0 / ray.Direction.z);

            int todoPosition = 0;
            bool hit = false;

            KdToDo[] todo = ToDoPool.Get ();

            while (index >= 0 && index < _nodes.Length)
            {
                if (ray.MaxT < tMin)
                    break;

                if (!_nodes[index].IsLeaf)
                {
                    int axis = _nodes[index].SplitAxis;
                    double tPlane = (_nodes[index].Split - ray.Origin[axis]) * inverseDirection[axis];
                    int firstIndex, secondIndex;
                    bool belowFirst = (ray.Origin[axis] < _nodes[index].Split) || (ray.Origin[axis] == _nodes[index].Split && ray.Direction[axis] >= 0);

                    if (belowFirst)
                    {
                        firstIndex = index + 1;
                        secondIndex = _nodes[index].AboveChild;
                    }
                    else
                    {
                        firstIndex = _nodes[index].AboveChild;
                        secondIndex = index + 1;
                    }

                    if (tPlane > tMax || tPlane <= 0)
                    {
                        index = firstIndex;
                    }
                    else if (tPlane < tMin)
                    {
                        index = secondIndex;
                    }
                    else
                    {
                        todo[todoPosition].tMax = tMax;
                        todo[todoPosition].tMin = tPlane;
                        todo[todoPosition].Index = secondIndex;
                        ++todoPosition;
                        index = firstIndex;
                        tMax = tPlane;
                    }
                }
                else
                {
                    if (_nodes[index].NumberOfPrimitives == 1)
                    {
                        IPrimitive prim = _primitives[_nodes[index].OnePrimitive];
                        if (prim.Intersect (ray, ref intersection))
                        {
                            hit = true;
                        }
                    }
                    else
                    {
                        for (int i = 0; i < _nodes[index].NumberOfPrimitives; ++i)
                        {
                            IPrimitive prim = _primitives[_nodes[index].Primitives[i]];
                            if (prim.Intersect (ray, ref intersection))
                            {
                                hit = true;
                            }
                        }
                    }

                    if (todoPosition > 0)
                    {
                        --todoPosition;
                        tMin = todo[todoPosition].tMin;
                        tMax = todo[todoPosition].tMax;
                        index = todo[todoPosition].Index;
                    }
                    else
                    {
                        break;
                    }
                }
            }
            ToDoPool.Free (todo);

            return hit;
        }
Пример #10
0
 public abstract bool Intersect(Ray ray, ref Intersection isect);
Пример #11
0
 public bool Intersect(Ray ray, ref Intersection isect)
 {
     return Aggregate.Intersect (ray, ref isect);
 }
Пример #12
0
 public virtual bool ReportResults(Sample[] samples, RayDifferential[] rays, Spectrum[] Ls, Intersection[] isects, int count)
 {
     return true;
 }