Ejemplo n.º 1
0
        /*
         * Sets the shader uniforms that are necessary to project on screen the
         * TerrainQuad of the given TerrainNode. This method can set the uniforms
         * that are common to all the quads of the given terrain.
         */
        public virtual void SetUniforms(TerrainNode node, Material mat)
        {
            if (mat == null || node == null)
            {
                return;
            }

            float d1 = node.GetSplitDist() + 1.0f;
            float d2 = 2.0f * node.GetSplitDist();

            mat.SetVector(m_uniforms.blending, new Vector2(d1, d2 - d1));

            m_localToCamera = node.GetView().GetWorldToCamera() * node.GetLocalToWorld();
            m_localToScreen = node.GetView().GetCameraToScreen() * m_localToCamera;

            Vector3d2 localCameraPos = node.GetLocalCameraPos();
            Vector3d2 worldCamera    = node.GetView().GetWorldCameraPos();

            Matrix4x4d A = LocalToDeformedDifferential(localCameraPos);
            Matrix4x4d B = DeformedToTangentFrame(worldCamera);

            Matrix4x4d ltot = B * node.GetLocalToWorld() * A;

            m_localToTangent = new Matrix3x3d(ltot.m[0, 0], ltot.m[0, 1], ltot.m[0, 3],
                                              ltot.m[1, 0], ltot.m[1, 1], ltot.m[1, 3],
                                              ltot.m[3, 0], ltot.m[3, 1], ltot.m[3, 3]);

            mat.SetMatrix(m_uniforms.localToScreen, m_localToScreen.ToMatrix4x4());
            mat.SetMatrix(m_uniforms.localToWorld, node.GetLocalToWorld().ToMatrix4x4());
        }
Ejemplo n.º 2
0
        public static void Draw(Camera camera, Vector3d a, Vector3d b, Color color, Matrix4x4d localToWorld)
        {
            if (camera == null)
            {
                return;
            }
            m_vertices.Clear();

            m_vertices.Add(a.ToVector4());
            m_vertices.Add(b.ToVector4());

            DrawVertices(camera, m_vertices, color, localToWorld.ToMatrix4x4(), null);
        }
Ejemplo n.º 3
0
        public static void Draw(Camera camera, IEnumerable <Vector3d> vertices, Color color, Matrix4x4d localToWorld, IList <int> indices = null)
        {
            if (camera == null || vertices == null)
            {
                return;
            }
            m_vertices.Clear();

            foreach (var v in vertices)
            {
                m_vertices.Add(v.ToVector4());
            }

            DrawVertices(camera, m_vertices, color, localToWorld.ToMatrix4x4(), indices);
        }
Ejemplo n.º 4
0
        public static void Draw(Camera camera, IEnumerable <Vector3d> vertices, IEnumerable <Vector3d> normals, Color color, double length, Matrix4x4d localToWorld)
        {
            if (camera == null || vertices == null)
            {
                return;
            }
            m_vertices.Clear();
            m_normals.Clear();

            foreach (var v in vertices)
            {
                m_vertices.Add(v.ToVector4());
            }

            foreach (var n in normals)
            {
                m_normals.Add(n.ToVector4());
            }

            Draw(camera, color, m_vertices, m_normals, (float)length, localToWorld.ToMatrix4x4());
        }
Ejemplo n.º 5
0
        public virtual void SetUniforms(TerrainNode node, Material mat)
        {
            if (mat == null || node == null)
            {
                return;
            }

            var d1 = node.SplitDistance + 1.0f;
            var d2 = 2.0f * node.SplitDistance;

            localToCamera = GodManager.Instance.WorldToCamera * node.LocalToWorld;
            localToScreen = GodManager.Instance.CameraToScreen * localToCamera;

            var ltot = DeformedToTangentFrame(GodManager.Instance.WorldCameraPos) * node.LocalToWorld * LocalToDeformedDifferential(node.LocalCameraPosition);

            localToTangent = new Matrix3x3d(ltot.m[0, 0], ltot.m[0, 1], ltot.m[0, 3], ltot.m[1, 0], ltot.m[1, 1], ltot.m[1, 3], ltot.m[3, 0], ltot.m[3, 1], ltot.m[3, 3]);

            mat.SetVector(uniforms.blending, new Vector2(d1, d2 - d1));
            mat.SetMatrix(uniforms.localToScreen, localToScreen.ToMatrix4x4());
            mat.SetMatrix(uniforms.localToWorld, node.LocalToWorld.ToMatrix4x4());
        }
Ejemplo n.º 6
0
        public static void Draw(Camera camera, Vector2d a, Vector2d b, Color color, Matrix4x4d localToWorld)
        {
            if (camera == null)
            {
                return;
            }
            m_vertices.Clear();

            if (Orientation == DRAW_ORIENTATION.XY)
            {
                m_vertices.Add(a.xy01.ToVector4());
                m_vertices.Add(b.xy01.ToVector4());
            }
            else if (Orientation == DRAW_ORIENTATION.XZ)
            {
                m_vertices.Add(a.x0y1.ToVector4());
                m_vertices.Add(b.x0y1.ToVector4());
            }

            DrawVertices(camera, m_vertices, color, localToWorld.ToMatrix4x4(), null);
        }
Ejemplo n.º 7
0
        /*
         * Computes the world to camera matrix using double precision
         * and applies it to the camera.
         */
        protected virtual void SetWorldToCameraMatrix()
        {
            Vector3d2 po = new Vector3d2(m_position.x0, m_position.y0, 0.0);
            Vector3d2 px = new Vector3d2(1.0, 0.0, 0.0);
            Vector3d2 py = new Vector3d2(0.0, 1.0, 0.0);
            Vector3d2 pz = new Vector3d2(0.0, 0.0, 1.0);

            double ct = Math.Cos(m_position.theta);
            double st = Math.Sin(m_position.theta);
            double cp = Math.Cos(m_position.phi);
            double sp = Math.Sin(m_position.phi);

            Vector3d2 cx = px * cp + py * sp;
            Vector3d2 cy = (px * -1.0) * sp * ct + py * cp * ct + pz * st;
            Vector3d2 cz = px * sp * st - py * cp * st + pz * ct;

            m_worldPos = po + cz * m_position.distance;

            if (m_worldPos.z < m_groundHeight + 10.0)
            {
                m_worldPos.z = m_groundHeight + 10.0;
            }

            Matrix4x4d view = new Matrix4x4d(cx.x, cx.y, cx.z, 0.0,
                                             cy.x, cy.y, cy.z, 0.0,
                                             cz.x, cz.y, cz.z, 0.0,
                                             0.0, 0.0, 0.0, 1.0);

            m_worldToCameraMatrix = view * Matrix4x4d.Translate(m_worldPos * -1.0);

            m_worldToCameraMatrix.m[0, 0] *= -1.0;
            m_worldToCameraMatrix.m[0, 1] *= -1.0;
            m_worldToCameraMatrix.m[0, 2] *= -1.0;
            m_worldToCameraMatrix.m[0, 3] *= -1.0;

            m_cameraToWorldMatrix = m_worldToCameraMatrix.Inverse();

            camera.worldToCameraMatrix = m_worldToCameraMatrix.ToMatrix4x4();
            camera.transform.position  = m_worldPos.ToVector3();
        }
Ejemplo n.º 8
0
        public static void Draw(Camera camera, IEnumerable <Vector2d> vertices, Color color, Matrix4x4d localToWorld, IList <int> indices = null)
        {
            if (camera == null || vertices == null)
            {
                return;
            }
            m_vertices.Clear();

            foreach (var v in vertices)
            {
                if (Orientation == DRAW_ORIENTATION.XY)
                {
                    m_vertices.Add(v.xy01.ToVector4());
                }
                else if (Orientation == DRAW_ORIENTATION.XZ)
                {
                    m_vertices.Add(v.x0y1.ToVector4());
                }
            }

            DrawVertices(camera, m_vertices, color, localToWorld.ToMatrix4x4(), indices);
        }
Ejemplo n.º 9
0
        private IEnumerator CalculateViewsRoutine(Action <List <string>, Dictionary <int, Texture2D> > callback)
        {
            yield return(Yielders.EndOfFrame); // Finish previous frame...

            List <string> viewsLines = new List <string>();
            Dictionary <int, Texture2D> viewsBilboards = new Dictionary <int, Texture2D>();

            int total   = 2 * (N_VIEWS * N_VIEWS + N_VIEWS) + 1;
            int current = 0;

            double zmax = Math.Abs(Z);
            double zmin = -Math.Abs(Z);

            for (int i = -N_VIEWS; i <= N_VIEWS; i++)
            {
                for (int j = -N_VIEWS + Math.Abs(i); j <= N_VIEWS - Math.Abs(i); ++j)
                {
                    double x     = (i + j) / (double)N_VIEWS;
                    double y     = (j - i) / (double)N_VIEWS;
                    double angle = 90.0 - Math.Max(Math.Abs(x), Math.Abs(y)) * 90.0;
                    double alpha = x.EpsilonEquals(0.0, 0.00000001) && y.EpsilonEquals(0.0, 0.00000001) ? 0.0f : Math.Atan2(y, x) / Math.PI * 180.0;

                    Matrix4x4d cameraToWorld = Matrix4x4d.RotateX(90) * Matrix4x4d.RotateX(angle);
                    Matrix4x4d worldToCamera = cameraToWorld.Inverse();

                    Box3d b = new Box3d();
                    b = b.Enlarge((worldToCamera * new Vector4d(-1.0, -1.0, zmin, 1.0)).xyz);
                    b = b.Enlarge((worldToCamera * new Vector4d(+1.0, -1.0, zmin, 1.0)).xyz);
                    b = b.Enlarge((worldToCamera * new Vector4d(-1.0, +1.0, zmin, 1.0)).xyz);
                    b = b.Enlarge((worldToCamera * new Vector4d(+1.0, +1.0, zmin, 1.0)).xyz);
                    b = b.Enlarge((worldToCamera * new Vector4d(-1.0, -1.0, zmax, 1.0)).xyz);
                    b = b.Enlarge((worldToCamera * new Vector4d(+1.0, -1.0, zmax, 1.0)).xyz);
                    b = b.Enlarge((worldToCamera * new Vector4d(-1.0, +1.0, zmax, 1.0)).xyz);
                    b = b.Enlarge((worldToCamera * new Vector4d(+1.0, +1.0, zmax, 1.0)).xyz);

                    Matrix4x4d c2s = Matrix4x4d.Ortho(b.Max.x, b.Min.x, b.Max.y, b.Min.y, -2.0 * b.Max.z, -2.0 * b.Min.z + S);
                    Matrix4x4d w2s = c2s * worldToCamera * Matrix4x4d.RotateZ(-90 - alpha);

                    Vector3d dir = ((Matrix4x4d.RotateZ(90 + alpha) * cameraToWorld) * new Vector4d(0.0, 0.0, 1.0, 0.0)).xyz;

                    ViewMaterial.SetTexture("colorSampler", TreeSampler);
                    ViewMaterial.SetVector("dir", dir.ToVector3());
                    ViewMaterial.SetMatrix("worldToScreen", w2s.ToMatrix4x4());

                    Camera.main.projectionMatrix = w2s.ToMatrix4x4();

                    ViewMaterial.SetPass(0);
                    Graphics.DrawMeshNow(PreProcessMesh, Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one));

                    ViewMaterial.SetPass(1);
                    Graphics.DrawMeshNow(PreProcessMesh, Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one));

                    yield return(Yielders.EndOfFrame); // Finish this frame...

                    var texture = new Texture2D(GRIDRES_VIEWS, GRIDRES_VIEWS, TextureFormat.RGBAFloat, false, true);

                    texture.ReadPixels(new Rect(0, 0, GRIDRES_VIEWS, GRIDRES_VIEWS), 0, 0, false);
                    texture.Apply(false);

                    viewsBilboards.Add(current, texture);

                    var view = i * (1 - Math.Abs(i)) + j + 2 * N_VIEWS * i + N_VIEWS * (N_VIEWS + 1);

                    RTUtility.ClearColor(RenderTexture.active);

                    current++;

                    Debug.Log(string.Format("Precomputing Views Step {0} of {1} : View {2}", current, total, view));

                    viewsLines.Add(string.Format("{0}f,{1}f,{2}f,{3}f,{4}f,{5}f,{6}f,{7}f,{8}f,", (float)w2s.m[0, 0], (float)w2s.m[0, 1], (float)w2s.m[0, 2],
                                                 (float)w2s.m[1, 0], (float)w2s.m[1, 1], (float)w2s.m[1, 2],
                                                 (float)w2s.m[2, 0], (float)w2s.m[2, 1], (float)w2s.m[2, 2]));
                }
            }

            if (callback != null)
            {
                callback(viewsLines, viewsBilboards);
            }
        }
Ejemplo n.º 10
0
        public override void DoCreateTile(int level, int tx, int ty, List <TileStorage.Slot> slot)
        {
            var gpuSlot       = slot[0] as GPUTileStorage.GPUSlot;
            var elevationTile = ElevationProducer.FindTile(level, tx, ty, false, true);

            GPUTileStorage.GPUSlot elevationGpuSlot = null;

            if (elevationTile != null)
            {
                elevationGpuSlot = elevationTile.GetSlot(0) as GPUTileStorage.GPUSlot;
            }
            else
            {
                throw new MissingTileException("Find elevation tile failed");
            }

            if (gpuSlot == null)
            {
                throw new NullReferenceException("gpuSlot");
            }

            if (elevationGpuSlot == null)
            {
                throw new NullReferenceException("elevationGpuSlot");
            }

            var tileWidth    = gpuSlot.Owner.TileSize;
            var elevationTex = elevationGpuSlot.Texture;
            var elevationOSL = new Vector4(0.25f / (float)elevationTex.width, 0.25f / (float)elevationTex.height, 1.0f / (float)elevationTex.width, 0.0f);

            if (TerrainNode.Deformation.GetType() == typeof(DeformationSpherical))
            {
                var D = TerrainNode.TerrainQuadRoot.Length;
                var R = D / 2.0;

                var x0 = (double)(tx) / (double)(1 << level) * D - R;
                var x1 = (double)(tx + 1) / (double)(1 << level) * D - R;
                var y0 = (double)(ty) / (double)(1 << level) * D - R;
                var y1 = (double)(ty + 1) / (double)(1 << level) * D - R;

                var p0 = new Vector3d(x0, y0, R);
                var p1 = new Vector3d(x1, y0, R);
                var p2 = new Vector3d(x0, y1, R);
                var p3 = new Vector3d(x1, y1, R);
                var pc = new Vector3d((x0 + x1) * 0.5, (y0 + y1) * 0.5, R);

                double l0 = 0, l1 = 0, l2 = 0, l3 = 0;

                var v0 = p0.Normalized(ref l0);
                var v1 = p1.Normalized(ref l1);
                var v2 = p2.Normalized(ref l2);
                var v3 = p3.Normalized(ref l3);
                var vc = (v0 + v1 + v2 + v3) * 0.25;

                var deformedCorners = new Matrix4x4d(v0.x * R - vc.x * R,
                                                     v1.x * R - vc.x * R,
                                                     v2.x * R - vc.x * R,
                                                     v3.x * R - vc.x * R,
                                                     v0.y * R - vc.y * R,
                                                     v1.y * R - vc.y * R,
                                                     v2.y * R - vc.y * R,
                                                     v3.y * R - vc.y * R,
                                                     v0.z * R - vc.z * R,
                                                     v1.z * R - vc.z * R,
                                                     v2.z * R - vc.z * R,
                                                     v3.z * R - vc.z * R, 1.0, 1.0, 1.0, 1.0);

                var deformedVerticals = new Matrix4x4d(v0.x, v1.x, v2.x, v3.x, v0.y, v1.y, v2.y, v3.y, v0.z, v1.z, v2.z, v3.z, 0.0, 0.0, 0.0, 0.0);

                var uz = pc.Normalized();
                var ux = new Vector3d(0.0, 1.0, 0.0).Cross(uz).Normalized();
                var uy = uz.Cross(ux);

                var worldToTangentFrame = new Matrix4x4d(ux.x, ux.y, ux.z, 0.0, uy.x, uy.y, uy.z, 0.0, uz.x, uz.y, uz.z, 0.0, 0.0, 0.0, 0.0, 0.0);

                NormalsMaterial.SetMatrix("_PatchCorners", deformedCorners.ToMatrix4x4());
                NormalsMaterial.SetMatrix("_PatchVerticals", deformedVerticals.ToMatrix4x4());
                NormalsMaterial.SetVector("_PatchCornerNorms", new Vector4((float)l0, (float)l1, (float)l2, (float)l3));
                NormalsMaterial.SetVector("_Deform", new Vector4((float)x0, (float)y0, (float)D / (float)(1 << level), (float)R));
                NormalsMaterial.SetMatrix("_WorldToTangentFrame", worldToTangentFrame.ToMatrix4x4());
            }
            else
            {
                var D  = TerrainNode.TerrainQuadRoot.Length;
                var R  = D / 2.0;
                var x0 = (double)tx / (double)(1 << level) * D - R;
                var y0 = (double)ty / (double)(1 << level) * D - R;

                NormalsMaterial.SetVector("_Deform", new Vector4((float)x0, (float)y0, (float)D / (float)(1 << level), 0.0f));
                NormalsMaterial.SetMatrix("_WorldToTangentFrame", Matrix4x4.identity);
            }

            NormalsMaterial.SetVector("_TileSD", new Vector2((float)tileWidth, (float)(tileWidth - 1) / (float)(TerrainNode.Body.GridResolution - 1)));
            NormalsMaterial.SetTexture("_ElevationSampler", elevationTex);
            NormalsMaterial.SetVector("_ElevationOSL", elevationOSL);

            Graphics.Blit(null, gpuSlot.Texture, NormalsMaterial);

            base.DoCreateTile(level, tx, ty, slot);
        }
Ejemplo n.º 11
0
        public void UpdateMatrices()
        {
            var worldToLocal = new Matrix4x4d(1.0, 0.0, 0.0, -Origin.x,
                                              0.0, 1.0, 0.0, -Origin.y,
                                              0.0, 0.0, 1.0, -Origin.z,
                                              0.0, 0.0, 0.0, 1.0);
            var cameraToLocal = worldToLocal * CameraToWorld;
            var localToCamera = cameraToLocal.Inverse();
            var oceanFrame    = cameraToLocal * Vector3d.zero;
            var radius        = ParentBody.Size;

            uz = oceanFrame.Normalized();

            ux = OldLocalToOcean != Matrix4x4d.identity ? new Vector3d(OldLocalToOcean.m[1, 0], OldLocalToOcean.m[1, 1], OldLocalToOcean.m[1, 2]).Cross(uz).Normalized() :
                 Vector3d.forward.Cross(uz).Normalized();

            uy = uz.Cross(ux);
            oo = (uz * radius);

            var localToOcean = new Matrix4x4d(ux.x, ux.y, ux.z, -ux.Dot(oo),
                                              uy.x, uy.y, uy.z, -uy.Dot(oo),
                                              uz.x, uz.y, uz.z, -uz.Dot(oo),
                                              0.0, 0.0, 0.0, 1.0);
            var cameraToOcean = localToOcean * cameraToLocal;

            //var worldToOcean = localToOcean * worldToLocal;

            if (OldLocalToOcean != Matrix4x4d.identity)
            {
                var delta = localToOcean * (OldLocalToOcean.Inverse() * Vector3d.zero);

                Offset += VectorHelper.MakeFrom(delta, 0.0f);
            }

            if (Mathf.Max(Mathf.Abs(Offset.x), Mathf.Abs(Offset.y)) > 20000.0f)
            {
                Offset.x = 0.0f;
                Offset.y = 0.0f;
            }

            OldLocalToOcean = localToOcean;

            var oc = cameraToOcean * Vector3d.zero;

            H = oc.z;

            if (double.IsNaN(H))
            {
                H = 1.0;
            }

            var offset = new Vector3d(-Offset.x, -Offset.y, H);

            // TODO : Up to four light sources support...
            var sun          = ParentBody.Suns.FirstOrDefault();
            var sunDirection = sun != null?ParentBody.GetSunDirection(sun) : Vector3.zero;

            var oceanSunDirection = localToOcean.ToMatrix3x3d() * sunDirection;

            var sphereDirection = (localToCamera * Vector3d.zero).Normalized();   // Direction to center of planet
            var OHL             = (localToCamera * Vector3d.zero).Magnitude();    // Distance to center of planet
            var rHorizon        = Math.Sqrt(OHL * OHL - radius * radius);         // Distance to the horizon, i.e distance to ocean sphere tangent

            // Theta equals angle to horizon, now all that is left to do is check the view direction against this angle
            var cosTheta            = rHorizon / OHL;
            var sinTheta            = Math.Sqrt(1.0 - cosTheta * cosTheta);
            var oceanGridResolution = GodManager.Instance.OceanGridResolution;

            OceanMaterial.SetVector("_SphereDirection", sphereDirection.ToVector3());
            OceanMaterial.SetFloat("_CosTheta", (float)cosTheta);
            OceanMaterial.SetFloat("_SinTheta", (float)sinTheta);

            OceanMaterial.SetVector("_Ocean_SunDir", oceanSunDirection.ToVector3());
            OceanMaterial.SetMatrix("_Ocean_CameraToOcean", cameraToOcean.ToMatrix4x4());
            OceanMaterial.SetMatrix("_Ocean_OceanToCamera", cameraToOcean.Inverse().ToMatrix4x4());
            OceanMaterial.SetMatrix("_Ocean_WorldToLocal", worldToLocal.ToMatrix4x4());
            OceanMaterial.SetMatrix("_Ocean_LocalToOcean", localToOcean.ToMatrix4x4());
            OceanMaterial.SetVector("_Ocean_CameraPos", offset.ToVector3());
            OceanMaterial.SetVector("_Ocean_Color", UpwellingColor * 0.1f);
            OceanMaterial.SetVector("_Ocean_ScreenGridSize", new Vector2((float)oceanGridResolution / (float)Screen.width, (float)oceanGridResolution / (float)Screen.height));
            OceanMaterial.SetFloat("_Ocean_Radius", radius);
            OceanMaterial.SetFloat("_Ocean_Wave_Level", OceanWaveLevel);

            // TODO : Complete ocean matrices calculation for a cyllindrical worlds...
        }
Ejemplo n.º 12
0
        public void updateCameraSpecificUniforms(Material oceanMaterial, Camera inCamera)
        {
            cameraToScreen = GL.GetGPUProjectionMatrix(inCamera.projectionMatrix, false);
            screenToCamera = cameraToScreen.inverse;

            m_oceanMaterial.SetMatrix("_Globals_CameraToScreen", cameraToScreen);
            m_oceanMaterial.SetMatrix("_Globals_ScreenToCamera", screenToCamera);


            //Calculates the required data for the projected grid

            // compute ltoo = localToOcean transform, where ocean frame = tangent space at
            // camera projection on sphere radius in local space

            //move these to dedicated projected grid class?

            Matrix4x4 ctol1 = inCamera.cameraToWorldMatrix;

            Matrix4x4d cameraToWorld = new Matrix4x4d(ctol1.m00, ctol1.m01, ctol1.m02, ctol1.m03,
                                                      ctol1.m10, ctol1.m11, ctol1.m12, ctol1.m13,
                                                      ctol1.m20, ctol1.m21, ctol1.m22, ctol1.m23,
                                                      ctol1.m30, ctol1.m31, ctol1.m32, ctol1.m33);

            Vector3d translation = m_manager.parentLocalTransform.position;


            Matrix4x4d worldToLocal = new Matrix4x4d(1, 0, 0, -translation.x,
                                                     0, 1, 0, -translation.y,
                                                     0, 0, 1, -translation.z,
                                                     0, 0, 0, 1);

            Matrix4x4d camToLocal = worldToLocal * cameraToWorld;
            Matrix4x4d localToCam = camToLocal.Inverse();

            // camera in local space relative to planet's origin
            Vector3d2 cl = new Vector3d2();

            cl = camToLocal * Vector3d2.Zero();

            double radius = m_manager.GetRadius();

            uz = cl.Normalized();              // unit z vector of ocean frame, in local space

            if (m_oldlocalToOcean != Matrix4x4d.Identity())
            {
                ux = (new Vector3d2(m_oldlocalToOcean.m [1, 0], m_oldlocalToOcean.m [1, 1], m_oldlocalToOcean.m [1, 2])).Cross(uz).Normalized();
            }
            else
            {
                ux = Vector3d2.UnitZ().Cross(uz).Normalized();
            }

            uy = uz.Cross(ux);              // unit y vector

            oo = uz * (radius);             // origin of ocean frame, in local space

            //local to ocean transform
            //computed from oo and ux, uy, uz should be correct
            Matrix4x4d localToOcean = new Matrix4x4d(
                ux.x, ux.y, ux.z, -ux.Dot(oo),
                uy.x, uy.y, uy.z, -uy.Dot(oo),
                uz.x, uz.y, uz.z, -uz.Dot(oo),
                0.0, 0.0, 0.0, 1.0);

            Matrix4x4d cameraToOcean = localToOcean * camToLocal;
            Matrix4x4d worldToOcean  = localToOcean * worldToLocal;

            Vector3d2 delta = new Vector3d2(0, 0, 0);

            if (m_oldlocalToOcean != Matrix4x4d.Identity())
            {
                delta     = localToOcean * (m_oldlocalToOcean.Inverse() * Vector3d2.Zero());
                m_offset += delta;
            }

            //reset offset when bigger than 20000 to  avoid floating point issues when later casting the offset to float
            if (Mathf.Max(Mathf.Abs((float)m_offset.x), Mathf.Abs((float)m_offset.y)) > 20000f)
            {
                m_offset.x = 0.0;
                m_offset.y = 0.0;
            }

            m_oldlocalToOcean = localToOcean;

//			Matrix4x4d ctos = ModifiedProjectionMatrix (inCamera); //moved to command buffer
//			Matrix4x4d stoc = ctos.Inverse ();

            Vector3d2 oc = cameraToOcean * Vector3d2.Zero();

            h = oc.z;

            offset = new Vector3d2(-m_offset.x, -m_offset.y, h);

            //old horizon code
            //This breaks down when you tilt the camera by 90 degrees in any direction
            //I made some new horizon code down, scroll down

//			Vector4d stoc_w = (stoc * Vector4d.UnitW ()).XYZ0 ();
//			Vector4d stoc_x = (stoc * Vector4d.UnitX ()).XYZ0 ();
//			Vector4d stoc_y = (stoc * Vector4d.UnitY ()).XYZ0 ();
//
//			Vector3d2 A0 = (cameraToOcean * stoc_w).XYZ ();
//			Vector3d2 dA = (cameraToOcean * stoc_x).XYZ ();
//			Vector3d2 B = (cameraToOcean * stoc_y).XYZ ();
//
//			Vector3d2 horizon1, horizon2;
//
//			double h1 = h * (h + 2.0 * radius);
//			double h2 = (h + radius) * (h + radius);
//			double alpha = B.Dot (B) * h1 - B.z * B.z * h2;
//
//			double beta0 = (A0.Dot (B) * h1 - B.z * A0.z * h2) / alpha;
//			double beta1 = (dA.Dot (B) * h1 - B.z * dA.z * h2) / alpha;
//
//			double gamma0 = (A0.Dot (A0) * h1 - A0.z * A0.z * h2) / alpha;
//			double gamma1 = (A0.Dot (dA) * h1 - A0.z * dA.z * h2) / alpha;
//			double gamma2 = (dA.Dot (dA) * h1 - dA.z * dA.z * h2) / alpha;
//
//			horizon1 = new Vector3d2 (-beta0, -beta1, 0.0);
//			horizon2 = new Vector3d2 (beta0 * beta0 - gamma0, 2.0 * (beta0 * beta1 - gamma1), beta1 * beta1 - gamma2);

            Vector3d2 sunDir      = new Vector3d2(m_manager.getDirectionToSun().normalized);
            Vector3d2 oceanSunDir = localToOcean.ToMatrix3x3d() * sunDir;

            oceanMaterial.SetMatrix(ShaderProperties._Globals_CameraToWorld_PROPERTY, cameraToWorld.ToMatrix4x4());

            oceanMaterial.SetVector(ShaderProperties._Ocean_SunDir_PROPERTY, oceanSunDir.ToVector3());

            oceanMaterial.SetMatrix(ShaderProperties._Ocean_CameraToOcean_PROPERTY, cameraToOcean.ToMatrix4x4());
            oceanMaterial.SetMatrix(ShaderProperties._Ocean_OceanToCamera_PROPERTY, cameraToOcean.Inverse().ToMatrix4x4());

//			oceanMaterial.SetMatrix (ShaderProperties._Globals_CameraToScreen_PROPERTY, ctos.ToMatrix4x4 ());
//			oceanMaterial.SetMatrix (ShaderProperties._Globals_ScreenToCamera_PROPERTY, stoc.ToMatrix4x4 ());

            oceanMaterial.SetMatrix(ShaderProperties._Globals_WorldToOcean_PROPERTY, worldToOcean.ToMatrix4x4());
            oceanMaterial.SetMatrix(ShaderProperties._Globals_OceanToWorld_PROPERTY, worldToOcean.Inverse().ToMatrix4x4());

            oceanMaterial.SetVector(ShaderProperties._Ocean_CameraPos_PROPERTY, offset.ToVector3());

            //horizon calculations
            //these are used to find where the horizon line is on screen
            //and "clamp" vertexes that are above it back to it
            //as the grid is projected on the whole screen, vertexes over the horizon need to be dealt with
            //simply passing a flag to drop fragments or moving these vertexes offscreen will cause issues
            //as the horizon line can be between two vertexes and the horizon line will appear "pixelated"
            //as whole chunks go missing

            //these need to be done here
            //1)for double precision
            //2)for speed

            Vector3d2 sphereDir = localToCam * Vector3d2.Zero();             //vector to center of planet
            double    OHL       = sphereDir.Magnitude();                     //distance to center of planet

            sphereDir = sphereDir.Normalized();                              //direction to center of planet

            double rHorizon = Math.Sqrt((OHL)*(OHL)-(radius * radius));      //distance to the horizon, i.e distance to ocean sphere tangent
            //basic geometry yo

            //Theta=angle to horizon, now all that is left to do is check the viewdir against this angle in the shader
            double cosTheta = rHorizon / (OHL);
            double sinTheta = Math.Sqrt(1 - cosTheta * cosTheta);

            oceanMaterial.SetVector(ShaderProperties.sphereDir_PROPERTY, sphereDir.ToVector3());
            oceanMaterial.SetFloat(ShaderProperties.cosTheta_PROPERTY, (float)cosTheta);
            oceanMaterial.SetFloat(ShaderProperties.sinTheta_PROPERTY, (float)sinTheta);

            //planetshine properties
            if (Scatterer.Instance.mainSettings.usePlanetShine)
            {
                Matrix4x4 planetShineSourcesMatrix = m_manager.m_skyNode.planetShineSourcesMatrix;

                Vector3d2 oceanSunDir2;
                for (int i = 0; i < 4; i++)
                {
                    Vector4 row = planetShineSourcesMatrix.GetRow(i);
                    oceanSunDir2 = localToOcean.ToMatrix3x3d() * new Vector3d2(row.x, row.y, row.z);
                    planetShineSourcesMatrix.SetRow(i, new Vector4((float)oceanSunDir2.x, (float)oceanSunDir2.y, (float)oceanSunDir2.z, row.w));
                }
                oceanMaterial.SetMatrix("planetShineSources", planetShineSourcesMatrix);                  //this can become shared code to not recompute

                oceanMaterial.SetMatrix("planetShineRGB", m_manager.m_skyNode.planetShineRGBMatrix);
            }

            if (!ReferenceEquals(causticsShadowMaskModulator, null))
            {
                causticsShadowMaskModulator.CausticsShadowMaskModulateMaterial.SetMatrix("CameraToWorld", inCamera.cameraToWorldMatrix);
                causticsShadowMaskModulator.CausticsShadowMaskModulateMaterial.SetMatrix("WorldToLight", Scatterer.Instance.sunLight.transform.worldToLocalMatrix);
                causticsShadowMaskModulator.CausticsShadowMaskModulateMaterial.SetVector("PlanetOrigin", m_manager.parentLocalTransform.position);

                float warpTime = (TimeWarp.CurrentRate > 1) ? (float)Planetarium.GetUniversalTime() : 0f;
                causticsShadowMaskModulator.CausticsShadowMaskModulateMaterial.SetFloat("warpTime", warpTime);
            }
        }
Ejemplo n.º 13
0
        /*
        * Computes the world to camera matrix using double precision
        * and applies it to the camera.
        */
        protected virtual void SetWorldToCameraMatrix()
        {
            Vector3d2 po = new Vector3d2(m_position.x0, m_position.y0, 0.0);
            Vector3d2 px = new Vector3d2(1.0, 0.0, 0.0);
            Vector3d2 py = new Vector3d2(0.0, 1.0, 0.0);
            Vector3d2 pz = new Vector3d2(0.0, 0.0, 1.0);

            double ct = Math.Cos(m_position.theta);
            double st = Math.Sin(m_position.theta);
            double cp = Math.Cos(m_position.phi);
            double sp = Math.Sin(m_position.phi);

            Vector3d2 cx = px * cp + py * sp;
            Vector3d2 cy = (px*-1.0) * sp*ct + py * cp*ct + pz * st;
            Vector3d2 cz = px * sp*st - py * cp*st + pz * ct;

            m_worldPos = po + cz * m_position.distance;

            if (m_worldPos.z < m_groundHeight + 10.0) {
                m_worldPos.z = m_groundHeight + 10.0;
            }

            Matrix4x4d view = new Matrix4x4d(	cx.x, cx.y, cx.z, 0.0,
                                                cy.x, cy.y, cy.z, 0.0,
                                                cz.x, cz.y, cz.z, 0.0,
                                                0.0, 0.0, 0.0, 1.0);

            m_worldToCameraMatrix = view * Matrix4x4d.Translate(m_worldPos * -1.0);

            m_worldToCameraMatrix.m[0,0] *= -1.0;
            m_worldToCameraMatrix.m[0,1] *= -1.0;
            m_worldToCameraMatrix.m[0,2] *= -1.0;
            m_worldToCameraMatrix.m[0,3] *= -1.0;

            m_cameraToWorldMatrix = m_worldToCameraMatrix.Inverse();

            camera.worldToCameraMatrix = m_worldToCameraMatrix.ToMatrix4x4();
            camera.transform.position = m_worldPos.ToVector3();
        }
Ejemplo n.º 14
0
        /**
        * Sets the shader uniforms that are necessary to project on screen the
        * TerrainQuad of the given TerrainNode. This method can set the uniforms
        * that are common to all the quads of the given terrain.
        */
        public virtual void SetUniforms(TerrainNode node, Material mat)
        {
            if(mat == null || node == null) return;

            float d1 = node.GetSplitDist() + 1.0f;
            float d2 = 2.0f * node.GetSplitDist();
            mat.SetVector(m_uniforms.blending, new Vector2(d1, d2 - d1));

            m_localToCamera = node.GetView().GetWorldToCamera() * node.GetLocalToWorld();
            m_localToScreen = node.GetView().GetCameraToScreen() * m_localToCamera;

            Vector3d2 localCameraPos = node.GetLocalCameraPos();
            Vector3d2 worldCamera = node.GetView().GetWorldCameraPos();

            Matrix4x4d A = LocalToDeformedDifferential(localCameraPos);
            Matrix4x4d B = DeformedToTangentFrame(worldCamera);

            Matrix4x4d ltot = B * node.GetLocalToWorld() * A;

            m_localToTangent = new Matrix3x3d(	ltot.m[0,0], ltot.m[0,1], ltot.m[0,3],
                                              ltot.m[1,0], ltot.m[1,1], ltot.m[1,3],
                                              ltot.m[3,0], ltot.m[3,1], ltot.m[3,3]);

            mat.SetMatrix(m_uniforms.localToScreen, m_localToScreen.ToMatrix4x4());
            mat.SetMatrix(m_uniforms.localToWorld, node.GetLocalToWorld().ToMatrix4x4());
        }
Ejemplo n.º 15
0
        public void SetUniforms(Material mat)
        {
            //Sets uniforms that this or other gameobjects may need
            if (mat == null) return;

            mat.SetFloat("_Extinction_Cutoff", ExtinctionCutoff);
            if (!MapView.MapIsEnabled) {
            mat.SetFloat("_Alpha_Global", alphaGlobal);
            mat.SetFloat("_Extinction_Tint", extinctionTint);
            mat.SetFloat("extinctionMultiplier", extinctionMultiplier);
            } else {
            mat.SetFloat("_Alpha_Global", mapAlphaGlobal);
            mat.SetFloat("_Extinction_Tint", mapExtinctionTint);
            mat.SetFloat("extinctionMultiplier", mapExtinctionMultiplier);
            }

            mat.SetFloat("scale", atmosphereGlobalScale);
            mat.SetFloat("Rg", Rg * atmosphereGlobalScale);
            mat.SetFloat("Rt", Rt * atmosphereGlobalScale);
            mat.SetFloat("RL", RL * atmosphereGlobalScale);

            //						if (debugSettings [5])
            if (!MapView.MapIsEnabled) {
            mat.SetFloat("_Globals_ApparentDistance", 1f);
            } else {
            mat.SetFloat("_Globals_ApparentDistance", (float)((parentCelestialBody.Radius / 100.2f) / MapViewScale));
            //				mat.SetFloat ("_Globals_ApparentDistance", MapViewScale);
            }

            //						if (debugSettings[1])
            if (!MapView.MapIsEnabled) {

            mat.SetMatrix("_Globals_WorldToCamera", farCamera.worldToCameraMatrix);
            mat.SetMatrix("_Globals_CameraToWorld", farCamera.worldToCameraMatrix.inverse);
            } else {
            mat.SetMatrix("_Globals_WorldToCamera", scaledSpaceCamera.worldToCameraMatrix);
            mat.SetMatrix("_Globals_CameraToWorld", scaledSpaceCamera.worldToCameraMatrix.inverse);
            }

            mat.SetVector("betaR", m_betaR / 1000.0f);
            mat.SetFloat("mieG", Mathf.Clamp(m_mieG, 0.0f, 0.99f));
            mat.SetTexture("_Sky_Transmittance", m_transmit);
            mat.SetTexture("_Sky_Inscatter", m_inscatter);
            mat.SetTexture("_Sky_Irradiance", m_irradiance);
            mat.SetFloat("_Sun_Intensity", 100f);
            mat.SetVector("_Sun_WorldSunDir", m_manager.getDirectionToSun().normalized);
            //			mat.SetVector("_Sun_WorldSunDir", m_manager.getDirectionToSun());

            //			//copied from m_manager's set uniforms

            //Matrix4x4 p;
            //						if (debugSettings [2])
            if (!MapView.MapIsEnabled) {
            p = farCamera.projectionMatrix;
            } else {
            p = scaledSpaceCamera.projectionMatrix;
            }

            m_cameraToScreenMatrix = new Matrix4x4d(p);
            mat.SetMatrix("_Globals_CameraToScreen", m_cameraToScreenMatrix.ToMatrix4x4());
            mat.SetMatrix("_Globals_ScreenToCamera", m_cameraToScreenMatrix.Inverse().ToMatrix4x4());

            //						if (debugSettings [3])
            if (!MapView.MapIsEnabled) {
            mat.SetVector("_Globals_WorldCameraPos", farCamera.transform.position);
            } else {
            mat.SetVector("_Globals_WorldCameraPos", scaledSpaceCamera.transform.position);
            }
            //			else
            //			{
            //				Vector3 newpos= ScaledSpace.ScaledToLocalSpace(scaledSpaceCamera.transform.position);
            //				//				m_skyMaterial.SetVector ("_Globals_WorldCameraPos", scaledSpaceCamera.transform.position);
            //				mat.SetVector ("_Globals_WorldCameraPos", newpos);
            //			}
            //
            //						if (debugSettings [4])
            if (!MapView.MapIsEnabled) {
            mat.SetVector("_Globals_Origin", parentCelestialBody.transform.position);

            } else {

            //				celestialTransform = ScaledSpace.Instance.scaledSpaceTransforms.Single(t => t.name == parentCelestialBody.name);
            celestialTransform = ParentPlanetTransform;
            //				idek =celestialTransform.position;
            idek = celestialTransform.position - scaledSpaceCamera.transform.position;
            mat.SetVector("_Globals_Origin", idek);

            }

            if (!MapView.MapIsEnabled) {
            mat.SetFloat("_Exposure", m_HDRExposure);
            } else {
            mat.SetFloat("_Exposure", mapExposure);
            }

            //			int childCnt = 0;
            //			Transform scaledSunTransform=ScaledSpace.Instance.scaledSpaceTransforms.Single(t => t.name == "Sun");
            //			foreach (Transform child in scaledSunTransform)
            //			{
            //				print(childCnt);
            //				print(child.gameObject.name);
            //				childCnt++;
            //				MeshRenderer temp;
            //				temp = child.gameObject.GetComponent<MeshRenderer>();
            ////				temp.enabled=false;
            //				print(temp.enabled);
            //			}
        }
Ejemplo n.º 16
0
        void UpdatePostProcessMaterial(Material mat)
        {
            //mat.SetFloat ("atmosphereGlobalScale", atmosphereGlobalScale);
            //			mat.SetFloat ("Rg", Rg*atmosphereGlobalScale*postProcessingScale);
            //			mat.SetFloat("Rt", Rt*atmosphereGlobalScale*postProcessingScale);
            //			mat.SetFloat("Rl", RL*atmosphereGlobalScale*postProcessingScale);

            totalscale = 1;
            totalscale2 = 1;
            for (int j = 0; j < 5; j++) {
            totalscale = totalscale * additionalScales[j];
            }

            for (int j = 6; j < 10; j++) {
            totalscale2 = totalscale2 * additionalScales[j];
            }

            mat.SetFloat("Rg", Rg * atmosphereGlobalScale * totalscale);
            mat.SetFloat("Rt", Rt * atmosphereGlobalScale * totalscale);
            mat.SetFloat("Rl", RL * atmosphereGlobalScale * totalscale);

            //mat.SetFloat("_inscatteringCoeff", inscatteringCoeff);
            mat.SetFloat("_extinctionCoeff", extinctionCoeff);
            mat.SetFloat("_global_alpha", postProcessingAlpha);
            mat.SetFloat("_Exposure", postProcessExposure);
            mat.SetFloat("_global_depth", postProcessDepth);
            mat.SetFloat("_global_depth2", totalscale2);

            mat.SetFloat("terrain_reflectance", terrainReflectance);
            mat.SetFloat("_irradianceFactor", irradianceFactor);

            mat.SetFloat("_Scale", postProcessingScale);
            //			mat.SetFloat("_Scale", 1);

            mat.SetFloat("_Ocean_Sigma", oceanSigma);
            mat.SetFloat("_Ocean_Threshold", _Ocean_Threshold);

            //			mat.SetMatrix ("_Globals_CameraToWorld", cams [0].worldToCameraMatrix.inverse);
            if (debugSettings[1]) {
            mat.SetMatrix("_Globals_CameraToWorld", farCamera.worldToCameraMatrix.inverse);
            } else {
            mat.SetMatrix("_Globals_CameraToWorld", scaledSpaceCamera.worldToCameraMatrix.inverse);
            }

            if (debugSettings[2]) {
            mat.SetVector("_CameraForwardDirection", farCamera.transform.forward);
            } else {
            mat.SetVector("_CameraForwardDirection", scaledSpaceCamera.transform.forward);
            }

            if (debugSettings[3]) {
            mat.SetVector("_Globals_Origin", /*Vector3.zero-*/ parentCelestialBody.transform.position);
            } else

            {

            //				celestialTransform = ScaledSpace.Instance.scaledSpaceTransforms.Single(t => t.name == parentCelestialBody.name);
            celestialTransform = ParentPlanetTransform;
            idek = celestialTransform.position;
            mat.SetVector("_Globals_Origin", /*Vector3.zero-*/ idek);
            }

            //mat.SetVector("betaR", m_betaR / (Rg / m_radius));
            //			mat.SetVector("betaR", m_betaR / (postProcessDepth));
            mat.SetVector("betaR", new Vector4(2.9e-3f, 0.675e-2f, 1.655e-2f, 0.0f));
            mat.SetFloat("mieG", 0.4f);
            mat.SetVector("SUN_DIR", m_manager.GetSunNodeDirection());
            mat.SetFloat("SUN_INTENSITY", sunIntensity);

            Matrix4x4 ctol1 = farCamera.cameraToWorldMatrix;
            Vector3d tmp = (farCamera.transform.position) - m_manager.parentCelestialBody.transform.position;

            Matrix4x4d viewMat = new Matrix4x4d(ctol1.m00, ctol1.m01, ctol1.m02, tmp.x,
                                            ctol1.m10, ctol1.m11, ctol1.m12, tmp.y,
                                            ctol1.m20, ctol1.m21, ctol1.m22, tmp.z,
                                            ctol1.m30, ctol1.m31, ctol1.m32, ctol1.m33);

            //			print ("viewmat");
            //			print (viewMat.ToMatrix4x4());

            //			Matrix4x4 viewMat = farCamera.worldToCameraMatrix;
            viewMat = viewMat.Inverse();
            Matrix4x4 projMat = GL.GetGPUProjectionMatrix(farCamera.projectionMatrix, false);

            //			projMat.m23 = projMat.m23 * 0.5f;

            //			print ("projmat");
            //			print (projMat);

            Matrix4x4 viewProjMat = (projMat * viewMat.ToMatrix4x4());
            mat.SetMatrix("_ViewProjInv", viewProjMat.inverse);

            //			mat.SetMatrix("_ViewToWorld", viewMat.ToMatrix4x4());
            //
            //			var lpoints = RecalculateFrustrumPoints(farCamera);
            //			mat.SetVector("_FrustrumPoints", new Vector4(
            //				lpoints[4].x,lpoints[5].x,lpoints[5].y,lpoints[6].y));
            //
            //			mat.SetFloat("_CameraFar", farCamera.farClipPlane);
        }
Ejemplo n.º 17
0
        public void updateStuff(Material oceanMaterial, Camera inCamera)
        {
            //Calculates the required data for the projected grid

            // compute ltoo = localToOcean transform, where ocean frame = tangent space at
            // camera projection on sphere radius in local space

            Matrix4x4 ctol1 = inCamera.cameraToWorldMatrix;

            //position relative to kerbin
//			Vector3d tmp = (inCamera.transform.position) - m_manager.parentCelestialBody.transform.position;


            Matrix4x4d cameraToWorld = new Matrix4x4d(ctol1.m00, ctol1.m01, ctol1.m02, ctol1.m03,
                                                      ctol1.m10, ctol1.m11, ctol1.m12, ctol1.m13,
                                                      ctol1.m20, ctol1.m21, ctol1.m22, ctol1.m23,
                                                      ctol1.m30, ctol1.m31, ctol1.m32, ctol1.m33);


            //Looking back, I have no idea how I figured this crap out
            Vector4 translation = m_manager.parentCelestialBody.transform.worldToLocalMatrix.inverse.GetColumn(3);

            Matrix4x4d worldToLocal = new Matrix4x4d(1, 0, 0, -translation.x,
                                                     0, 1, 0, -translation.y,
                                                     0, 0, 1, -translation.z,
                                                     0, 0, 0, 1);

            Matrix4x4d camToLocal = worldToLocal * cameraToWorld;


            // camera in local space relative to planet's origin
            Vector3d2 cl = new Vector3d2();

            cl = camToLocal * Vector3d2.Zero();

//			double radius = m_manager.GetRadius ();
            double radius = m_manager.GetRadius() + m_oceanLevel;

//			Vector3d2 ux, uy, uz, oo;

            uz = cl.Normalized();              // unit z vector of ocean frame, in local space

            if (m_oldlocalToOcean != Matrix4x4d.Identity())
            {
                ux = (new Vector3d2(m_oldlocalToOcean.m [1, 0], m_oldlocalToOcean.m [1, 1], m_oldlocalToOcean.m [1, 2])).Cross(uz).Normalized();
            }
            else
            {
                ux = Vector3d2.UnitZ().Cross(uz).Normalized();
            }

            uy = uz.Cross(ux);              // unit y vector

            oo = uz * (radius);             // origin of ocean frame, in local space


            //local to ocean transform
            //computed from oo and ux, uy, uz should be correct
            Matrix4x4d localToOcean = new Matrix4x4d(
                ux.x, ux.y, ux.z, -ux.Dot(oo),
                uy.x, uy.y, uy.z, -uy.Dot(oo),
                uz.x, uz.y, uz.z, -uz.Dot(oo),
                0.0, 0.0, 0.0, 1.0);


            Matrix4x4d cameraToOcean = localToOcean * camToLocal;


            //Couldn't figure out how to change the wind's direction in all that math so I tried to do the easy thing
            //And Rotated the ocean and the sun
            //This didn't work

            //deleted rotation code here



            Vector3d2 delta = new Vector3d2(0, 0, 0);

            if (m_oldlocalToOcean != Matrix4x4d.Identity())
            {
                delta     = localToOcean * (m_oldlocalToOcean.Inverse() * Vector3d2.Zero());
                m_offset += delta;
            }

            m_oldlocalToOcean = localToOcean;

            Matrix4x4d ctos = ModifiedProjectionMatrix(inCamera);
            Matrix4x4d stoc = ctos.Inverse();

            Vector3d2 oc = cameraToOcean * Vector3d2.Zero();

            h = oc.z;

            Vector4d stoc_w = (stoc * Vector4d.UnitW()).XYZ0();
            Vector4d stoc_x = (stoc * Vector4d.UnitX()).XYZ0();
            Vector4d stoc_y = (stoc * Vector4d.UnitY()).XYZ0();

            Vector3d2 A0 = (cameraToOcean * stoc_w).XYZ();
            Vector3d2 dA = (cameraToOcean * stoc_x).XYZ();
            Vector3d2 B  = (cameraToOcean * stoc_y).XYZ();

            Vector3d2 horizon1, horizon2;

//			Vector3d2 offset = new Vector3d2 (-m_offset.x, -m_offset.y, h);
            offset = new Vector3d2(-m_offset.x, -m_offset.y, h);
//			Vector3d2 offset = new Vector3d2 (0f, 0f, h);

            double h1    = h * (h + 2.0 * radius);
            double h2    = (h + radius) * (h + radius);
            double alpha = B.Dot(B) * h1 - B.z * B.z * h2;

            double beta0 = (A0.Dot(B) * h1 - B.z * A0.z * h2) / alpha;
            double beta1 = (dA.Dot(B) * h1 - B.z * dA.z * h2) / alpha;

            double gamma0 = (A0.Dot(A0) * h1 - A0.z * A0.z * h2) / alpha;
            double gamma1 = (A0.Dot(dA) * h1 - A0.z * dA.z * h2) / alpha;
            double gamma2 = (dA.Dot(dA) * h1 - dA.z * dA.z * h2) / alpha;

            horizon1 = new Vector3d2(-beta0, -beta1, 0.0);
            horizon2 = new Vector3d2(beta0 * beta0 - gamma0, 2.0 * (beta0 * beta1 - gamma1), beta1 * beta1 - gamma2);

            Vector3d2 sunDir      = new Vector3d2(m_manager.getDirectionToSun().normalized);
            Vector3d2 oceanSunDir = localToOcean.ToMatrix3x3d() * sunDir;

            oceanMaterial.SetVector("_Ocean_SunDir", oceanSunDir.ToVector3());

            oceanMaterial.SetVector("_Ocean_Horizon1", horizon1.ToVector3());
            oceanMaterial.SetVector("_Ocean_Horizon2", horizon2.ToVector3());

            oceanMaterial.SetMatrix("_Ocean_CameraToOcean", cameraToOcean.ToMatrix4x4());
            oceanMaterial.SetMatrix("_Ocean_OceanToCamera", cameraToOcean.Inverse().ToMatrix4x4());

            oceanMaterial.SetMatrix("_Globals_CameraToScreen", ctos.ToMatrix4x4());
            oceanMaterial.SetMatrix("_Globals_ScreenToCamera", stoc.ToMatrix4x4());

            oceanMaterial.SetVector("_Ocean_CameraPos", offset.ToVector3());

            oceanMaterial.SetVector("_Ocean_Color", new Color(m_oceanUpwellingColor.x, m_oceanUpwellingColor.y, m_oceanUpwellingColor.z) /*  *0.1f   */);
            oceanMaterial.SetVector("_Ocean_ScreenGridSize", new Vector2((float)m_resolution / (float)Screen.width, (float)m_resolution / (float)Screen.height));
            oceanMaterial.SetFloat("_Ocean_Radius", (float)radius);

            //			oceanMaterial.SetFloat("scale", 1);
            oceanMaterial.SetFloat("scale", oceanScale);

            oceanMaterial.SetFloat("_OceanAlpha", oceanAlpha);
            oceanMaterial.SetFloat("alphaRadius", alphaRadius);


            oceanMaterial.SetFloat("sunReflectionMultiplier", sunReflectionMultiplier);
            oceanMaterial.SetFloat("skyReflectionMultiplier", skyReflectionMultiplier);
            oceanMaterial.SetFloat("seaRefractionMultiplier", seaRefractionMultiplier);


            m_manager.GetSkyNode().SetOceanUniforms(oceanMaterial);
        }
Ejemplo n.º 18
0
        public void updateStuff(Material oceanMaterial, Camera inCamera)
        {
//			m_manager.GetSkyNode ().SetOceanUniforms (m_oceanMaterial);

            //Calculates the required data for the projected grid

            // compute ltoo = localToOcean transform, where ocean frame = tangent space at
            // camera projection on sphere radius in local space

            Matrix4x4 ctol1 = inCamera.cameraToWorldMatrix;

            Matrix4x4d cameraToWorld = new Matrix4x4d(ctol1.m00, ctol1.m01, ctol1.m02, ctol1.m03,
                                                      ctol1.m10, ctol1.m11, ctol1.m12, ctol1.m13,
                                                      ctol1.m20, ctol1.m21, ctol1.m22, ctol1.m23,
                                                      ctol1.m30, ctol1.m31, ctol1.m32, ctol1.m33);


            //Looking back, I have no idea how I figured this crap out
            //I probably did the math wrong anyway and it worked by sheer luck and incessant tries

//			Vector4 translation = m_manager.parentCelestialBody.transform.localToWorldMatrix.GetColumn (3);
            Vector3d translation = m_manager.parentCelestialBody.position;

            Matrix4x4d worldToLocal = new Matrix4x4d(1, 0, 0, -translation.x,
                                                     0, 1, 0, -translation.y,
                                                     0, 0, 1, -translation.z,
                                                     0, 0, 0, 1);


            Matrix4x4d camToLocal = worldToLocal * cameraToWorld;
            Matrix4x4d localToCam = camToLocal.Inverse();


            // camera in local space relative to planet's origin
            Vector3d2 cl = new Vector3d2();

            cl = camToLocal * Vector3d2.Zero();

            double radius = m_manager.GetRadius() + m_oceanLevel;

            uz = cl.Normalized();              // unit z vector of ocean frame, in local space

            if (m_oldlocalToOcean != Matrix4x4d.Identity())
            {
                ux = (new Vector3d2(m_oldlocalToOcean.m [1, 0], m_oldlocalToOcean.m [1, 1], m_oldlocalToOcean.m [1, 2])).Cross(uz).Normalized();
            }
            else
            {
                ux = Vector3d2.UnitZ().Cross(uz).Normalized();
            }

            uy = uz.Cross(ux);              // unit y vector

            oo = uz * (radius);             // origin of ocean frame, in local space


            //local to ocean transform
            //computed from oo and ux, uy, uz should be correct
            Matrix4x4d localToOcean = new Matrix4x4d(
                ux.x, ux.y, ux.z, -ux.Dot(oo),
                uy.x, uy.y, uy.z, -uy.Dot(oo),
                uz.x, uz.y, uz.z, -uz.Dot(oo),
                0.0, 0.0, 0.0, 1.0);


            Matrix4x4d cameraToOcean = localToOcean * camToLocal;
            Matrix4x4d worldToOcean  = localToOcean * worldToLocal;

            Vector3d2 delta = new Vector3d2(0, 0, 0);

            if (m_oldlocalToOcean != Matrix4x4d.Identity())
            {
                delta     = localToOcean * (m_oldlocalToOcean.Inverse() * Vector3d2.Zero());
                m_offset += delta;
            }

            //reset offset when bigger than 20000 to  avoid floating point issues when later casting the offset to float
            if (Mathf.Max(Mathf.Abs((float)m_offset.x), Mathf.Abs((float)m_offset.y)) > 20000f)
            {
                m_offset.x = 0.0;
                m_offset.y = 0.0;
            }

            m_oldlocalToOcean = localToOcean;

//			Matrix4x4d ctos = ModifiedProjectionMatrix (inCamera); //moved to command buffer
//			Matrix4x4d stoc = ctos.Inverse ();

            Vector3d2 oc = cameraToOcean * Vector3d2.Zero();

            h = oc.z;

            //				m_skyMaterialLocal.EnableKeyword ("ECLIPSES_ON");
            //				m_skyMaterialLocal.DisableKeyword ("ECLIPSES_OFF");

            offset = new Vector3d2(-m_offset.x, -m_offset.y, h);

            //old horizon code
            //This breaks down when you tilt the camera by 90 degrees in any direction
            //I made some new horizon code down, scroll down

//			Vector4d stoc_w = (stoc * Vector4d.UnitW ()).XYZ0 ();
//			Vector4d stoc_x = (stoc * Vector4d.UnitX ()).XYZ0 ();
//			Vector4d stoc_y = (stoc * Vector4d.UnitY ()).XYZ0 ();
//
//			Vector3d2 A0 = (cameraToOcean * stoc_w).XYZ ();
//			Vector3d2 dA = (cameraToOcean * stoc_x).XYZ ();
//			Vector3d2 B = (cameraToOcean * stoc_y).XYZ ();
//
//			Vector3d2 horizon1, horizon2;
//
//			double h1 = h * (h + 2.0 * radius);
//			double h2 = (h + radius) * (h + radius);
//			double alpha = B.Dot (B) * h1 - B.z * B.z * h2;
//
//			double beta0 = (A0.Dot (B) * h1 - B.z * A0.z * h2) / alpha;
//			double beta1 = (dA.Dot (B) * h1 - B.z * dA.z * h2) / alpha;
//
//			double gamma0 = (A0.Dot (A0) * h1 - A0.z * A0.z * h2) / alpha;
//			double gamma1 = (A0.Dot (dA) * h1 - A0.z * dA.z * h2) / alpha;
//			double gamma2 = (dA.Dot (dA) * h1 - dA.z * dA.z * h2) / alpha;
//
//			horizon1 = new Vector3d2 (-beta0, -beta1, 0.0);
//			horizon2 = new Vector3d2 (beta0 * beta0 - gamma0, 2.0 * (beta0 * beta1 - gamma1), beta1 * beta1 - gamma2);

            Vector3d2 sunDir      = new Vector3d2(m_manager.getDirectionToSun().normalized);
            Vector3d2 oceanSunDir = localToOcean.ToMatrix3x3d() * sunDir;

            oceanMaterial.SetMatrix(ShaderProperties._Globals_CameraToWorld_PROPERTY, cameraToWorld.ToMatrix4x4());


            oceanMaterial.SetVector(ShaderProperties._Ocean_SunDir_PROPERTY, oceanSunDir.ToVector3());

            oceanMaterial.SetMatrix(ShaderProperties._Ocean_CameraToOcean_PROPERTY, cameraToOcean.ToMatrix4x4());
            oceanMaterial.SetMatrix(ShaderProperties._Ocean_OceanToCamera_PROPERTY, cameraToOcean.Inverse().ToMatrix4x4());

//			oceanMaterial.SetMatrix (ShaderProperties._Globals_CameraToScreen_PROPERTY, ctos.ToMatrix4x4 ());
//			oceanMaterial.SetMatrix (ShaderProperties._Globals_ScreenToCamera_PROPERTY, stoc.ToMatrix4x4 ());


            oceanMaterial.SetMatrix(ShaderProperties._Globals_WorldToOcean_PROPERTY, worldToOcean.ToMatrix4x4());
            oceanMaterial.SetMatrix(ShaderProperties._Globals_OceanToWorld_PROPERTY, worldToOcean.Inverse().ToMatrix4x4());


            oceanMaterial.SetVector(ShaderProperties._Ocean_CameraPos_PROPERTY, offset.ToVector3());

            //oceanMaterial.SetVector (ShaderProperties._Ocean_Color_PROPERTY, new Color (m_oceanUpwellingColor.x, m_oceanUpwellingColor.y, m_oceanUpwellingColor.z));
            oceanMaterial.SetVector(ShaderProperties._Ocean_Color_PROPERTY, m_oceanUpwellingColor);
            oceanMaterial.SetVector("_Underwater_Color", m_UnderwaterColor);
            oceanMaterial.SetVector(ShaderProperties._Ocean_ScreenGridSize_PROPERTY, new Vector2((float)m_resolution / (float)Screen.width, (float)m_resolution / (float)Screen.height));
            oceanMaterial.SetFloat(ShaderProperties._Ocean_Radius_PROPERTY, (float)(radius + m_oceanLevel));

            //			oceanMaterial.SetFloat("scale_PROPERTY, 1);
            oceanMaterial.SetFloat(ShaderProperties.scale_PROPERTY, oceanScale);

            oceanMaterial.SetFloat(ShaderProperties._OceanAlpha_PROPERTY, oceanAlpha);
            oceanMaterial.SetFloat(ShaderProperties.alphaRadius_PROPERTY, alphaRadius);

            oceanMaterial.SetFloat(ShaderProperties._GlobalOceanAlpha_PROPERTY, m_manager.m_skyNode.interpolatedSettings._GlobalOceanAlpha);


            m_manager.GetSkyNode().SetOceanUniforms(oceanMaterial);


            //horizon calculations
            //these are used to find where the horizon line is on screen
            //and "clamp" vertexes that are above it back to it
            //as the grid is projected on the whole screen, vertexes over the horizon need to be dealt with
            //simply passing a flag to drop fragments or moving these vertexes offscreen will cause issues
            //as the horizon line can be between two vertexes and the horizon line will appear "pixelated"
            //as whole chunks go missing

            //these need to be done here
            //1)for double precision
            //2)for speed

            Vector3d2 sphereDir = (localToCam * Vector3d2.Zero()).Normalized();         //direction to center of planet
            double    OHL       = (localToCam * Vector3d2.Zero()).Magnitude();          //distance to center of planet

            double rHorizon = Math.Sqrt((OHL)*(OHL)-(radius * radius));                 //distance to the horizon, i.e distance to ocean sphere tangent
            //basic geometry yo

            //Theta=angle to horizon, now all that is left to do is check the viewdir against this angle in the shader
            double cosTheta = rHorizon / (OHL);
            double sinTheta = Math.Sqrt(1 - cosTheta * cosTheta);

            oceanMaterial.SetVector(ShaderProperties.sphereDir_PROPERTY, sphereDir.ToVector3());
            oceanMaterial.SetFloat(ShaderProperties.cosTheta_PROPERTY, (float)cosTheta);
            oceanMaterial.SetFloat(ShaderProperties.sinTheta_PROPERTY, (float)sinTheta);

            if (Core.Instance.usePlanetShine)
            {
                Matrix4x4 planetShineSourcesMatrix = m_manager.m_skyNode.planetShineSourcesMatrix;

                Vector3d2 oceanSunDir2;
                for (int i = 0; i < 4; i++)
                {
                    Vector4 row = planetShineSourcesMatrix.GetRow(i);
                    oceanSunDir2 = localToOcean.ToMatrix3x3d() * new Vector3d2(row.x, row.y, row.z);
                    planetShineSourcesMatrix.SetRow(i, new Vector4((float)oceanSunDir2.x, (float)oceanSunDir2.y, (float)oceanSunDir2.z, row.w));
                }
                oceanMaterial.SetMatrix("planetShineSources", planetShineSourcesMatrix);

                oceanMaterial.SetMatrix("planetShineRGB", m_manager.m_skyNode.planetShineRGBMatrix);
            }

            m_manager.GetSkyNode().UpdatePostProcessMaterial(underwaterPostProcessingMaterial);
            underwaterPostProcessingMaterial.SetVector("_Underwater_Color", m_UnderwaterColor);

            m_oceanMaterial.SetFloat("refractionIndex", refractionIndex);
            m_oceanMaterial.SetFloat("transparencyDepth", transparencyDepth);
            m_oceanMaterial.SetFloat("darknessDepth", darknessDepth);

            underwaterPostProcessingMaterial.SetFloat("transparencyDepth", transparencyDepth);
            underwaterPostProcessingMaterial.SetFloat("darknessDepth", darknessDepth);

            //underwaterPostProcessingMaterial.SetFloat ("refractionIndex", refractionIndex);
        }
Ejemplo n.º 19
0
        public void SetUniforms(Material mat)
        {
            //Sets uniforms that this or other gameobjects may need
            if(mat == null) return;
            //mat.SetFloat ("atmosphereGlobalScale", atmosphereGlobalScale);

            mat.SetFloat ("_Alpha_Cutoff", alphaCutoff);
            mat.SetFloat ("_Alpha_Global", alphaGlobal);

            mat.SetFloat("scale",atmosphereGlobalScale);
            mat.SetFloat("Rg", Rg*atmosphereGlobalScale);
            mat.SetFloat("Rt", Rt*atmosphereGlobalScale);
            mat.SetFloat("RL", RL*atmosphereGlobalScale);

            //			if (debugSettings [5])
            if(!MapView.MapIsEnabled)
            {
                mat.SetFloat ("_Globals_ApparentDistance", apparentDistance);
            }
            else
            {
                mat.SetFloat("_Globals_ApparentDistance", (float)(parentCelestialBody.Radius/100.2f));
            }

            //			if (debugSettings[1])
            if(!MapView.MapIsEnabled)
            {

                mat.SetMatrix ("_Globals_WorldToCamera", farCamera.worldToCameraMatrix);
                mat.SetMatrix ("_Globals_CameraToWorld", farCamera.worldToCameraMatrix.inverse);
            }

            else
            {
                mat.SetMatrix ("_Globals_WorldToCamera", scaledSpaceCamera.worldToCameraMatrix);
                mat.SetMatrix ("_Globals_CameraToWorld", scaledSpaceCamera.worldToCameraMatrix.inverse);
            }

            mat.SetVector("betaR", m_betaR / 1000.0f);
            mat.SetFloat("mieG", Mathf.Clamp(m_mieG, 0.0f, 0.99f));
            mat.SetTexture("_Sky_Transmittance", m_transmit);
            mat.SetTexture("_Sky_Inscatter", m_inscatter);
            mat.SetTexture("_Sky_Irradiance", m_irradiance);
            //			mat.SetTexture("_Sky_Map", m_skyMap);
            mat.SetFloat("_Sun_Intensity", sun_intensity);
            mat.SetVector("_Sun_WorldSunDir", m_manager.getDirectionToSun().normalized);
            //			mat.SetVector("_Sun_WorldSunDir", m_manager.getDirectionToSun());

            //			//copied from m_manager's set uniforms

            Matrix4x4 p;
            //			if (debugSettings [2])
            if(!MapView.MapIsEnabled)
            {
                p = farCamera.projectionMatrix;
            }
            else
            {
                p = scaledSpaceCamera.projectionMatrix;
            }

            m_cameraToScreenMatrix = new Matrix4x4d (p);
            mat.SetMatrix ("_Globals_CameraToScreen", m_cameraToScreenMatrix.ToMatrix4x4 ());
            mat.SetMatrix ("_Globals_ScreenToCamera", m_cameraToScreenMatrix.Inverse ().ToMatrix4x4 ());

            //			if (debugSettings [3])
            {
                mat.SetVector ("_Globals_WorldCameraPos", farCamera.transform.position);
            }
            //			else
            //			{
            //				Vector3 newpos= ScaledSpace.ScaledToLocalSpace(scaledSpaceCamera.transform.position);
            //				//				m_skyMaterial.SetVector ("_Globals_WorldCameraPos", scaledSpaceCamera.transform.position);
            //				mat.SetVector ("_Globals_WorldCameraPos", newpos);
            //			}

            //			if (debugSettings [4])
            if(!MapView.MapIsEnabled)
            {
                mat.SetVector ("_Globals_Origin", parentCelestialBody.transform.position);
            }
            else
            {

                Transform celestialTransform = ScaledSpace.Instance.scaledSpaceTransforms.Single(t => t.name == parentCelestialBody.name);
                Vector3 idek =celestialTransform.position;
                mat.SetVector ("_Globals_Origin", idek);

            }

            mat.SetFloat ("_Exposure", m_HDRExposure);
        }