Skip to content

Commit

Permalink
Merge pull request #293 from Kopernicus/normals
Browse files Browse the repository at this point in the history
Normals
StollD authored Jun 1, 2018
2 parents 71becc4 + 5fd1f11 commit 9325659
Showing 2 changed files with 36 additions and 20 deletions.
2 changes: 1 addition & 1 deletion src/Kopernicus/UI/PlanetTextureExporter.cs
Original file line number Diff line number Diff line change
@@ -222,7 +222,7 @@ public static IEnumerator UpdateTextures(CelestialBody celestialBody, TextureOpt
if (options.ExportNormal)
{
// Bump to Normal Map
Texture2D normalMap = Utility.BumpToNormalMap(heightMap, options.NormalStrength);
Texture2D normalMap = Utility.BumpToNormalMap(heightMap, pqsVersion.radius, options.NormalStrength);
yield return null;

if (options.SaveToDisk)
54 changes: 35 additions & 19 deletions src/Kopernicus/Utility.cs
Original file line number Diff line number Diff line change
@@ -107,11 +107,11 @@ public static void CopyObjectProperties<T>(T source, T destination, Boolean log

System.Object sourceValue = property.GetValue(source, null);
System.Object destValue = property.GetValue(destination, null);

// Check if both values are equal
if (sourceValue == destValue)
continue;

// Log the fields
if (log)
{
@@ -341,7 +341,7 @@ public static void UpdateScaledMesh(GameObject scaledVersion, PQS pqs, Celestial
// Compute scale between Jool and this body
Single scale = (Single)(body.Radius / rJool);
scaledVersion.transform.localScale = new Vector3(scale, scale, scale);

// Attempt to load a cached version of the scale space
String cacheDirectory = KSPUtil.ApplicationRootPath + "GameData/" + path;
if (!String.IsNullOrEmpty(cacheFile))
@@ -390,11 +390,11 @@ public static Mesh ComputeScaledSpaceMesh(CelestialBody body, PQS pqs)
{
// We need to get the body for Jool (to steal it's mesh)
const Double rScaledJool = 1000.0f;
Double rMetersToScaledUnits = (Single) (rScaledJool / body.Radius);
Double rMetersToScaledUnits = (Single)(rScaledJool / body.Radius);

// Generate a duplicate of the Jool mesh
Mesh mesh = DuplicateMesh(Templates.ReferenceGeosphere);

Logger.Active.Log(body);
Logger.Active.Log(pqs);
Logger.Active.Log(body.pqsController);
@@ -425,7 +425,7 @@ public static Mesh ComputeScaledSpaceMesh(CelestialBody body, PQS pqs)
PQS pqsOcean = pqs.ChildSpheres?.FirstOrDefault();

// Deactivate blacklisted Mods
Type[] blacklist = {typeof(PQSMod_OnDemandHandler)};
Type[] blacklist = { typeof(PQSMod_OnDemandHandler) };
foreach (PQSMod mod in pqsVersion.GetComponentsInChildren<PQSMod>(true)
.Where(m => m.enabled && blacklist.Contains(m.GetType())))
{
@@ -504,7 +504,7 @@ public static Mesh ComputeScaledSpaceMesh(CelestialBody body, PQS pqs)
}

// Adjust the displacement
vertices[i] = direction * (Single) (vertex.vertHeight * rMetersToScaledUnits);
vertices[i] = direction * (Single)(vertex.vertHeight * rMetersToScaledUnits);
}
mesh.vertices = vertices;
mesh.RecalculateNormals();
@@ -774,22 +774,38 @@ public static Mesh DeserializeMesh(String path)
return m;
}

// Credit goes to Kragrathea.
public static Texture2D BumpToNormalMap(Texture2D source, Single strength)
// Credit goes to Sigma88.
public static Texture2D BumpToNormalMap(Texture2D source, Double radius, Single strength)
{
strength = Mathf.Clamp(strength, 0.0F, 10.0F);
double dS = radius * 2 * Math.PI / source.width;

if (!(strength > 0)) strength = 1;

Texture2D result = new Texture2D(source.width, source.height, TextureFormat.ARGB32, true);
for (Int32 by = 0; by < result.height; by++)
{
for (Int32 bx = 0; bx < result.width; bx++)
{
Single xLeft = source.GetPixel(bx - 1, by).grayscale * strength;
Single xRight = source.GetPixel(bx + 1, by).grayscale * strength;
Single yUp = source.GetPixel(bx, by - 1).grayscale * strength;
Single yDown = source.GetPixel(bx, by + 1).grayscale * strength;
Single xDelta = (xLeft - xRight + 1) * 0.5f;
Single yDelta = (yUp - yDown + 1) * 0.5f;
result.SetPixel(bx, by, new Color(yDelta, yDelta, yDelta, xDelta));
if (by == 0 || by == result.height - 1 || source.GetPixel(bx, by).r == 0)
{
result.SetPixel(bx, by, new Color(0.5f, 0.5f, 0.5f, 0.5f));
}
else
{
int xN = (bx + result.width - 1) % result.width;
int xP = (bx + result.width + 1) % result.width;

int yN = by - 1;
int yP = by + 1;

float dX = source.GetPixel(xP, by).r - source.GetPixel(xN, by).r;
float dY = source.GetPixel(bx, yP).r - source.GetPixel(bx, yN).r;

double slopeX = (1 + dX / Math.Pow(dX * dX + dS * dS, 0.5) * strength) / 2;
double slopeY = (1 - dY / Math.Pow(dY * dY + dS * dS, 0.5) * strength) / 2;

result.SetPixel(bx, by, new Color((float)slopeY, (float)slopeY, (float)slopeY, (float)slopeX));
}
}
}
result.Apply();
@@ -964,7 +980,7 @@ public static void RemoveModsOfType(List<Type> types, PQS p, List<Type> blacklis
}
}
cpMods.Remove(delMod);

// If no mod is left, delete the game object too
GameObject gameObject = delMod.gameObject;
UnityEngine.Object.DestroyImmediate(delMod);
@@ -1081,4 +1097,4 @@ public static void DoRecursive<T>(T start, Func<T, IEnumerable<T>> selector, Act
DoRecursive<T, Object>(start, selector, tout => false, tin => { action(tin); return null; });
}
}
}
}

0 comments on commit 9325659

Please sign in to comment.