Add rock, make materials work, probably use less memory

This commit is contained in:
xen-42 2025-02-15 01:18:50 -05:00
parent d770cc6bd3
commit 06fd45e83e
11 changed files with 107 additions and 37 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 KiB

View File

@ -87,10 +87,6 @@ namespace NewHorizons.Builder.Body
{
config.ProcGen = belt.procGen;
config.ProcGen.scale = size;
if (belt.procGen.color == null)
{
config.ProcGen.color = new MColor(126, 94, 73);
}
}
else
{
@ -100,7 +96,7 @@ namespace NewHorizons.Builder.Body
color = new MColor(126, 94, 73)
};
}
config.AmbientLights = new[] { new AmbientLightModule() { outerRadius = size * 1.2f, intensity = 0.6f } };
config.AmbientLights = new[] { new AmbientLightModule() { outerRadius = size * 1.2f, intensity = 0.1f } };
var asteroid = new NewHorizonsBody(config, mod);
PlanetCreationHandler.GenerateBody(asteroid);

View File

@ -100,6 +100,11 @@ namespace NewHorizons.Builder.Body.Geometry
mesh.normals = normals;
mesh.uv = uvs;
mesh.RecalculateBounds();
// Unity recalculate normals does not support smooth normals
//mesh.RecalculateNormals();
mesh.RecalculateTangents();
return mesh;
}

View File

@ -11,7 +11,7 @@ namespace NewHorizons.Builder.Body
{
public static class HeightMapBuilder
{
public static Shader PlanetShader;
private static Shader _planetShader;
// I hate nested functions okay
private static IModBehaviour _currentMod;
@ -62,7 +62,7 @@ namespace NewHorizons.Builder.Body
cubeSphere.SetActive(false);
cubeSphere.transform.SetParent(sector?.transform ?? planetGO.transform, false);
if (PlanetShader == null) PlanetShader = AssetBundleUtilities.NHAssetBundle.LoadAsset<Shader>("Assets/Shaders/SphereTextureWrapperTriplanar.shader");
if (_planetShader == null) _planetShader = AssetBundleUtilities.NHAssetBundle.LoadAsset<Shader>("Assets/Shaders/SphereTextureWrapperTriplanar.shader");
var stretch = module.stretch != null ? (Vector3)module.stretch : Vector3.one;
@ -115,7 +115,7 @@ namespace NewHorizons.Builder.Body
LODCubeSphere.AddComponent<MeshFilter>().mesh = CubeSphere.Build(resolution, heightMap, module.minHeight, module.maxHeight, stretch);
var cubeSphereMR = LODCubeSphere.AddComponent<MeshRenderer>();
var material = new Material(PlanetShader);
var material = new Material(_planetShader);
cubeSphereMR.material = material;
material.name = textureMap.name;

View File

@ -2,18 +2,47 @@ using NewHorizons.Builder.Body.Geometry;
using NewHorizons.External.Modules;
using NewHorizons.Utility;
using NewHorizons.Utility.Files;
using OWML.Common;
using System.Collections.Generic;
using UnityEngine;
namespace NewHorizons.Builder.Body
{
public static class ProcGenBuilder
{
private static Material quantumMaterial;
private static Material iceMaterial;
private static Material _material;
private static Shader _planetShader;
public static GameObject Make(GameObject planetGO, Sector sector, ProcGenModule module)
private static Dictionary<ProcGenModule, Material> _materialCache = new();
public static void ClearCache()
{
if (quantumMaterial == null) quantumMaterial = SearchUtilities.FindResourceOfTypeAndName<Material>("Rock_QM_EyeRock_mat");
if (iceMaterial == null) iceMaterial = SearchUtilities.FindResourceOfTypeAndName<Material>("Rock_BH_IceSpike_mat");
foreach (var material in _materialCache.Values)
{
Object.Destroy(material);
}
_materialCache.Clear();
}
private static Material MakeMaterial()
{
var material = new Material(_planetShader);
var keyword = "BASE_TILE";
var prefix = "_BaseTile";
material.SetFloat(prefix, 1);
material.EnableKeyword(keyword);
material.SetTexture("_BlendMap", ImageUtilities.MakeSolidColorTexture(1, 1, Color.white));
return material;
}
public static GameObject Make(IModBehaviour mod, GameObject planetGO, Sector sector, ProcGenModule module)
{
if (_planetShader == null) _planetShader = AssetBundleUtilities.NHAssetBundle.LoadAsset<Shader>("Assets/Shaders/SphereTextureWrapperTriplanar.shader");
if (_material == null) _material = MakeMaterial();
var icosphere = new GameObject("Icosphere");
icosphere.SetActive(false);
@ -27,28 +56,51 @@ namespace NewHorizons.Builder.Body
var cubeSphereMR = icosphere.AddComponent<MeshRenderer>();
Material material;
var colour = module.color?.ToColor() ?? Color.white;
if (!_materialCache.TryGetValue(module, out var material))
{
material = new Material(_material);
material.name = planetGO.name;
if (module.material == ProcGenModule.Material.Default)
{
if (!string.IsNullOrEmpty(module.texturePath))
{
material.SetTexture($"_BaseTileAlbedo", ImageUtilities.GetTexture(mod, module.texturePath, wrap: true));
}
else
{
material.mainTexture = ImageUtilities.MakeSolidColorTexture(1, 1, module.color?.ToColor() ?? Color.white);
}
}
else
{
switch (module.material)
{
case ProcGenModule.Material.Ice:
material = iceMaterial;
material.SetTexture($"_BaseTileAlbedo", ImageUtilities.GetTexture(Main.Instance, "Assets/textures/Ice.png", wrap: true));
break;
case ProcGenModule.Material.Quantum:
material = quantumMaterial;
material.SetTexture($"_BaseTileAlbedo", ImageUtilities.GetTexture(Main.Instance, "Assets/textures/Quantum.png", wrap: true));
break;
case ProcGenModule.Material.Rock:
material.SetTexture($"_BaseTileAlbedo", ImageUtilities.GetTexture(Main.Instance, "Assets/textures/Rocks.png", wrap: true));
break;
default:
// Todo: copy stuff from heightmap builder such as triplanar
material = new Material(HeightMapBuilder.PlanetShader);
material.name = planetGO.name;
material.mainTexture = ImageUtilities.TintImage(ImageUtilities.ClearTexture(1, 1), colour);
material.SetFloat("_Smoothness", 0.1f);
material.SetFloat("_Metallic", 0.1f);
break;
}
material.color = colour;
cubeSphereMR.material = material;
material.SetFloat($"_BaseTileScale", 5 / module.scale);
if (module.color != null)
{
material.color = module.color.ToColor();
}
}
material.SetFloat("_Smoothness", 0.1f);
material.SetFloat("_Metallic", 0.1f);
_materialCache[module] = material;
}
cubeSphereMR.sharedMaterial = material;
var cubeSphereMC = icosphere.AddComponent<MeshCollider>();
cubeSphereMC.sharedMesh = mesh;

View File

@ -162,7 +162,7 @@ namespace NewHorizons.Builder.Body
GameObject procGen = null;
if (body.Config.ProcGen != null)
{
procGen = ProcGenBuilder.Make(proxy, null, body.Config.ProcGen);
procGen = ProcGenBuilder.Make(body.Mod, proxy, null, body.Config.ProcGen);
if (realSize < body.Config.ProcGen.scale) realSize = body.Config.ProcGen.scale;
}

View File

@ -9,12 +9,26 @@ namespace NewHorizons.External.Modules
[JsonObject]
public class ProcGenModule
{
public MColor color;
/// <summary>
/// Scale height of the proc gen.
/// </summary>
[Range(0, double.MaxValue)] public float scale;
/// <summary>
/// Ground color, only applied if no texture or material is chosen.
/// </summary>
public MColor color;
/// <summary>
/// Can pick a preset material with a texture from the base game. Does not work with color.
/// </summary>
public Material material;
/// <summary>
/// Can use a custom texture. Does not work with material or color.
/// </summary>
public string texturePath;
[JsonConverter(typeof(StringEnumConverter))]
public enum Material
{
@ -22,7 +36,9 @@ namespace NewHorizons.External.Modules
[EnumMember(Value = @"ice")] Ice = 1,
[EnumMember(Value = @"quantum")] Quantum = 2
[EnumMember(Value = @"quantum")] Quantum = 2,
[EnumMember(Value = @"rock")] Rock = 3
}
}
}

View File

@ -581,7 +581,7 @@ namespace NewHorizons.Handlers
GameObject procGen = null;
if (body.Config.ProcGen != null)
{
procGen = ProcGenBuilder.Make(go, sector, body.Config.ProcGen);
procGen = ProcGenBuilder.Make(body.Mod, go, sector, body.Config.ProcGen);
}
if (body.Config.Star != null)

View File

@ -308,6 +308,7 @@ namespace NewHorizons
ImageUtilities.ClearCache();
AudioUtilities.ClearCache();
AssetBundleUtilities.ClearCache();
ProcGenBuilder.ClearCache();
}
IsSystemReady = false;