private Vector3 GetVertexTranslationAtIndex(Index2D i) { float translationX = 0; float translationY = 0; float translationZ = 0; translationX = -TotalTileCountX * VertexSpacing / 2; if (i.X < SurfaceMinIndex.X) { translationX += (SurfaceMinIndex.X - i.X) * VertexSpacing; } else if (i.X > SurfaceMaxIndex.X) { translationX += (SurfaceMaxIndex.X - i.X) * VertexSpacing; } translationZ = -TotalTileCountZ * VertexSpacing / 2; if (i.Z < SurfaceMinIndex.Z) { translationZ += (SurfaceMinIndex.Z - i.Z) * VertexSpacing; } else if (i.Z > SurfaceMaxIndex.Z) { translationZ += (SurfaceMaxIndex.Z - i.Z) * VertexSpacing; } if (WillShiftVertexInHexagonTiling(i)) { translationX += VertexSpacing * 0.5f; } return(new Vector3(translationX, translationY, translationZ)); }
private bool WillShiftVertexInHexagonTiling(Index2D i) { return(TilingMode == SurfaceTilingMode.Hexagon && Utilities.IsInRangeExclusive(i.X, SurfaceMinIndex.X, SurfaceMaxIndex.X) && Utilities.IsInRange(i.Z, SurfaceMinIndex.Z, SurfaceMaxIndex.Z) && i.Z % 2 == 0); }
private void GenerateVertexColorAtIndex(Index2D i) { Color c = Color.white; bool isUnderground = !Utilities.IsInRange(i.X, SurfaceMinIndex.X - 1, SurfaceMaxIndex.X + 1) || !Utilities.IsInRange(i.Z, SurfaceMinIndex.Z - 1, SurfaceMaxIndex.Z + 1); if (isUnderground) { c = UndergroundColor; } else { Vector3 v = vertices[i.Z][i.X]; float heightFraction = Utilities.GetFraction(v.y - BaseHeight, 0, SurfaceMaxHeight); Color cbh = ColorByHeight.Evaluate(heightFraction); Vector3 normal = EvaluateNormalAtIndex(i); float normalDotUp = Vector3.Dot(normal, Vector3.up); Color cbn = ColorByNormal.Evaluate(normalDotUp); float blendFraction = ColorBlendFraction.Evaluate(heightFraction).a; c = Vector4.Lerp(cbh, cbn, blendFraction); } int cIndex = To1DIndex(i.X, i.Z); vertexColors[cIndex] = c; }
private float GetGroundThicknessNoiseValueAtIndex(Index2D i) { Vector2 noiseOrigin = GroundThicknessVariationSeed * Vector2.one; Vector2 noiseCoord = noiseOrigin + new Vector2(i.X, i.Z) * GroundThicknessNoiseStep; float noiseValue = Mathf.PerlinNoise(noiseCoord.x, noiseCoord.y); return(noiseValue); }
private float GetVertexHeight(Index2D i) { if (!IsSurfaceVertex(i)) { return(GetUndergroundVertexHeight(i)); } else { return(GetSurfaceVertexHeight(i)); } }
private void GenerateVertexUvAtIndex(Index2D i) { float xOffset = 0; if (WillShiftVertexInHexagonTiling(i)) { xOffset = 0.5f; } Vector2 uv = new Vector2( Utilities.GetFraction(i.X + xOffset, 0, VerticesArrayLength.X - 1), Utilities.GetFraction(i.Z, 0, VerticesArrayLength.Z - 1)); uvCoords[To1DIndex(i.X, i.Z)] = uv; }
private void GenerateVertexPositionAtIndex(Index2D i) { float vertexX = 0; float vertexY = 0; float vertexZ = 0; Vector3 translation = GetVertexTranslationAtIndex(i); vertexX = i.X * VertexSpacing + translation.x; vertexY = GetVertexHeight(i); vertexZ = i.Z * VertexSpacing + translation.z; vertices[i.Z][i.X] = new Vector3(vertexX, vertexY, vertexZ); }
private Vector3 EvaluateNormalAtIndex(Index2D i) { Vector3 normal = Vector3.zero; Vector3 normalTopLeft = Vector3.zero; if (Utilities.IsInRange(i.X, 0, VerticesArrayLength.X - 2) && Utilities.IsInRange(i.Z, 0, VerticesArrayLength.Z - 2)) { normalTopLeft = Vector3.Cross( vertices[i.Z + 1][i.X], vertices[i.Z][i.X + 1]); } Vector3 normalTopRight = Vector3.zero; if (Utilities.IsInRange(i.X, 1, VerticesArrayLength.X - 1) && Utilities.IsInRange(i.Z, 0, VerticesArrayLength.Z - 2)) { normalTopRight = Vector3.Cross( vertices[i.Z][i.X - 1], vertices[i.Z + 1][i.X]); } Vector3 normalBottomRight = Vector3.zero; if (Utilities.IsInRange(i.X, 1, VerticesArrayLength.X - 1) && Utilities.IsInRange(i.Z, 1, VerticesArrayLength.Z - 1)) { normalBottomRight = Vector3.Cross( vertices[i.Z - 1][i.X], vertices[i.Z][i.X - 1]); } Vector3 normalBottomLeft = Vector3.zero; if (Utilities.IsInRange(i.X, 0, VerticesArrayLength.X - 2) && Utilities.IsInRange(i.Z, 1, VerticesArrayLength.Z - 1)) { normalBottomLeft = Vector3.Cross( vertices[i.Z][i.X + 1], vertices[i.Z - 1][i.X]); } normal = (normalTopLeft + normalTopRight + normalBottomRight + normalBottomLeft).normalized; return(normal); }
private float GetSurfaceNoiseValueAtIndex(Index2D i) { if (Roughness == 0) { return(1); } Vector2 noiseOrigin = RoughnessSeed * Vector2.one; Vector2 noiseCoord = noiseOrigin + new Vector2(i.X, i.Z) * Roughness * NOISE_STEP_MULTIPLIER; if (WillShiftVertexInHexagonTiling(i)) { noiseCoord.x += 0.5f * Roughness * NOISE_STEP_MULTIPLIER; } float noiseValue = Mathf.PerlinNoise(noiseCoord.x, noiseCoord.y); return(noiseValue); }
private void GenerateVerticesInfo() { vertices = Utilities.CreateJaggedArray <Vector3>(VerticesArrayLength.Z, VerticesArrayLength.X); vertexColors = new Color[VerticesArrayLength.Z * VerticesArrayLength.X]; uvCoords = new Vector2[VerticesArrayLength.Z * VerticesArrayLength.X]; for (int z = SurfaceMinIndex.Z; z <= SurfaceMaxIndex.Z; ++z) { for (int x = SurfaceMinIndex.X; x <= SurfaceMaxIndex.X; ++x) { Index2D i = new Index2D(x, z); GenerateVertexPositionAtIndex(i); } } for (int z = 0; z < VerticesArrayLength.Z; ++z) { for (int x = 0; x < VerticesArrayLength.X; ++x) { Index2D i = new Index2D(x, z); if (!IsSurfaceVertex(i)) { GenerateVertexPositionAtIndex(i); } } } for (int z = 0; z < VerticesArrayLength.Z; ++z) { for (int x = 0; x < VerticesArrayLength.X; ++x) { Index2D i = new Index2D(x, z); if (UseVertexColor) { GenerateVertexColorAtIndex(i); } if (ShouldUnwrapUv) { GenerateVertexUvAtIndex(i); } } } }
private float GetSurfaceVertexHeight(Index2D i) { float heightMapMultiplier = 1; if (HeightMap != null) { float xOffset = 0; if (WillShiftVertexInHexagonTiling(i)) { xOffset = 0.5f; } Vector2 uv = new Vector2( Utilities.GetFraction(i.X + xOffset, SurfaceMinIndex.X, SurfaceMaxIndex.X), Utilities.GetFraction(i.Z, SurfaceMinIndex.Z, SurfaceMaxIndex.Z)); heightMapMultiplier = HeightMap.GetPixelBilinear(uv.x, uv.y).a; } float noiseMultiplier = GetSurfaceNoiseValueAtIndex(i); return(BaseHeight + SurfaceMaxHeight * heightMapMultiplier * noiseMultiplier); }
private float GetUndergroundVertexHeight(Index2D i) { if (!Utilities.IsInRangeExclusive(i.X, 0, VerticesArrayLength.X - 1) || !Utilities.IsInRangeExclusive(i.Z, 0, VerticesArrayLength.Z - 1)) { return(0); } else { Index2D nearestSurfaceVertexIndex = new Index2D( Mathf.Clamp(i.X, SurfaceMinIndex.X, SurfaceMaxIndex.X), Mathf.Clamp(i.Z, SurfaceMinIndex.Z, SurfaceMaxIndex.Z)); Vector3 nearestSurfaceVertexPosition = vertices[nearestSurfaceVertexIndex.Z][nearestSurfaceVertexIndex.X]; float thicknessVariation = 0; if (GroundThicnknessVariation > 0) { float noiseValue = GetGroundThicknessNoiseValueAtIndex(nearestSurfaceVertexIndex); thicknessVariation = noiseValue * GroundThickness * GroundThicnknessVariation; } float height = nearestSurfaceVertexPosition.y - GroundThickness + thicknessVariation; return(height); } }
private bool IsSurfaceVertex(Index2D i) { return(Utilities.IsInRange(i.X, SurfaceMinIndex.X, SurfaceMaxIndex.X) && Utilities.IsInRange(i.Z, SurfaceMinIndex.Z, SurfaceMaxIndex.Z)); }