/// <summary> /// Computes the change of area when mapping a direction from the hemisphere around the camera /// to the image. Given by our transformation to spherical coordinates, followed by the scaling to the /// desired resolution. /// </summary> /// <param name="pos">Position in world space of a point towards which the direction points</param> /// <returns> /// Jacobian determinant that describes how much larger an area on the image plane is than /// the corresponding solid angle. /// </returns> public override float SolidAngleToPixelJacobian(Vector3 pos) { var dir = Vector3.Normalize(pos - position); dir = Shading.ShadingSpace.WorldToShading(upVector, dir); float theta = SampleWarp.CartesianToSpherical(dir).Y; return(1 / (2 * MathF.PI * MathF.PI * MathF.Sin(theta)) * width * height); }
Vector3 WorldToFilm(Vector3 pos) { Debug.Assert(width != 0 && height != 0); var dir = pos - position; float distance = dir.Length(); dir = Shading.ShadingSpace.WorldToShading(upVector, dir / distance); var spherical = SampleWarp.CartesianToSpherical(dir); return(new( width * spherical.X / (2 * MathF.PI), height *spherical.Y / MathF.PI, distance )); }
public void SphericalInverse() { // Y axis var spherical = SampleWarp.CartesianToSpherical(Vector3.UnitY); var dir = SampleWarp.SphericalToCartesian(spherical); Assert.Equal(0, dir.X, 4); Assert.Equal(1, dir.Y, 4); Assert.Equal(0, dir.Z, 4); spherical = SampleWarp.CartesianToSpherical(-Vector3.UnitY); dir = SampleWarp.SphericalToCartesian(spherical); Assert.Equal(0, dir.X, 4); Assert.Equal(-1, dir.Y, 4); Assert.Equal(0, dir.Z, 4); // x axis spherical = SampleWarp.CartesianToSpherical(Vector3.UnitX); dir = SampleWarp.SphericalToCartesian(spherical); Assert.Equal(1, dir.X, 4); Assert.Equal(0, dir.Y, 4); Assert.Equal(0, dir.Z, 4); spherical = SampleWarp.CartesianToSpherical(-Vector3.UnitX); dir = SampleWarp.SphericalToCartesian(spherical); Assert.Equal(-1, dir.X, 4); Assert.Equal(0, dir.Y, 4); Assert.Equal(0, dir.Z, 4); // z axis spherical = SampleWarp.CartesianToSpherical(Vector3.UnitZ); dir = SampleWarp.SphericalToCartesian(spherical); Assert.Equal(0, dir.X, 4); Assert.Equal(0, dir.Y, 4); Assert.Equal(1, dir.Z, 4); spherical = SampleWarp.CartesianToSpherical(-Vector3.UnitZ); dir = SampleWarp.SphericalToCartesian(spherical); Assert.Equal(0, dir.X, 4); Assert.Equal(0, dir.Y, 4); Assert.Equal(-1, dir.Z, 4); }