// uses GPU to accumulate layers of noise public static void Execute(CNoiseLayer layer, RenderTexture noiseRT, CBoundingVolume volume, bool flip, float planetRadius) { CGlobal global = CGlobal.GetInstance(); int matidx = 0; float amp = 1.0f; float frequency = layer.m_Frequency; switch (layer.m_LayerType) { case NoiseLayerType.Cell: { Debug.Log("[ETHEREA1] NoiseLayerType.Cell is not implemented yet! Please select Ridged or Turbulence instead."); break; } case NoiseLayerType.Ridged: { matidx = 0; break; } case NoiseLayerType.Turbulence: { matidx = 1; break; } } for (int i = 0; i < layer.m_Octaves; i++) { RenderTexture.active = noiseRT; global.GenNoiseMaterial[matidx].SetFloat("_planetRadius", planetRadius); global.GenNoiseMaterial[matidx].SetVector("_noiseOffset", layer.m_NoiseOffset); global.GenNoiseMaterial[matidx].SetFloat("_offset", layer.m_Offset); global.GenNoiseMaterial[matidx].SetFloat("_hpower", layer.m_HPower); global.GenNoiseMaterial[matidx].SetTexture("_permTexture", global.PermTex); global.GenNoiseMaterial[matidx].SetTexture("_simplexTexture", global.SimplexTex); global.GenNoiseMaterial[matidx].SetFloat("_contribution", layer.m_Contribution); global.GenNoiseMaterial[matidx].SetTexture("_previousPass", noiseRT); global.GenNoiseMaterial[matidx].SetFloat("_amp", amp); global.GenNoiseMaterial[matidx].SetFloat("_frequency", frequency); // ### render with extended volume coordinates but with normal uv volume coordinates //global.RenderQuadVolumeExCoord(noiseRT.width, noiseRT.height, global.GenNoiseMaterial[matidx], volume, flip); global.RenderQuadVolume(noiseRT.width, noiseRT.height, global.GenNoiseMaterial[matidx], volume, flip); frequency *= layer.m_Lacunarity; amp *= layer.m_Persistence; RenderTexture.active = null; } }
public static void ShapeNoise(RenderTexture noiseRT, Texture2D shapeTex, CBoundingVolume volume) { CGlobal global = CGlobal.GetInstance(); RenderTexture.active = noiseRT; global.ShapeNoiseMaterial.SetTexture("_hmap", noiseRT); global.ShapeNoiseMaterial.SetTexture("_shape", shapeTex); global.RenderQuadVolume(noiseRT.width, noiseRT.height, global.ShapeNoiseMaterial, volume, false); RenderTexture.active = null; }
// split node into 4 children private void Split() { // force too coarse neighbors to split as well for (byte i=0; i<4; i++) { if (m_SplitLevel > m_Neighbors[i].node.m_SplitLevel && !m_Neighbors[i].node.m_HasChildren) { m_Neighbors[i].node.Split(); return; } } // // split into the children // // first child - top left CBoundingVolume vol1 = new CBoundingVolume(); Vector3 v1a = m_Volume.vertices[0]; Vector3 v1b = Vector3.Lerp(m_Volume.vertices[0], m_Volume.vertices[1], 0.5f); Vector3 v1c = m_Center; Vector3 v1d = Vector3.Lerp(m_Volume.vertices[3], m_Volume.vertices[0], 0.5f); vol1.vertices.Add(v1a); vol1.vertices.Add(v1b); vol1.vertices.Add(v1c); vol1.vertices.Add(v1d); Vector3 uv1a = m_Volume.uvs[0]; Vector3 uv1b = Vector3.Lerp(m_Volume.uvs[0], m_Volume.uvs[1], 0.5f); Vector3 uv1d = Vector3.Lerp(m_Volume.uvs[3], m_Volume.uvs[0], 0.5f); Vector3 uv1c = new Vector3(uv1b.x, uv1d.y, 0); vol1.uvs.Add(uv1a); vol1.uvs.Add(uv1b); vol1.uvs.Add(uv1c); vol1.uvs.Add(uv1d); CQuadtree q1 = new CQuadtree(this, vol1); // second child - top right CBoundingVolume vol2 = new CBoundingVolume(); Vector3 v2a = Vector3.Lerp(m_Volume.vertices[0], m_Volume.vertices[1], 0.5f); Vector3 v2b = m_Volume.vertices[1]; Vector3 v2c = Vector3.Lerp(m_Volume.vertices[1], m_Volume.vertices[2], 0.5f); Vector3 v2d = m_Center; vol2.vertices.Add(v2a); vol2.vertices.Add(v2b); vol2.vertices.Add(v2c); vol2.vertices.Add(v2d); Vector3 uv2a = Vector3.Lerp(m_Volume.uvs[0], m_Volume.uvs[1], 0.5f); Vector3 uv2b = m_Volume.uvs[1]; Vector3 uv2c = Vector3.Lerp(m_Volume.uvs[1], m_Volume.uvs[2], 0.5f); Vector3 uv2d = new Vector3(uv2a.x, uv2c.y, 0); vol2.uvs.Add(uv2a); vol2.uvs.Add(uv2b); vol2.uvs.Add(uv2c); vol2.uvs.Add(uv2d); CQuadtree q2 = new CQuadtree(this, vol2); // third child - bottom right CBoundingVolume vol3 = new CBoundingVolume(); Vector3 v3a = m_Center; Vector3 v3b = Vector3.Lerp(m_Volume.vertices[1], m_Volume.vertices[2], 0.5f); Vector3 v3c = m_Volume.vertices[2]; Vector3 v3d = Vector3.Lerp(m_Volume.vertices[3], m_Volume.vertices[2], 0.5f); vol3.vertices.Add(v3a); vol3.vertices.Add(v3b); vol3.vertices.Add(v3c); vol3.vertices.Add(v3d); Vector3 uv3b = Vector3.Lerp(m_Volume.uvs[1], m_Volume.uvs[2], 0.5f); Vector3 uv3c = m_Volume.uvs[2]; Vector3 uv3d = Vector3.Lerp(m_Volume.uvs[3], m_Volume.uvs[2], 0.5f); Vector3 uv3a = new Vector3(uv3d.x, uv3b.y, 0); vol3.uvs.Add(uv3a); vol3.uvs.Add(uv3b); vol3.uvs.Add(uv3c); vol3.uvs.Add(uv3d); CQuadtree q3 = new CQuadtree(this, vol3); // fourth child - bottom left CBoundingVolume vol4 = new CBoundingVolume(); Vector3 v4a = Vector3.Lerp(m_Volume.vertices[3], m_Volume.vertices[0], 0.5f); Vector3 v4b = m_Center; Vector3 v4c = Vector3.Lerp(m_Volume.vertices[3], m_Volume.vertices[2], 0.5f); Vector3 v4d = m_Volume.vertices[3]; vol4.vertices.Add(v4a); vol4.vertices.Add(v4b); vol4.vertices.Add(v4c); vol4.vertices.Add(v4d); Vector3 uv4a = Vector3.Lerp(m_Volume.uvs[3], m_Volume.uvs[0], 0.5f); Vector3 uv4c = Vector3.Lerp(m_Volume.uvs[3], m_Volume.uvs[2], 0.5f); Vector3 uv4d = m_Volume.uvs[3]; Vector3 uv4b = new Vector3(uv4c.x, uv4a.y, 0); vol4.uvs.Add(uv4a); vol4.uvs.Add(uv4b); vol4.uvs.Add(uv4c); vol4.uvs.Add(uv4d); CQuadtree q4 = new CQuadtree(this, vol4); // ----------------------------------------------------------------------- // set internal neighbors q1.SetNeighbor(en_NeighborDirection.NB_Bottom, q4, en_NeighborDirection.NB_Top); q1.SetNeighbor(en_NeighborDirection.NB_Right, q2, en_NeighborDirection.NB_Left); // set internal neighbors q2.SetNeighbor(en_NeighborDirection.NB_Bottom, q3, en_NeighborDirection.NB_Top); q2.SetNeighbor(en_NeighborDirection.NB_Left, q1, en_NeighborDirection.NB_Right); // set internal neighbors q3.SetNeighbor(en_NeighborDirection.NB_Top, q2, en_NeighborDirection.NB_Bottom); q3.SetNeighbor(en_NeighborDirection.NB_Left, q4, en_NeighborDirection.NB_Right); // set internal neighbors q4.SetNeighbor(en_NeighborDirection.NB_Top, q1, en_NeighborDirection.NB_Bottom); q4.SetNeighbor(en_NeighborDirection.NB_Right, q3, en_NeighborDirection.NB_Left); // store as children of the current node m_Children[0] = q1; m_Children[1] = q2; m_Children[2] = q3; m_Children[3] = q4; m_Planet.Splitted = true; m_HasChildren = true; Relink(); }
private void GenVolume() { // only root uses this // define its own bounding volume, depending on the direction vector // the bounding volume is based on the planet radius // and is always relative to the origin at (0,0,0) // the planet that will be instancing this quadtree is a CEntity, though, having position and rotation. Vector3 left = -m_Right; // volume vertices are clockwise Vector3 v1 = (left * m_Planet.m_Radius) + (m_Front * m_Planet.m_Radius) + (m_Up * m_Planet.m_Radius); // left far Vector3 v2 = (left * -m_Planet.m_Radius) + (m_Front * m_Planet.m_Radius) + (m_Up * m_Planet.m_Radius); // right far Vector3 v3 = (left * -m_Planet.m_Radius) + (m_Front * -m_Planet.m_Radius) + (m_Up * m_Planet.m_Radius); // right near Vector3 v4 = (left * m_Planet.m_Radius) + (m_Front * -m_Planet.m_Radius) + (m_Up * m_Planet.m_Radius); // left near Vector3 uv1 = new Vector3(0,0,0); Vector3 uv2 = new Vector3(1,0,0); Vector3 uv3 = new Vector3(1,1,0); Vector3 uv4 = new Vector3(0,1,0); m_Volume = new CBoundingVolume(); m_Volume.vertices.Add(v1); m_Volume.uvs.Add(uv1); m_Volume.vertices.Add(v2); m_Volume.uvs.Add(uv2); m_Volume.vertices.Add(v3); m_Volume.uvs.Add(uv3); m_Volume.vertices.Add(v4); m_Volume.uvs.Add(uv4); // // extrapolate the volume vertices and uvs for normalmapping // float vertSpace = m_Size / (m_Planet.PatchConfig.PatchSize - 1); // vertex spacing v1 += left * vertSpace + m_Up * vertSpace; v2 += m_Right * vertSpace + m_Up * vertSpace; v3 += m_Right * vertSpace - m_Up * vertSpace; v4 += left * vertSpace - m_Up * vertSpace; m_Volume.exvertices.Add(v1); m_Volume.exvertices.Add(v2); m_Volume.exvertices.Add(v3); m_Volume.exvertices.Add(v4); // // make the spherical deformed volume // Vector3 v5 = v1; Vector3 v6 = v2; Vector3 v7 = v3; Vector3 v8 = v4; v5 = CMath.ProjectToSphere(v5, m_Planet.m_Radius); v6 = CMath.ProjectToSphere(v6, m_Planet.m_Radius); v7 = CMath.ProjectToSphere(v7, m_Planet.m_Radius); v8 = CMath.ProjectToSphere(v8, m_Planet.m_Radius); m_SVolume = new CBoundingVolume(); m_SVolume.vertices.Add(v5); m_SVolume.vertices.Add(v6); m_SVolume.vertices.Add(v7); m_SVolume.vertices.Add(v8); m_Normal = m_Up; m_Center = (v1 + v2 + v3 + v4) / 4; m_SCenter = m_Center; m_SCenter = CMath.ProjectToSphere(m_SCenter, m_Planet.m_Radius); }
// volume is already passed as 1/2 of the parent's volume public CQuadtree(CQuadtree parent, CBoundingVolume volume) { m_Parent = parent; m_Planet = parent.m_Planet; m_ShapeTex = parent.m_ShapeTex; m_SplitLevel = (ushort)(m_Parent.m_SplitLevel + 1); if (m_SplitLevel > m_Planet.HighestSplitLevel) m_Planet.HighestSplitLevel = m_SplitLevel; m_Size = m_Parent.m_Size / 2; // // make the new spherical projected volume // m_Volume = volume; Vector3 v1 = m_Volume.vertices[0]; Vector3 v2 = m_Volume.vertices[1]; Vector3 v3 = m_Volume.vertices[2]; Vector3 v4 = m_Volume.vertices[3]; Vector2 uv1 = m_Volume.uvs[0]; Vector2 uv2 = m_Volume.uvs[1]; Vector2 uv3 = m_Volume.uvs[2]; Vector2 uv4 = m_Volume.uvs[3]; m_SVolume = new CBoundingVolume(); m_SVolume.vertices.Add(CMath.ProjectToSphere(v1, m_Planet.m_Radius)); m_SVolume.vertices.Add(CMath.ProjectToSphere(v2, m_Planet.m_Radius)); m_SVolume.vertices.Add(CMath.ProjectToSphere(v3, m_Planet.m_Radius)); m_SVolume.vertices.Add(CMath.ProjectToSphere(v4, m_Planet.m_Radius)); m_SVolume.uvs.Add(uv1); m_SVolume.uvs.Add(uv2); m_SVolume.uvs.Add(uv3); m_SVolume.uvs.Add(uv4); // // extrapolate the flat volume vertices and uvs for normalmapping // float vertSpace = m_Size / (m_Planet.PatchConfig.PatchSize - 1); // vertex spacing Vector3 left = -m_Right; v1 += left * vertSpace + m_Up * vertSpace; v2 += m_Right * vertSpace + m_Up * vertSpace; v3 += m_Right * vertSpace - m_Up * vertSpace; v4 += left * vertSpace - m_Up * vertSpace; m_Volume.exvertices.Add(v1); m_Volume.exvertices.Add(v2); m_Volume.exvertices.Add(v3); m_Volume.exvertices.Add(v4); // -- m_Neighbors[0].node = m_Neighbors[1].node = m_Neighbors[2].node = m_Neighbors[3].node = null; m_Neighbors[0].isFixed = m_Neighbors[1].isFixed = m_Neighbors[2].isFixed = m_Neighbors[3].isFixed = false; m_Children[0] = m_Children[1] = m_Children[2] = m_Children[3] = null; m_NeedsRejoinCount = 0; m_HasChildren = false; m_NeedsReedge = true; m_NeedsTerrain = true; m_GapFixMask = 15; m_NormalMapTex = null; m_Normal = m_Parent.m_Normal; m_Up = m_Parent.m_Up; m_Center = (volume.vertices[0] + volume.vertices[1] + volume.vertices[2] + volume.vertices[3]) / 4; m_SCenter = m_Center; m_SCenter = CMath.ProjectToSphere(m_SCenter, m_Planet.m_Radius); m_SUp = m_SCenter; m_SUp.Normalize(); m_Front = m_Parent.m_Front; m_SFront = Vector3.Lerp(m_SVolume.vertices[0], m_SVolume.vertices[1], 0.5f) - m_SCenter; m_SFront.Normalize(); m_Plane = m_Parent.m_Plane; m_Right = m_Parent.m_Right; }
public static void ShapeNoise(RenderTexture noiseRT, Texture2D shapeTex, CBoundingVolume volume) { CGlobal global = CGlobal.GetInstance(); // actually, do nothing }
// uses CPU to accumulate layers of noise public static void ExecuteCPU(CNoiseLayer layer, Color[] heights, int w, int h, CBoundingVolume volume, bool flip, float planetRadius) { CGlobal global = CGlobal.GetInstance(); // actually, do nothing. }
public void RenderQuadVolumeExUv(int width, int height, int sourceWidth, Material material, CBoundingVolume volume, bool flip) { GL.PushMatrix(); GL.LoadOrtho(); GL.Viewport(new Rect(0, 0, width, height)); material.SetPass(0); float zero = 1.0f / sourceWidth; float one = 1 - zero; Vector3 v1 = volume.vertices[0]; Vector3 uv1 = new Vector3(zero, zero, 0); Vector3 v2 = volume.vertices[3]; Vector3 uv2 = new Vector3(zero, one, 0); Vector3 v3 = volume.vertices[2]; Vector3 uv3 = new Vector3(one, one, 0); Vector3 v4 = volume.vertices[1]; Vector3 uv4 = new Vector3(one, zero, 0); GL.Begin(GL.QUADS); if (flip) { GL.MultiTexCoord(0, new Vector3(0, 1, 0)); GL.MultiTexCoord(1, v1); GL.MultiTexCoord(2, uv1); GL.Vertex3(-1, 1, 0); GL.MultiTexCoord(0, new Vector3(0, 0, 0)); GL.MultiTexCoord(1, v2); GL.MultiTexCoord(2, uv2); GL.Vertex3(-1, -1, 0); GL.MultiTexCoord(0, new Vector3(1, 0, 0)); GL.MultiTexCoord(1, v3); GL.MultiTexCoord(2, uv3); GL.Vertex3(1, -1, 0); GL.MultiTexCoord(0, new Vector3(1, 1, 0)); GL.MultiTexCoord(1, v4); GL.MultiTexCoord(2, uv4); GL.Vertex3(1, 1, 0); } else { GL.MultiTexCoord(0, new Vector3(0, 0, 0)); GL.MultiTexCoord(1, v1); GL.MultiTexCoord(2, uv1); GL.Vertex3(-1, 1, 0); GL.MultiTexCoord(0, new Vector3(0, 1, 0)); GL.MultiTexCoord(1, v2); GL.MultiTexCoord(2, uv2); GL.Vertex3(-1, -1, 0); GL.MultiTexCoord(0, new Vector3(1, 1, 0)); GL.MultiTexCoord(1, v3); GL.MultiTexCoord(2, uv3); GL.Vertex3(1, -1, 0); GL.MultiTexCoord(0, new Vector3(1, 0, 0)); GL.MultiTexCoord(1, v4); GL.MultiTexCoord(2, uv4); GL.Vertex3(1, 1, 0); } GL.End(); GL.PopMatrix(); }
public void RenderQuadVolumeExCoord(int width, int height, Material material, CBoundingVolume volume, bool flip) { GL.PushMatrix(); GL.LoadOrtho(); GL.Viewport(new Rect(0, 0, width, height)); material.SetPass(0); Vector3 v1 = volume.exvertices[0]; Vector3 uv1 = volume.uvs[0]; Vector3 v2 = volume.exvertices[3]; Vector3 uv2 = volume.uvs[3]; Vector3 v3 = volume.exvertices[2]; Vector3 uv3 = volume.uvs[2]; Vector3 v4 = volume.exvertices[1]; Vector3 uv4 = volume.uvs[1]; GL.Begin(GL.QUADS); if (flip) { GL.MultiTexCoord(0, new Vector3(0, 1, 0)); GL.MultiTexCoord(1, v1); GL.MultiTexCoord(2, uv1); GL.Vertex3(-1, 1, 0); GL.MultiTexCoord(0, new Vector3(0, 0, 0)); GL.MultiTexCoord(1, v2); GL.MultiTexCoord(2, uv2); GL.Vertex3(-1, -1, 0); GL.MultiTexCoord(0, new Vector3(1, 0, 0)); GL.MultiTexCoord(1, v3); GL.MultiTexCoord(2, uv3); GL.Vertex3(1, -1, 0); GL.MultiTexCoord(0, new Vector3(1, 1, 0)); GL.MultiTexCoord(1, v4); GL.MultiTexCoord(2, uv4); GL.Vertex3(1, 1, 0); } else { GL.MultiTexCoord(0, new Vector3(0, 0, 0)); GL.MultiTexCoord(1, v1); GL.MultiTexCoord(2, uv1); GL.Vertex3(-1, 1, 0); GL.MultiTexCoord(0, new Vector3(0, 1, 0)); GL.MultiTexCoord(1, v2); GL.MultiTexCoord(2, uv2); GL.Vertex3(-1, -1, 0); GL.MultiTexCoord(0, new Vector3(1, 1, 0)); GL.MultiTexCoord(1, v3); GL.MultiTexCoord(2, uv3); GL.Vertex3(1, -1, 0); GL.MultiTexCoord(0, new Vector3(1, 0, 0)); GL.MultiTexCoord(1, v4); GL.MultiTexCoord(2, uv4); GL.Vertex3(1, 1, 0); } GL.End(); GL.PopMatrix(); }