Skip to content

Commit

Permalink
Fix venues shaders on OSX (again)
Browse files Browse the repository at this point in the history
Previously we were exporting shaders for OSX separately.
Unfortunately that does not guarantee that all shader variants were exported.
To mitigate that we now export materials instead. However to avoid
doubling of resulting yarground size we replace all textures with
dummy on export.
On load we fixup all the shaders to pick up from osx-specific subbundle
  • Loading branch information
Anton Romanov authored and theli-ua committed Feb 2, 2025
1 parent 4439beb commit d428b8f
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 24 deletions.
31 changes: 13 additions & 18 deletions Assets/Script/Gameplay/BackgroundManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using UnityEngine.Video;
using YARG.Core.Extensions;
using YARG.Core.IO;
using YARG.Core.Logging;
using YARG.Core.Venue;
using YARG.Helpers.Extensions;
using YARG.Settings;
Expand Down Expand Up @@ -63,27 +64,28 @@ private async UniTaskVoid Start()
{
case BackgroundType.Yarground:
var bundle = AssetBundle.LoadFromStream(result.Stream);
AssetBundle shaderBundle = null;
AssetBundle materialBundle = null;

// KEEP THIS PATH LOWERCASE
// Breaks things for other platforms, because Unity
var bg = (GameObject) await bundle.LoadAssetAsync<GameObject>(
BundleBackgroundManager.BACKGROUND_PREFAB_PATH.ToLowerInvariant());

#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
var metalShaders = new Dictionary<string, Shader>();
var metalMaterials = new Dictionary<string, Material>();

var shaderBundleData = (TextAsset)await bundle.LoadAssetAsync<TextAsset>(
var materialBundleData = (TextAsset)await bundle.LoadAssetAsync<TextAsset>(
"Assets/" + BundleBackgroundManager.BACKGROUND_SHADER_BUNDLE_NAME
);

if (shaderBundleData != null && shaderBundleData.bytes.Length > 0)
if (materialBundleData != null && materialBundleData.bytes.Length > 0)
{
shaderBundle = await AssetBundle.LoadFromMemoryAsync(shaderBundleData.bytes);
var allAssets = shaderBundle.LoadAllAssets<Shader>();
foreach (var shader in allAssets)
YargLogger.LogInfo("Found OSX material bundle for yarground");
materialBundle = await AssetBundle.LoadFromMemoryAsync(materialBundleData.bytes);
var allAssets = materialBundle.LoadAllAssets<Material>();
foreach (var material in allAssets)
{
metalShaders.Add(shader.name, shader);
metalMaterials.Add(material.name, material);
}

}
Expand All @@ -97,24 +99,17 @@ private async UniTaskVoid Start()
{
foreach (var material in renderer.sharedMaterials)
{
var shaderName = material.shader.name;
if (metalShaders.TryGetValue(shaderName, out var shader))
if (metalMaterials.TryGetValue(BundleBackgroundManager.BACKGOUND_OSX_MATERIAL_PREFIX + material.name, out var bundled_material))
{
// We found shader from Yarground
material.shader = shader;
}
else
{
// Fallback to try to find among builtin shaders
material.shader = Shader.Find(shaderName);
material.shader = bundled_material.shader;
}
}
}
#endif
var bgInstance = Instantiate(bg);
var bundleBackgroundManager = bgInstance.GetComponent<BundleBackgroundManager>();
bundleBackgroundManager.Bundle = bundle;
bundleBackgroundManager.ShaderBundle = shaderBundle;
bundleBackgroundManager.ShaderBundle = materialBundle;

// Destroy the default camera (venue has its own)
Destroy(_videoPlayer.targetCamera.gameObject);
Expand Down
34 changes: 28 additions & 6 deletions Assets/Script/Venue/BundleBackgroundManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class BundleBackgroundManager : MonoBehaviour
// DO NOT CHANGE THIS! It will break existing venues
public const string BACKGROUND_PREFAB_PATH = "Assets/_Background.prefab";
public const string BACKGROUND_SHADER_BUNDLE_NAME = "_metal_shaders.bytes";
public const string BACKGOUND_OSX_MATERIAL_PREFIX = "_metal_";

// DO NOT CHANGE the name of this! I *know* it doesn't follow naming conventions, but it will also break existing
// venues if we do change it.
Expand Down Expand Up @@ -58,9 +59,6 @@ public void ExportBackground()
_backgroundReference = gameObject;
string path = EditorUtility.SaveFilePanel("Save Background", string.Empty, "bg", "yarground");

var selectedBuildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup;
var activeBuildTarget = EditorUserBuildSettings.activeBuildTarget;

GameObject clonedBackground = null;


Expand All @@ -75,9 +73,28 @@ public void ExportBackground()
// for Mac as no other build target will include Metal shaders
// And we want our background to work everywhere
var shaderAssets = EditorUtility.CollectDependencies(new[] { gameObject })
.OfType<Shader>() // Only shader dependencices
.Select(shader => AssetDatabase.GetAssetPath(shader)) // Get asset path
.Where(assetPath => !assetPath.StartsWith("Packages/com.unity")) // Not builtins
.OfType<Material>() // Only material dependencices
.Select((mat, i) => {
// Create a clone
var matClone = new Material(mat);
// Avoid name collision
matClone.name = BACKGOUND_OSX_MATERIAL_PREFIX + mat.name;
// Drop all textures to not double resulting yarground in size
if (matClone.mainTexture != null)
{
matClone.mainTexture = Texture2D.whiteTexture;
}
foreach (var id in matClone.GetTexturePropertyNameIDs()) {
if (matClone.GetTexture(id) != null)
{
matClone.SetTexture(id, Texture2D.whiteTexture);
}
}
var assetPath = Path.Combine("Assets", matClone.name + ".mat");
AssetDatabase.CreateAsset(matClone, assetPath);

return assetPath;
})
.ToArray();

if (shaderAssets.Length > 0)
Expand All @@ -97,6 +114,11 @@ public void ExportBackground()
File.Move(filePath, Path.Combine(Application.dataPath, BACKGROUND_SHADER_BUNDLE_NAME));
AssetDatabase.Refresh();
}
// Now delete our material clones
foreach (var assetPath in shaderAssets)
{
AssetDatabase.DeleteAsset(assetPath);
}

clonedBackground = Instantiate(_backgroundReference.gameObject);

Expand Down

0 comments on commit d428b8f

Please sign in to comment.