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