Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ public static class BasisSettingsDefaults

public static BasisSettingsBinding<float> CacheMaxSizeGB = new("cachemaxsizegb", new BasisPlatformDefault<float>(128));

public static BasisSettingsBinding<bool> SharedContentPreviews = new("sharedcontentpreviews", new BasisPlatformDefault<bool>(false));

public static BasisSettingsBinding<float> AvatarMeshLOD = new("avatarmeshlod", new BasisPlatformDefault<float>
{
windows = 0.05f,
Expand Down Expand Up @@ -631,6 +633,7 @@ public static void LoadAll()
// LOD / Download limits
AvatarDownloadSize.LoadBindingValue();
CacheMaxSizeGB.LoadBindingValue();
SharedContentPreviews.LoadBindingValue();
AvatarMeshLOD.LoadBindingValue();
GlobalMeshLOD.LoadBindingValue();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ public static PanelTabPage StorageTab(PanelTabGroup tabGroup)
PanelSlider.SliderSettings.Advanced("Avatar Download Size", 5, 1024, false, 0, ValueDisplayMode.MemorySize),
BasisSettingsDefaults.AvatarDownloadSize);

PanelToggle sharedPreviewToggle = PanelToggle.CreateNewEntry(downloadGroup.ContentParent);
sharedPreviewToggle.Descriptor.SetTitle("Load Shared Content Previews");
sharedPreviewToggle.Descriptor.SetDescription("Downloads shared content in the background and renders a fitted LOD3-style preview inside the share sphere.");
sharedPreviewToggle.AssignBinding(BasisSettingsDefaults.SharedContentPreviews);

// Cache size limit slider (lightweight, no file I/O)
PanelElementDescriptor limitGroup =
PanelElementDescriptor.CreateNew(PanelElementDescriptor.ElementStyles.Group, container);
Expand Down Expand Up @@ -137,5 +142,6 @@ private static void ResetStorageDefaults()
{
BasisSettingsDefaults.AvatarDownloadSize.ResetToDefault();
BasisSettingsDefaults.CacheMaxSizeGB.ResetToDefault();
BasisSettingsDefaults.SharedContentPreviews.ResetToDefault();
}
}
155 changes: 86 additions & 69 deletions Basis/Packages/com.basis.framework/Drivers/Common/BasisAvatarDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -548,98 +548,115 @@ public static bool TryGetTextureWithScaleAndOffset(Material mat, string property
result = new BasisTexTransform(tex, scale, offset);
return true;
}
public static void MaterialCorrection(SkinnedMeshRenderer renderer, Shader fallbackUrpShader)
private static bool TryCreateFallbackMaterial(Material mat, Shader fallbackUrpShader, out Material fixedMat)
{
if (renderer == null)
fixedMat = null;

if (mat == null)
{
return;
return false;
}

var materials = renderer.sharedMaterials;
if (materials == null || materials.Length == 0)
var shader = mat.shader;
if (shader == null)
{
return;
return false;
}

if (fallbackUrpShader == null)
{
Debug.LogWarning("MaterialCorrection: fallbackUrpShader is null, cannot swap shaders.");
return;
return false;
}

bool anyChanged = false;

for (int mi = 0; mi < materials.Length; mi++)
bool shaderBroken = !shader.isSupported || (!string.IsNullOrEmpty(shader.name) && shader.name.Contains("InternalErrorShader"));
if (!shaderBroken)
{
var mat = materials[mi];
if (mat == null)
{
continue;
}
return false;
}

var shader = mat.shader;
if (shader == null)
{
continue;
}
bool hasAlbedo = TryGetFirstTextureWithScaleAndOffset(mat, AlbedoProps, out BasisTexTransform albedo, out _);
bool hasNormal = TryGetFirstTextureWithScaleAndOffset(mat, NormalProps, out BasisTexTransform normal, out _);
bool hasMetal = TryGetFirstTextureWithScaleAndOffset(mat, MetallicProps, out BasisTexTransform metal, out _);
bool hasOcc = TryGetFirstTextureWithScaleAndOffset(mat, OcclusionProps, out BasisTexTransform occ, out _);
bool hasColor = TryGetFirstColor(mat, out Color baseColor, out _);
fixedMat = new Material(fallbackUrpShader)
{
name = mat.name + " (Fixed)"
};
if (hasAlbedo)
{
fixedMat.SetTexture("_BaseMap", albedo.texture);
fixedMat.SetTextureScale("_BaseMap", albedo.scale);
fixedMat.SetTextureOffset("_BaseMap", albedo.offset);
}
if (hasColor)
{
fixedMat.SetColor("_BaseColor", baseColor);
}
if (hasNormal)
{
fixedMat.EnableKeyword("_NORMALMAP");
fixedMat.SetTexture("_BumpMap", normal.texture);
fixedMat.SetTextureScale("_BumpMap", normal.scale);
fixedMat.SetTextureOffset("_BumpMap", normal.offset);
fixedMat.SetFloat("_BumpScale", 0.2f);
}
if (hasMetal)
{
fixedMat.EnableKeyword("_METALLICSPECGLOSSMAP");
fixedMat.SetTexture("_MetallicGlossMap", metal.texture);
fixedMat.SetTextureScale("_MetallicGlossMap", metal.scale);
fixedMat.SetTextureOffset("_MetallicGlossMap", metal.offset);
}
fixedMat.SetFloat("_Metallic", 0.2f);
fixedMat.SetFloat("_Smoothness", 0.2f);
if (hasOcc)
{
fixedMat.SetTexture("_OcclusionMap", occ.texture);
fixedMat.SetTextureScale("_OcclusionMap", occ.scale);
fixedMat.SetTextureOffset("_OcclusionMap", occ.offset);
fixedMat.SetFloat("_OcclusionStrength", 0.2f);
}
return true;
}
public static void MaterialCorrection(Renderer renderer, Shader fallbackUrpShader, List<Material> createdMaterials = null)
{
if (renderer == null)
{
return;
}

bool shaderBroken = !shader.isSupported || (!string.IsNullOrEmpty(shader.name) && shader.name.Contains("InternalErrorShader"));
var materials = renderer.sharedMaterials;
if (materials == null || materials.Length == 0)
{
return;
}

if (!shaderBroken)
{
continue;
}
bool hasAlbedo = TryGetFirstTextureWithScaleAndOffset(mat, AlbedoProps, out BasisTexTransform albedo, out string albedoProp);
bool hasNormal = TryGetFirstTextureWithScaleAndOffset(mat, NormalProps, out BasisTexTransform normal, out string normalProp);
bool hasMetal = TryGetFirstTextureWithScaleAndOffset(mat, MetallicProps, out BasisTexTransform metal, out string metalProp);
bool hasOcc = TryGetFirstTextureWithScaleAndOffset(mat, OcclusionProps, out BasisTexTransform occ, out string occProp);
bool hasColor = TryGetFirstColor(mat, out Color baseColor, out string colorProp);
var fixedMat = new Material(fallbackUrpShader)
{
name = mat.name + " (Fixed)"
};
if (hasAlbedo)
{
fixedMat.SetTexture("_BaseMap", albedo.texture);
fixedMat.SetTextureScale("_BaseMap", albedo.scale);
fixedMat.SetTextureOffset("_BaseMap", albedo.offset);
}
if (hasColor)
{
fixedMat.SetColor("_BaseColor", baseColor);
}
if (hasNormal)
{
fixedMat.EnableKeyword("_NORMALMAP");
fixedMat.SetTexture("_BumpMap", normal.texture);
fixedMat.SetTextureScale("_BumpMap", normal.scale);
fixedMat.SetTextureOffset("_BumpMap", normal.offset);
fixedMat.SetFloat("_BumpScale", 0.2f);
}
if (hasMetal)
{
fixedMat.EnableKeyword("_METALLICSPECGLOSSMAP");
fixedMat.SetTexture("_MetallicGlossMap", metal.texture);
fixedMat.SetTextureScale("_MetallicGlossMap", metal.scale);
fixedMat.SetTextureOffset("_MetallicGlossMap", metal.offset);
}
fixedMat.SetFloat("_Metallic", 0.2f);
fixedMat.SetFloat("_Smoothness", 0.2f);
if (hasOcc)
bool anyChanged = false;
for (int mi = 0; mi < materials.Length; mi++)
{
if (TryCreateFallbackMaterial(materials[mi], fallbackUrpShader, out Material fixedMat))
{
fixedMat.SetTexture("_OcclusionMap", occ.texture);
fixedMat.SetTextureScale("_OcclusionMap", occ.scale);
fixedMat.SetTextureOffset("_OcclusionMap", occ.offset);

fixedMat.SetFloat("_OcclusionStrength", 0.2f);
materials[mi] = fixedMat;
createdMaterials?.Add(fixedMat);
anyChanged = true;
}
materials[mi] = fixedMat;
anyChanged = true;
}

if (anyChanged)
{
renderer.sharedMaterials = materials;
}
}
public static void MaterialCorrection(SkinnedMeshRenderer renderer, Shader fallbackUrpShader)
{
if (renderer == null)
{
return;
}

MaterialCorrection((Renderer)renderer, fallbackUrpShader, null);
}
}
}
Loading
Loading