Пример #1
0
	public Quat(Vector3d2 to, Vector3d2 _from)
	{
	    Vector3d2 f = _from.Normalized();
	    Vector3d2 t = to.Normalized();
	
	    double dotProdPlus1 = 1.0 + f.Dot(t);
	
	    if (dotProdPlus1 < 1e-7) {
	        w = 0;
	        if (System.Math.Abs(f.x) < 0.6) {
	            double norm = System.Math.Sqrt(1 - f.x * f.x);
	            x = 0;
	            y = f.z / norm;
	            z = -f.y / norm;
	        } else if (System.Math.Abs(f.y) < 0.6) {
	            double norm = System.Math.Sqrt(1 - f.y * f.y);
	            x = -f.z / norm;
	            y = 0;
	            z = f.x / norm;
	        } else {
	            double norm = System.Math.Sqrt(1 - f.z * f.z);
	            x = f.y / norm;
	            y = -f.x / norm;
	            z = 0;
	        }
	    } else {
	        double s = System.Math.Sqrt(0.5 * dotProdPlus1);
	        Vector3d2 tmp = (f.Cross(t)) / (2.0 * s);
	        x = tmp.x;
	        y = tmp.y;
	        z = tmp.z;
	        w = s;
	    }
	}
        public override Matrix4x4d DeformedToTangentFrame(Vector3d2 deformedPt)
        {
            Vector3d2 Uz = deformedPt.Normalized();
            Vector3d2 Ux = (new Vector3d2(0, 1, 0)).Cross(Uz).Normalized();
            Vector3d2 Uy = Uz.Cross(Ux);

            return(new Matrix4x4d(Ux.x, Ux.y, Ux.z, 0.0,
                                  Uy.x, Uy.y, Uy.z, 0.0,
                                  Uz.x, Uz.y, Uz.z, -R,
                                  0.0, 0.0, 0.0, 1.0));
        }
Пример #3
0
	public Quat(Vector3d2 axis, double angle)
	{
	    Vector3d2 axisN = axis.Normalized();
	    double a = angle * 0.5;
	    double sina = System.Math.Sin(a);
	    double cosa = System.Math.Cos(a);
	    x = axisN.x * sina;
	    y = axisN.y * sina;
	    z = axisN.z * sina;
	    w = cosa;
	}
Пример #4
0
    public Quat(Vector3d2 axis, double angle)
    {
        Vector3d2 axisN = axis.Normalized();
        double    a     = angle * 0.5;
        double    sina  = System.Math.Sin(a);
        double    cosa  = System.Math.Cos(a);

        x = axisN.x * sina;
        y = axisN.y * sina;
        z = axisN.z * sina;
        w = cosa;
    }
Пример #5
0
        public override void Move(Vector3d2 oldp, Vector3d2 p, double speed)
        {
            Vector3d2 oldpos = oldp.Normalized();
            Vector3d2 pos    = p.Normalized();

            double oldlat = MathUtility.Safe_Asin(oldpos.z);
            double oldlon = Math.Atan2(oldpos.y, oldpos.x);
            double lat    = MathUtility.Safe_Asin(pos.z);
            double lon    = Math.Atan2(pos.y, pos.x);

            m_position.x0 -= (lon - oldlon) * speed * Math.Max(1.0, GetHeight());
            m_position.y0 -= (lat - oldlat) * speed * Math.Max(1.0, GetHeight());
        }
        protected override void SetScreenUniforms(TerrainNode node, TerrainQuad quad, MaterialPropertyBlock matPropertyBlock)
        {
            double ox = quad.GetOX();
            double oy = quad.GetOY();
            double l  = quad.GetLength();

            Vector3d2 p0 = new Vector3d2(ox, oy, R);
            Vector3d2 p1 = new Vector3d2(ox + l, oy, R);
            Vector3d2 p2 = new Vector3d2(ox, oy + l, R);
            Vector3d2 p3 = new Vector3d2(ox + l, oy + l, R);
            Vector3d2 pc = (p0 + p3) * 0.5;

            double    l0 = 0.0, l1 = 0.0, l2 = 0.0, l3 = 0.0;
            Vector3d2 v0 = p0.Normalized(ref l0);
            Vector3d2 v1 = p1.Normalized(ref l1);
            Vector3d2 v2 = p2.Normalized(ref l2);
            Vector3d2 v3 = p3.Normalized(ref l3);

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

            matPropertyBlock.AddMatrix(m_uniforms.screenQuadCorners, (m_localToScreen * deformedCorners).ToMatrix4x4());

            Matrix4x4d 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);

            matPropertyBlock.AddMatrix(m_uniforms.screenQuadVerticals, (m_localToScreen * deformedVerticals).ToMatrix4x4());
            matPropertyBlock.AddVector(m_uniforms.screenQuadCornerNorms, new Vector4((float)l0, (float)l1, (float)l2, (float)l3));

            Vector3d2 uz = pc.Normalized();
            Vector3d2 ux = (new Vector3d2(0, 1, 0)).Cross(uz).Normalized();
            Vector3d2 uy = uz.Cross(ux);

            Matrix4x4d ltow = node.GetLocalToWorld();

            Matrix3x3d tangentFrameToWorld = new Matrix3x3d(ltow.m[0, 0], ltow.m[0, 1], ltow.m[0, 2],
                                                            ltow.m[1, 0], ltow.m[1, 1], ltow.m[1, 2],
                                                            ltow.m[2, 0], ltow.m[2, 1], ltow.m[2, 2]);

            Matrix3x3d m = new Matrix3x3d(ux.x, uy.x, uz.x,
                                          ux.y, uy.y, uz.y,
                                          ux.z, uy.z, uz.z);

            matPropertyBlock.AddMatrix(m_uniforms.tangentFrameToWorld, (tangentFrameToWorld * m).ToMatrix4x4());
        }
Пример #7
0
    public Quat(Vector3d2 to, Vector3d2 _from)
    {
        Vector3d2 f = _from.Normalized();
        Vector3d2 t = to.Normalized();

        double dotProdPlus1 = 1.0 + f.Dot(t);

        if (dotProdPlus1 < 1e-7)
        {
            w = 0;
            if (System.Math.Abs(f.x) < 0.6)
            {
                double norm = System.Math.Sqrt(1 - f.x * f.x);
                x = 0;
                y = f.z / norm;
                z = -f.y / norm;
            }
            else if (System.Math.Abs(f.y) < 0.6)
            {
                double norm = System.Math.Sqrt(1 - f.y * f.y);
                x = -f.z / norm;
                y = 0;
                z = f.x / norm;
            }
            else
            {
                double norm = System.Math.Sqrt(1 - f.z * f.z);
                x = f.y / norm;
                y = -f.x / norm;
                z = 0;
            }
        }
        else
        {
            double    s   = System.Math.Sqrt(0.5 * dotProdPlus1);
            Vector3d2 tmp = (f.Cross(t)) / (2.0 * s);
            x = tmp.x;
            y = tmp.y;
            z = tmp.z;
            w = s;
        }
    }
Пример #8
0
        public override void Move(Vector3d2 oldp, Vector3d2 p, double speed)
        {
            Vector3d2 oldpos = oldp.Normalized();
            Vector3d2 pos = p.Normalized();

            double oldlat = MathUtility.Safe_Asin(oldpos.z);
            double oldlon = Math.Atan2(oldpos.y, oldpos.x);
            double lat = MathUtility.Safe_Asin(pos.z);
            double lon = Math.Atan2(pos.y, pos.x);

            m_position.x0 -= (lon - oldlon) * speed * Math.Max(1.0, GetHeight());
            m_position.y0 -= (lat - oldlat) * speed * Math.Max(1.0, GetHeight());
        }
Пример #9
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);
            }
        }
Пример #10
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);
        }
Пример #11
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);
        }
Пример #12
0
        protected override void SetScreenUniforms(TerrainNode node, TerrainQuad quad, MaterialPropertyBlock matPropertyBlock)
        {
            double ox = quad.GetOX();
            double oy = quad.GetOY();
            double l = quad.GetLength();

            Vector3d2 p0 = new Vector3d2(ox, oy, R);
            Vector3d2 p1 = new Vector3d2(ox + l, oy, R);
            Vector3d2 p2 = new Vector3d2(ox, oy + l, R);
            Vector3d2 p3 = new Vector3d2(ox + l, oy + l, R);
            Vector3d2 pc = (p0 + p3) * 0.5;

            double l0 = 0.0, l1 = 0.0, l2 = 0.0, l3 = 0.0;
            Vector3d2 v0 = p0.Normalized(ref l0);
            Vector3d2 v1 = p1.Normalized(ref l1);
            Vector3d2 v2 = p2.Normalized(ref l2);
            Vector3d2 v3 = p3.Normalized(ref l3);

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

            matPropertyBlock.AddMatrix(m_uniforms.screenQuadCorners, (m_localToScreen * deformedCorners).ToMatrix4x4());

            Matrix4x4d 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);

            matPropertyBlock.AddMatrix(m_uniforms.screenQuadVerticals, (m_localToScreen * deformedVerticals).ToMatrix4x4());
            matPropertyBlock.AddVector(m_uniforms.screenQuadCornerNorms, new Vector4((float)l0, (float)l1, (float)l2, (float)l3));

            Vector3d2 uz = pc.Normalized();
            Vector3d2 ux = (new Vector3d2(0,1,0)).Cross(uz).Normalized();
            Vector3d2 uy = uz.Cross(ux);

            Matrix4x4d ltow = node.GetLocalToWorld();

            Matrix3x3d tangentFrameToWorld = new Matrix3x3d(ltow.m[0,0], ltow.m[0,1], ltow.m[0,2],
                                                            ltow.m[1,0], ltow.m[1,1], ltow.m[1,2],
                                                            ltow.m[2,0], ltow.m[2,1], ltow.m[2,2]);

            Matrix3x3d m = new Matrix3x3d(	ux.x, uy.x, uz.x,
                                          ux.y, uy.y, uz.y,
                                          ux.z, uy.z, uz.z);

            matPropertyBlock.AddMatrix(m_uniforms.tangentFrameToWorld, (tangentFrameToWorld * m).ToMatrix4x4());
        }
Пример #13
0
        public override Matrix4x4d DeformedToTangentFrame(Vector3d2 deformedPt)
        {
            Vector3d2 Uz = deformedPt.Normalized();
            Vector3d2 Ux = (new Vector3d2(0,1,0)).Cross(Uz).Normalized();
            Vector3d2 Uy = Uz.Cross(Ux);

            return new Matrix4x4d(	Ux.x, Ux.y, Ux.z, 0.0,
                                  Uy.x, Uy.y, Uy.z, 0.0,
                                  Uz.x, Uz.y, Uz.z, -R,
                                  0.0, 0.0, 0.0, 1.0);
        }
Пример #14
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);
			
		}
Пример #15
0
        public void updateStuff()
        {
            //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

            //			m_core.chosenCamera.ResetProjectionMatrix();
            //			m_core.chosenCamera.ResetWorldToCameraMatrix();

            //			Matrix4x4 ctol1 = m_core.chosenCamera.cameraToWorldMatrix;
            Matrix4x4 ctol1 = m_manager.m_skyNode.farCamera.cameraToWorldMatrix;

            //position relative to kerbin
            //			Vector3d tmp = (m_core.chosenCamera.transform.position) - m_manager.parentCelestialBody.transform.position;
            Vector3d tmp = (m_manager.m_skyNode.farCamera.transform.position) - m_manager.parentCelestialBody.transform.position;
            //			print ("TMP");
            //			print (tmp);
            //			print (tmp.magnitude);

            Vector3d2 cl = new Vector3d2 ();
            //			cl.x = tmp.x;
            //			cl.y = tmp.y;
            //			cl.z = tmp.z;

            //			Matrix4x4d cameraToWorld = 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);

            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);

            //			Matrix4x4d cameraToWorld = new Matrix4x4d (0,0.906534175092856,  0.422132431102747,    6365631.33384793,
            //			                                           -0.997188818006091 ,  0.0316302600890084,   -0.0679263416526804,  -906.151431945729,
            //			                                           0.0749297086849734,0.420945740013386,-0.903985742542972,-12059.3565785169,
            //			                                           0,0,0,1);

            //Vector3d planetPos = m_manager.parentCelestialBody.transform.position;

            Matrix4x4d worldToLocal = new Matrix4x4d (m_manager.parentCelestialBody.transform.worldToLocalMatrix);

            Vector4 translation = m_manager.parentCelestialBody.transform.worldToLocalMatrix.inverse.GetColumn (3);

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

            //			print ("translation");
            //			print (translation);

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

            Matrix4x4d camToLocal = worldToLocal2 * cameraToWorld;
            //			Matrix4x4d camToLocal = ModifiedWorldToCameraMatrix ();

            //			Matrix4x4d camToLocal = cameraToWorld ;

            //			print ("WORLD TO LOCAL");
            //			print (worldToLocal);

            //			print ("CAM T		O LOCAL");
            //			print (camToLocal);

            //cl = camToLocal * Vector3d2.Zero ();
            /*Vector3d2*/ cl = camToLocal * Vector3d2.Zero ();

            //			print ("CL");
            //			print (cl);
            //			print (cl.Magnitude ());

            // camera in local space relative to planet's origin

            double radius = m_manager.GetRadius ();

            m_drawOcean = true;
            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

            //			h = cl.Magnitude() - radius;
            //			print ("h=");
            //			print (h);
            //			h = cl.Magnitude();
            //			Vector3d tmp2=m_core.chosenCamera.transform.position-m_manager.parentCelestialBody.transform.position;

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

            //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;
            //			cameraToOcean = cameraToOcean.Inverse ();
            //			Matrix4x4d cameraToOcean = OceanToWorld.Inverse() * cameraToWorld;
            Vector3d2 delta=new Vector3d2(0,0,0);

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

            m_oldlocalToOcean = localToOcean;

            Matrix4x4d ctos = ModifiedProjectionMatrix (m_manager.m_skyNode.farCamera);
            Matrix4x4d stoc = ctos.Inverse();
            //			Matrix4x4d stoc = new Matrix4x4d (1.23614492203479, 0, 0, 0,
            //				0, 0.577350279552042, 0, 0,
            //					0, 0, 0, -1,
            //			                                 0, 0, -0.000249974703487648, 0.000249974763086261);
            //			print ("STOC");
            //			print (stoc);
            //			Matrix4x4d stoc = Matrix4x4d.Identity();

            //			Matrix4x4 p = camera.projectionMatrix;
            //
            //			m_cameraToScreenMatrix = new Matrix4x4d(p);
            //			m_screenToCameraMatrix = m_cameraToScreenMatrix.Inverse();

            //			Matrix4x4d stoc = new Matrix4x4d(3.57253843540205,0,0,0,
            //			                             0,3.577350279552042,0,0,
            //			                             0,0,0,-2,
            //			                             0,0,-0.00178426976276966,0.00178426997547119);

            Vector3d2 oc = cameraToOcean * Vector3d2.Zero();

            //			h = tmp2.magnitude - radius;
            h = oc.z;
            //			print ("oc.z");
            //			print (h);
            //			print ("h=");
            //			print (h);

            //			print ("tmp2.magnitude - radius");
            //			print (tmp2.magnitude - radius);

            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);

            //			print ("offset");
            //			print (offset);

            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;

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

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

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

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

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

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

            m_oceanMaterial.SetFloat("scale", 1);

            m_manager.GetSkyNode().SetOceanUniforms(m_oceanMaterial);
        }