예제 #1
0
        //public PerspectiveCamera(Transform c2w) { }
        override public float GenerateRay(CameraSample sample, out Ray ray)
        {
            Point3 Pras = new Point3(sample.imageX, sample.imageY, 0); //光栅坐标
            Point3 Pcamera;

            Pcamera = RasterToCamera.Caculate(Pras);//光栅坐标转换为相机坐标 相机为原点

            ray = new Ray(new Point3(0, 0, 0), LR.Normalize(new Vector(Pcamera)), 0.0f, 1.0f / 0);
            // Modify ray for depth of field
            if (lensRadius > 0.0)
            {
                // Sample point on lens
                float lensU, lensV;
                //  ConcentricSampleDisk(sample.lensU, sample.lensV, &lensU, &lensV);
                //lensU *= lensRadius;
                //lensV *= lensRadius;

                // Compute point on plane of focus
                //    float ft = focalDistance / ray->d.z;
                //    Point Pfocus = (*ray)(ft);

                //    // Update ray for effect of lens
                //    ray->o = Point(lensU, lensV, 0.f);
                //    ray->d = Normalize(Pfocus - ray->o);
                //}
                //ray->time = sample.time;
                //CameraToWorld(*ray, ray);
            }

            return(1.0f);
        }
예제 #2
0
        // float GenerateRay()
        public override float GenerateRay(CameraSample sample, out Ray ray)
        {
            Point3 Pras    = new Point3(sample.imageX, sample.imageY);
            Point3 Pcamera = RasterToCamera.Caculate(Pras);

            ray = new Ray(Pcamera, new Vector(0, 0, 1), 0, LR.INFINITY);//正交相机方向固定

            #region modify ray for depth of filed
            if (lensRadius > 0.0f)
            {
                // Sample point on lens
                float lensU = 0, lensV = 0;

                LR.ConcentricSampleDisk(sample.lensU, sample.lensV, ref lensU, ref lensV);
                lensU *= lensRadius;
                lensV *= lensRadius;

                // Compute point on plane of focus
                float  ft     = focalDistance / ray.d.z;
                Point3 Pfocus = ray.Transfer(ft);

                // Update ray for effect of lens
                ray.o = new Point3(lensU, lensV, 0.0f);
                ray.d = LR.Normalize(Pfocus - ray.o);
            }
            #endregion
            ray.time = sample.time;
            ray      = CameraToWorld.Caculate(ray);
            return(1.0f);
        }
예제 #3
0
        public virtual float GenerateRayDifferential(CameraSample sample, out RayDifferential rd)
        {
            Ray   ray;
            float wt = GenerateRay(sample, out ray);

            rd = RayDifferential.FromRay(ray);

            // Find ray after shifting one pixel in the $x$ direction
            CameraSample sshift = sample;

            ++(sshift.ImageX);
            Ray   rx;
            float wtx = GenerateRay(sshift, out rx);

            rd.RxOrigin    = rx.Origin;
            rd.RxDirection = rx.Direction;

            // Find ray after shifting one pixel in the $y$ direction
            --(sshift.ImageX);
            ++(sshift.ImageY);
            Ray   ry;
            float wty = GenerateRay(sshift, out ry);

            rd.RyOrigin    = ry.Origin;
            rd.RyDirection = ry.Direction;

            if (wtx == 0.0f || wty == 0.0f)
            {
                return(0.0f);
            }

            rd.HasDifferentials = true;
            return(wt);
        }
예제 #4
0
        public override float GenerateRayDifferential(CameraSample sample, out RayDifferential ray)
        {
            // Generate raster and camera samples
            Point Pras    = new Point(sample.ImageX, sample.ImageY, 0);
            Point Pcamera = RasterToCamera.TransformPoint(ref Pras);

            ray = new RayDifferential(new Point(0, 0, 0), Vector.Normalize((Vector)Pcamera), 0.0f);
            // Modify ray for depth of field
            if (LensRadius > 0.0f)
            {
                // Sample point on lens
                float lensU, lensV;
                MonteCarloUtilities.ConcentricSampleDisk(sample.LensU, sample.LensV, out lensU, out lensV);
                lensU *= LensRadius;
                lensV *= LensRadius;

                // Compute point on plane of focus
                float ft     = FocalDistance / ray.Direction.Z;
                Point Pfocus = ray.Evaluate(ft);

                // Update ray for effect of lens
                ray.Origin    = new Point(lensU, lensV, 0.0f);
                ray.Direction = Vector.Normalize(Pfocus - ray.Origin);
            }
            // Compute offset rays for _PerspectiveCamera_ ray differentials
            ray.RxOrigin    = ray.RyOrigin = ray.Origin;
            ray.RxDirection = Vector.Normalize((Vector)Pcamera + _dxCamera);
            ray.RyDirection = Vector.Normalize((Vector)Pcamera + _dyCamera);
            ray.Time        = sample.Time;
            ray             = CameraToWorld.TransformRayDifferential(ray);
            return(1.0f);
        }
예제 #5
0
        /// <inheritdoc />
        public override double GenerateRay(CameraSample sample, out Ray ray)
        {
            //ProfilePhase prof(Prof::GenerateCameraRay);
            // Compute raster and camera sample positions
            Point3D pFilm   = new Point3D(sample.FilmPoint.X, sample.FilmPoint.Y, 0.0);
            Point3D pCamera = RasterToCamera.AtPoint(pFilm);

            ray = new Ray(new Point3D(0.0, 0.0, 0.0), pCamera.ToVector3D().Normalize());
            // Modify ray for depth of field
            if (LensRadius > 0.0)
            {
                // Sample point on lens
                Point2D pLens = LensRadius * Sampling.ConcentricSampleDisk(sample.LensPoint);

                // Compute point on plane of focus
                double  ft     = FocalDistance / ray.Direction.Z;
                Point3D pFocus = ray.AtPoint(ft);

                // Update ray for effect of lens
                ray.Origin    = new Point3D(pLens.X, pLens.Y, 0.0);
                ray.Direction = (pFocus - ray.Origin).ToVector3D().Normalize();
            }
            ray.Time   = PbrtMath.Lerp(sample.Time, ShutterOpen, ShutterClose);
            ray.Medium = Medium;
            ray        = CameraToWorld.ExecuteTransform(ray);
            return(1.0);
        }
예제 #6
0
        static void Main(string[] args)
        {
            //Matrix4x4 m1 = new Matrix4x4(-0.0198209956f, -0.328598410f, -0.944261789f, 396.734772f, -0.999803603f, 0.00651442632f, 0.0187198818f, 54.7861862f, 0.000000000f, 0.944447339f, -0.328662962f, 30.0000000f, 0, 0, 0, 1);
            //Matrix4x4 m2 = new Matrix4x4(-0.0198209956f, -0.328598410f, -0.944261789f, 396.734772f, -0.999803603f, 0.00651442632f, 0.0187198818f, 54.7861862f, 0.000000000f, 0.944447339f, -0.328662962f, 30.0000000f, 0, 0, 0, 1);
            //Matrix4x4 m3 = LR.Multiply(m1, m2);
            //Transform t = new Transform(m1);
            //Transform t2 = LR.Multiply(LR.Scale(10, 10, 10), t);

            Transform         t11      = new Transform(new Matrix4x4(-0.0198209956f, -0.328598410f, -0.944261789f, 396.734772f, -0.999803603f, 0.00651442632f, 0.0187198818f, 54.7861862f, 0.000000000f, 0.944447339f, -0.328662962f, 30.0000000f, 0, 0, 0, 1));
            Transform         t22      = new Transform(new Matrix4x4(-0.0198209956f, -0.328598410f, -0.944261789f, 396.734772f, -0.999803603f, 0.00651442632f, 0.0187198818f, 54.7861862f, 0.000000000f, 0.944447339f, -0.328662962f, 30.0000000f, 0, 0, 0, 1));
            AnimatedTransform cam2word = new AnimatedTransform(t11, 0, t22, 1);

            float[] screen = new float[4] {
                -1, 1, -1, 1
            };
            Film film = new Film();

            film.xResolution = 700;
            film.yResolution = 700;
            OrthoCamera  orthoCamera  = new OrthoCamera(cam2word, screen, 0, 1, 0, 0, film);
            CameraSample cameraSample = new CameraSample(689.738220f, 678.709778f, 0.559352338f, 0.253510952f, 0.562246382f);

            //cameraSample.imageX = 689.738220f;
            RayDifferential rd;

            orthoCamera.GenerateRayDifferential(cameraSample, out rd);
        }
예제 #7
0
        void ExportCamera(Scene scene, GameObject go, ExportPlan exportPlan)
        {
            CameraSample sample = (CameraSample)exportPlan.sample;
            Camera       camera = go.GetComponent <Camera>();

            sample.CopyFromCamera(camera);
            scene.Write(exportPlan.path, sample);
        }
예제 #8
0
        // Convenience function to initialize camera samples for the given pixel
        public CameraSample GetCameraSample(Point2 <int> posRaster)
        {
            CameraSample cs = new CameraSample();

            cs.PosFilm = posRaster.ToFloat() + Get2D();
            cs.Time    = Get1D();
            cs.PosLens = Get2D();
            return(cs);
        }
예제 #9
0
        /// <inheritdoc />
        public override double GenerateRayDifferential(CameraSample sample, out RayDifferential ray)
        {
            //ProfilePhase prof(Prof::GenerateCameraRay);
            // Compute raster and camera sample positions
            Point3D  pFilm   = new Point3D(sample.FilmPoint.X, sample.FilmPoint.Y, 0.0);
            Point3D  pCamera = RasterToCamera.ExecuteTransform(pFilm);
            Vector3D dir     = new Vector3D(pCamera.X, pCamera.Y, pCamera.Z).Normalize();

            ray = new RayDifferential(new Point3D(0.0, 0.0, 0.0), dir);
            // Modify ray for depth of field
            if (LensRadius > 0.0)
            {
                // Sample point on lens
                Point2D pLens = LensRadius * Sampling.ConcentricSampleDisk(sample.LensPoint);

                // Compute point on plane of focus
                double  ft     = FocalDistance / ray.Direction.Z;
                Point3D pFocus = ray.AtPoint(ft);

                // Update ray for effect of lens
                ray.Origin    = new Point3D(pLens.X, pLens.Y, 0.0);
                ray.Direction = (pFocus - ray.Origin).ToVector3D().Normalize();
            }

            // Compute offset rays for _PerspectiveCamera_ ray differentials
            if (LensRadius > 0.0)
            {
                // Compute _PerspectiveCamera_ ray differentials accounting for lens

                // Sample point on lens
                Point2D  pLens  = LensRadius * Sampling.ConcentricSampleDisk(sample.LensPoint);
                Vector3D dx     = (pCamera.ToVector3D() + _dxCamera).Normalize();
                double   ft     = FocalDistance / dx.Z;
                Point3D  pFocus = new Point3D(0.0, 0.0, 0.0) + (ft * dx).ToPoint3D();
                ray.RxOrigin    = new Point3D(pLens.X, pLens.Y, 0.0);
                ray.RxDirection = (pFocus - ray.RxOrigin).ToVector3D().Normalize();

                Vector3D dy = (pCamera.ToVector3D() + _dyCamera).Normalize();
                ft              = FocalDistance / dy.Z;
                pFocus          = new Point3D(0.0, 0.0, 0.0) + (ft * dy).ToPoint3D();
                ray.RyOrigin    = new Point3D(pLens.X, pLens.Y, 0.0);
                ray.RyDirection = (pFocus - ray.RyOrigin).ToVector3D().Normalize();
            }
            else
            {
                ray.RxOrigin    = ray.RyOrigin = ray.Origin;
                ray.RxDirection = (pCamera.ToVector3D() + _dxCamera).Normalize();
                ray.RyDirection = (pCamera.ToVector3D() + _dyCamera).Normalize();
            }
            ray.Time   = PbrtMath.Lerp(sample.Time, ShutterOpen, ShutterClose);
            ray.Medium = Medium;
            ray        = new RayDifferential(CameraToWorld.ExecuteTransform(ray))
            {
                HasDifferentials = true
            };
            return(1.0);
        }
        /// <summary>
        /// Copy camera data from USD to Unity with the given import options.
        /// </summary>
        public static void BuildCamera(CameraSample usdCamera,
                                       GameObject go,
                                       SceneImportOptions options)
        {
            var cam = ImporterBase.GetOrAddComponent <Camera>(go);

            usdCamera.CopyToCamera(cam, setTransform: false);
            cam.nearClipPlane *= options.scale;
            cam.farClipPlane  *= options.scale;
        }
예제 #11
0
        void InitExportableObjects(GameObject go)
        {
            SampleBase     sample     = null;
            ExportFunction exportFunc = null;

            if (go.GetComponent <MeshFilter>() != null && go.GetComponent <MeshRenderer>() != null)
            {
                sample     = new MeshSample();
                exportFunc = ExportMesh;
                foreach (var mat in go.GetComponent <MeshRenderer>().materials)
                {
                    if (!m_materialMap.ContainsKey(mat))
                    {
                        string usdPath = "/World/Materials/" + pxr.UsdCs.TfMakeValidIdentifier(mat.name);
                        m_materialMap.Add(mat, usdPath);
                    }
                }
            }
            else if (go.GetComponent <Camera>())
            {
                sample     = new CameraSample();
                exportFunc = ExportCamera;
            }
            else
            {
                return;
            }

            // This is an exportable object.
            string path = Unity.UnityTypeConverter.GetPath(go.transform);

            m_primMap.Add(go, new ExportPlan {
                path = path, sample = sample, exportFunc = exportFunc
            });
            Debug.Log(path + " " + sample.GetType().Name);

            // Include the parent xform hierarchy.
            // Note that the parent hierarchy is memoised, so despite looking expensive, the time
            // complexity is linear.
            Transform xf = go.transform.parent;

            while (xf)
            {
                if (!InitExportableParents(xf.gameObject))
                {
                    break;
                }
                xf = xf.parent;
            }
        }
예제 #12
0
        public override void Splat(CameraSample sample, Spectrum l)
        {
            var xyz = l.ToXyz();
            int x = MathUtility.Floor(sample.ImageX), y = MathUtility.Floor(sample.ImageY);

            if (x < _xPixelStart || x - _xPixelStart >= _xPixelCount ||
                y < _yPixelStart || y - _yPixelStart >= _yPixelCount)
            {
                return;
            }
            var pixel = _pixels[x - _xPixelStart, y - _yPixelStart];

            AtomicAdd(ref pixel.SplatXyz[0], xyz[0]);
            AtomicAdd(ref pixel.SplatXyz[1], xyz[1]);
            AtomicAdd(ref pixel.SplatXyz[2], xyz[2]);
        }
예제 #13
0
        public static void CameraTest()
        {
            var scene = USD.NET.Scene.Create();
            var cam   = new CameraSample();

            cam.projection     = CameraSample.ProjectionType.Perspective;
            cam.clippingPlanes = new UnityEngine.Vector4[] {
                new UnityEngine.Vector4(0, 1, 2, 3),
                new UnityEngine.Vector4(4, 5, 6, 7)
            };
            cam.clippingRange            = new UnityEngine.Vector2(0.01f, 1000.0f);
            cam.focalLength              = 50;
            cam.focusDistance            = 1.0f;
            cam.fStop                    = 2.5f;
            cam.horizontalAperture       = 20.9550f;
            cam.horizontalApertureOffset = 0.001f;
            cam.stereoRole               = CameraSample.StereoRole.Mono;
            cam.verticalAperture         = 15.2908f;
            cam.verticalApertureOffset   = 0.002f;

            cam.shutter       = new CameraSample.Shutter();
            cam.shutter.open  = 0.001;
            cam.shutter.close = 0.002;

            // Prep a new camera sample to be populated.
            var cam2 = new CameraSample();

            cam2.shutter = new CameraSample.Shutter();

            UsdGeomTests.WriteAndRead(ref cam, ref cam2, true);

            AssertEqual(cam.clippingPlanes, cam2.clippingPlanes);
            AssertEqual(cam.clippingRange, cam2.clippingRange);
            AssertEqual(cam.focalLength, cam2.focalLength);
            AssertEqual(cam.focusDistance, cam2.focusDistance);
            AssertEqual(cam.fStop, cam2.fStop);
            AssertEqual(cam.horizontalAperture, cam2.horizontalAperture);
            AssertEqual(cam.horizontalApertureOffset, cam2.horizontalApertureOffset);
            AssertEqual(cam.projection, cam2.projection);
            AssertEqual(cam.shutter.open, cam2.shutter.open);
            AssertEqual(cam.shutter.close, cam2.shutter.close);
            AssertEqual(cam.stereoRole, cam2.stereoRole);
            AssertEqual(cam.verticalAperture, cam2.verticalAperture);
            AssertEqual(cam.verticalApertureOffset, cam2.verticalApertureOffset);
        }
예제 #14
0
        public static void CameraTest2()
        {
            CameraSample sample = new CameraSample();

            sample.transform     = UnityEngine.Matrix4x4.identity;
            sample.clippingRange = new UnityEngine.Vector2(.01f, 10);

            // GfCamera is a gold mine of camera math.
            pxr.GfCamera c = new pxr.GfCamera(UnityTypeConverter.ToGfMatrix(UnityEngine.Matrix4x4.identity));

            sample.focalLength        = c.GetFocalLength();
            sample.horizontalAperture = c.GetHorizontalAperture();
            sample.verticalAperture   = c.GetVerticalAperture();

            var scene = USD.NET.Scene.Create();

            scene.Write("/Foo/Bar", sample);
        }
예제 #15
0
        public override float GenerateRay(CameraSample sample, out Ray ray)
        {
            // Transform the film position from raster space to camera space
            var posFilm   = new Point3 <float>(sample.PosFilm.X, sample.PosFilm.Y, 0);
            var posCamera = RasterToCamera * posFilm;

            // Create a ray directed towards the camera's Z-axis
            ray = new Ray(posCamera, new Vector3 <float>(0, 0, 1));

            // TODO DoF

            //ray.time = ...
            //ray.medium = ...

            ray = CameraToWorld * ray;

            return(1);
        }
예제 #16
0
        public override float GenerateRay(CameraSample sample, out Ray ray)
        {
            // Transform the film position from raster space to camera space
            var posFilm   = new Point3 <float>(sample.PosFilm.X, sample.PosFilm.Y, 0);
            var posCamera = RasterToCamera * posFilm;

            // Create a ray coming from the center of the view
            ray = new RayDifferential(Point3 <float> .Zero, new Vector3 <float>(posCamera).Normalized());

            // TODO DoF

            //ray.time = ...
            //ray.medium = ...

            ray = CameraToWorld * ray;

            return(1);
        }
예제 #17
0
        public override float GenerateRayDifferential(CameraSample sample, out RayDifferential rayDiff)
        {
            // Transform the film position from raster space to camera space
            var posFilm   = new Point3 <float>(sample.PosFilm.X, sample.PosFilm.Y, 0);
            var posCamera = RasterToCamera * posFilm;

            // Create a ray directed towards the camera's Z-axis
            rayDiff     = new RayDifferential(posCamera, new Vector3 <float>(0, 0, 1));
            rayDiff.RxO = rayDiff.O + dxCamera;
            rayDiff.RyO = rayDiff.O + dyCamera;
            rayDiff.RxD = rayDiff.RyD = rayDiff.D;

            // TODO time, medium
            rayDiff.HasDifferentials = true;

            // Transform the ray from camera space to world space
            rayDiff = CameraToWorld * rayDiff;

            return(1);
        }
예제 #18
0
        public override float GenerateRayDifferential(CameraSample sample, out RayDifferential rayDiff)
        {
            // Transform the film position from raster space to camera space
            var posFilm   = new Point3 <float>(sample.PosFilm.X, sample.PosFilm.Y, 0);
            var posCamera = RasterToCamera * posFilm;

            // Create a ray coming from the center of the view
            rayDiff     = new RayDifferential(Point3 <float> .Zero, new Vector3 <float>(posCamera).Normalized());
            rayDiff.RxO = rayDiff.O + dxCamera;
            rayDiff.RyO = rayDiff.O + dyCamera;
            rayDiff.RxD = rayDiff.RyD = rayDiff.D;

            // TODO time, medium
            rayDiff.HasDifferentials = true;

            // Transform the ray from camera space to world space
            rayDiff = CameraToWorld * rayDiff;

            return(1);
        }
예제 #19
0
        public override void InitPath(IPathProcessor buffer)
        {
            base.InitPath(buffer);
            this.scene = pathIntegrator.Scene;
            this.Radiance = new RgbSpectrum(0f);
            this.Throughput = new RgbSpectrum(1f);
            this.PathState = PathTracerPathState.EyeVertex;
            if (this.secRays == null)
            {
                this.secRays = new ShadowRayInfo[scene.ShadowRaysPerSample];
                continueRays = new ShadowRayInfo[scene.ShadowRaysPerSample];
            }
            if (paths == null)
            {
                paths = new List<PathInfo>();
            }
            if (CurrentVertices == null)
            {
                CurrentVertices = new List<PathVertex>();
            }
            else
            {
                CurrentVertices.Clear();
            }

            contCount = 0;
            this.Sample = pathIntegrator.Sampler.GetSample(this.Sample);

            pathIntegrator.Scene.Camera.GetRay(Sample.imageX, Sample.imageY, out this.PathRay);
            this.EyeSample = new CameraSample()
            {
                imageX = (float)Sample.imageX,
                imageY = (float)Sample.imageY,
                EyeRay = this.PathRay
            };
            this.RayIndex = -1;
            this.pathWeight = 1.0f;
            this.tracedShadowRayCount = 0;
            this.depth = 0;
            this.specularBounce = true;
        }
예제 #20
0
파일: Camera.cs 프로젝트: merwaaan/pbrt
        public virtual float GenerateRayDifferential(CameraSample sample, out RayDifferential rayDiff)
        {
            rayDiff = null;

            Ray ray;
            var weight = GenerateRay(sample, out ray);

            // Compute the ray shifted on the X-axis
            var shiftedX = sample;

            shiftedX.PosFilm.X++;
            Ray rayX;
            var weightX = GenerateRay(shiftedX, out rayX);

            if (weightX == 0)
            {
                return(0);
            }
            rayDiff.RxO = rayX.O;
            rayDiff.RxD = rayX.D;

            // Compute the ray shifted on the Y-axis
            var shiftedY = sample;

            shiftedY.PosFilm.X--;
            shiftedY.PosFilm.Y++;
            Ray rayY;
            var weightY = GenerateRay(shiftedY, out rayY);

            if (weightY == 0)
            {
                return(0);
            }
            rayDiff.RyO = rayY.O;
            rayDiff.RyD = rayY.D;

            rayDiff.HasDifferentials = true;
            return(weight);
        }
예제 #21
0
        public static void ExportCamera(ObjectContext objContext, ExportContext exportContext)
        {
            UnityEngine.Profiling.Profiler.BeginSample("USD: Camera Conversion");

            CameraSample sample      = (CameraSample)objContext.sample;
            Camera       camera      = objContext.gameObject.GetComponent <Camera>();
            var          path        = objContext.path;
            var          scene       = exportContext.scene;
            bool         fastConvert = exportContext.basisTransform == BasisTransformation.FastWithNegativeScale;

            // If doing a fast conversion, do not let the constructor do the change of basis for us.
            sample.CopyFromCamera(camera, convertTransformToUsd: !fastConvert);

            if (fastConvert)
            {
                // Partial change of basis.
                var basisChange = Matrix4x4.identity;
                // Invert the forward vector.
                basisChange[2, 2] = -1;
                // Full change of basis would be b*t*b-1, but here we're placing only a single inversion
                // at the root of the hierarchy, so all we need to do is get the camera into the same
                // space.
                sample.transform = sample.transform * basisChange;

                // Is this also a root path?
                // If so the partial basis conversion must be completed on the camera itself.
                if (path.LastIndexOf("/") == 0)
                {
                    sample.transform = basisChange * sample.transform;
                }
            }

            UnityEngine.Profiling.Profiler.EndSample();

            UnityEngine.Profiling.Profiler.BeginSample("USD: Camera Write");
            scene.Write(path, sample);
            UnityEngine.Profiling.Profiler.EndSample();
        }
예제 #22
0
 public abstract float GenerateRay(CameraSample sample, out Ray ray);
예제 #23
0
        public override float GenerateRayDifferential(CameraSample sample, out RayDifferential ray)
        {
            Point3 Pras    = new Point3(sample.imageX, sample.imageY);
            Point3 Pcamera = RasterToCamera.Caculate(Pras);

            ray = new RayDifferential(Pcamera, new Vector(0, 0, 1), 0, 1.0f / 0);

            #region Modify ray for depth of field
            if (lensRadius > 0.0)
            {
                // Sample point on lens
                float lensU = 0, lensV = 0;
                LR.ConcentricSampleDisk(sample.lensU, sample.lensV, ref lensU, ref lensV);
                lensU *= lensRadius;
                lensV *= lensRadius;

                // Compute point on plane of focus
                float  ft     = focalDistance / ray.d.z;
                Point3 Pfocus = ray.Transfer(ft);

                // Update ray for effect of lens
                ray.o = new Point3(lensU, lensV, 0.0f);
                ray.d = LR.Normalize(Pfocus - ray.o);
            }
            #endregion
            ray.time = sample.time;

            #region Compute ray differentials for _OrthoCamera_
            if (lensRadius > 0)
            {
                // Compute _OrthoCamera_ ray differentials with defocus blur

                // Sample point on lens
                float lensU = 0, lensV = 0;
                LR.ConcentricSampleDisk(sample.lensU, sample.lensV, ref lensU, ref lensV);
                lensU *= lensRadius;
                lensV *= lensRadius;

                float ft = focalDistance / ray.d.z;

                Point3 pFocus = Pcamera + dxCamera + (ft * new Vector(0, 0, 1));
                ray.rxOrigin    = new Point3(lensU, lensV, 0.0f);
                ray.rxDirection = LR.Normalize(pFocus - ray.rxOrigin);

                pFocus          = Pcamera + dyCamera + (ft * new Vector(0, 0, 1));
                ray.ryOrigin    = new Point3(lensU, lensV, 0.0f);
                ray.ryDirection = LR.Normalize(pFocus - ray.ryOrigin);
            }
            else
            {
                ray.rxOrigin    = ray.o + dxCamera;
                ray.ryOrigin    = ray.o + dyCamera;
                ray.rxDirection = ray.ryDirection = ray.d;
            }
            #endregion

            ray.hasDifferentials = true;
            ray = CameraToWorld.Caculate(ray);

            return(1.0f);
        }
예제 #24
0
파일: Film.cs 프로젝트: MassVOiD/aether
 /// Updates the stored image with a given sample and corresponding radiance.
 /// The selected reconstruction filter will be applied.
 public abstract void AddSample(CameraSample sample, Spectrum l);
예제 #25
0
파일: Film.cs 프로젝트: MassVOiD/aether
 /// Updates the stored image. Splatted values are summed, rather than
 /// a weighted average as is the case with AddSample.
 public abstract void Splat(CameraSample sample, Spectrum l);
예제 #26
0
 public CameraSample GetCameraSample(float x, float y, IRandomProvider sampler)
 {
     var res = new CameraSample()
         {
             imageX = x,
             imageY = y,
         };
     if (sampler != null)
     {
         res.lensU = sampler.NextFloat();
         res.lensV = sampler.NextFloat();
         res.time = sampler.NextFloat();
     }
     IRay ray;
     this.Camera.GetRay(x, y, out ray);
     res.EyeRay = (RayData)ray;
     return res;
 }
예제 #27
0
        public override void AddSample(CameraSample sample, Spectrum l)
        {
            // Compute sample's raster extent
            float dimageX = sample.ImageX - 0.5f;
            float dimageY = sample.ImageY - 0.5f;
            int   x0      = MathUtility.Ceiling(dimageX - _filter.XWidth);
            int   x1      = MathUtility.Floor(dimageX + _filter.XWidth);
            int   y0      = MathUtility.Ceiling(dimageY - _filter.YWidth);
            int   y1      = MathUtility.Floor(dimageY + _filter.YWidth);

            x0 = Math.Max(x0, _xPixelStart);
            x1 = Math.Min(x1, _xPixelStart + _xPixelCount - 1);
            y0 = Math.Max(y0, _yPixelStart);
            y1 = Math.Min(y1, _yPixelStart + _yPixelCount - 1);
            if ((x1 - x0) < 0 || (y1 - y0) < 0)
            {
                return;
            }

            // Loop over filter support and add sample to pixel arrays
            var xyz = l.ToXyz();

            // Precompute $x$ and $y$ filter table offsets
            var ifx = new int[x1 - x0 + 1];

            for (int x = x0; x <= x1; ++x)
            {
                float fx = Math.Abs((x - dimageX) * _filter.InverseXWidth * FilterTableSize);
                ifx[x - x0] = Math.Min(MathUtility.Floor(fx), FilterTableSize - 1);
            }
            var ify = new int[y1 - y0 + 1];

            for (int y = y0; y <= y1; ++y)
            {
                float fy = Math.Abs((y - dimageY) * _filter.InverseYWidth * FilterTableSize);
                ify[y - y0] = Math.Min(MathUtility.Floor(fy), FilterTableSize - 1);
            }
            bool syncNeeded = (_filter.XWidth > 0.5f || _filter.YWidth > 0.5f);

            for (int y = y0; y <= y1; ++y)
            {
                for (int x = x0; x <= x1; ++x)
                {
                    // Evaluate filter value at $(x,y)$ pixel
                    int   offset   = ify[y - y0] * FilterTableSize + ifx[x - x0];
                    float filterWt = _filterTable[offset];

                    // Update pixel values with filtered sample contribution
                    var pixel = _pixels[x - _xPixelStart, y - _yPixelStart];
                    if (!syncNeeded)
                    {
                        pixel.Lxyz[0]   += filterWt * xyz[0];
                        pixel.Lxyz[1]   += filterWt * xyz[1];
                        pixel.Lxyz[2]   += filterWt * xyz[2];
                        pixel.WeightSum += filterWt;
                    }
                    else
                    {
                        // Safely update _Lxyz_ and _weightSum_ even with concurrency
                        AtomicAdd(ref pixel.Lxyz[0], filterWt * xyz[0]);
                        AtomicAdd(ref pixel.Lxyz[1], filterWt * xyz[1]);
                        AtomicAdd(ref pixel.Lxyz[2], filterWt * xyz[2]);
                        AtomicAdd(ref pixel.WeightSum, filterWt);
                    }
                }
            }
        }
예제 #28
0
 override public float GenerateRayDifferential(CameraSample sample, out RayDifferential ray)
 {
     // Generate raster and camera samples
     ray = new RayDifferential(new Point3(), new Vector());
     return(0.0f);
 }