/* * 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(); }
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); } }
/* * 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(); }
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); }
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); }
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); }
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); }