Skip to content

Commit

Permalink
com.unity.cloud.gltfast@6.7.0
Browse files Browse the repository at this point in the history
## [6.7.0] - 2024-06-25

### Added
- (Import) Support for [materials variants extension](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_variants).
- Serialization support for material extensions IOR, Sheen and Specular.
- (Import) Ability to load a glTF from a generic `Stream` (`GltfImport.LoadStream`; thanks [sandr01d][sandr01d] for [#10](Unity-Technologies/com.unity.cloud.gltfast#10)).

### Changed
- (Import) Prefabs imported from glTF assets (at design-time) don't have the glTF logo icon assigned to them anymore. This makes it more consistent with other file types (like FBX; fixes [#557](atteneder/glTFast#557)).

### Deprecated
- `MetaMaterialExport`. Always use `MaterialExport.GetDefaultMaterialExport` to get the correct material export.

### Fixed
- (Export) glTFast shader based materials and textures are exported correctly when using the default render pipeline.
- Added missing entries to the API documentation.
- (Export) Base colors are now in correct, linear color space.
- Alpha mode blend now works as expected in HDRP 11 and newer as well (fixes [#699](atteneder/glTFast#699)).
- (Export) Fixed mesh min/max when using Draco compression.
  • Loading branch information
Unity Technologies committed Jun 25, 2024
1 parent 0155961 commit 1674ff3
Show file tree
Hide file tree
Showing 60 changed files with 1,411 additions and 176 deletions.
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [6.7.0] - 2024-06-25

### Added
- (Import) Support for [materials variants extension](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_variants).
- Serialization support for material extensions IOR, Sheen and Specular.
- (Import) Ability to load a glTF from a generic `Stream` (`GltfImport.LoadStream`; thanks [sandr01d][sandr01d] for [#10](https://github.com/Unity-Technologies/com.unity.cloud.gltfast/pull/10)).

### Changed
- (Import) Prefabs imported from glTF assets (at design-time) don't have the glTF logo icon assigned to them anymore. This makes it more consistent with other file types (like FBX; fixes [#557](https://github.com/atteneder/glTFast/issues/557)).

### Deprecated
- `MetaMaterialExport`. Always use `MaterialExport.GetDefaultMaterialExport` to get the correct material export.

### Fixed
- (Export) glTFast shader based materials and textures are exported correctly when using the default render pipeline.
- Added missing entries to the API documentation.
- (Export) Base colors are now in correct, linear color space.
- Alpha mode blend now works as expected in HDRP 11 and newer as well (fixes [#699](https://github.com/atteneder/glTFast/issues/699)).
- (Export) Fixed mesh min/max when using Draco compression.

## [6.6.0] - 2024-05-29

### Added
Expand Down Expand Up @@ -1185,6 +1205,7 @@ This release contains multiple breaking changes. Please read the [upgrade guide]
[mikejurka]: https://github.com/mikejurka
[ReadyPlayerMe]: https://readyplayer.me
[rt-nikowiss]: https://github.com/rt-nikowiss
[sandr01d]: https://github.com/sandr01d
[NyxStudio]: https://github.com/NyxStudio
[zharry]: https://github.com/zharry
[weichx]: https://gist.github.com/weichx
Expand Down
2 changes: 1 addition & 1 deletion Documentation~/config.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"DefineConstants": "DRACO_UNITY;KTX_UNITY;KTX_UNITY_1_3_OR_NEWER;KTX_UNITY_2_2_OR_NEWER;USING_URP;USING_HDRP;USING_HDRP_10_OR_NEWER;UNITY_PHYSICS;UNITY_IMAGECONVERSION;UNITY_WEBREQUEST_TEXTURE;MESHOPT;USING_URP_12_OR_NEWER;UNITY_SHADER_GRAPH_12_OR_NEWER;UNITY_ANIMATION;UNITY_ENTITIES_GRAPHICS;NEWTONSOFT_JSON"
"DefineConstants": "DRACO_UNITY;KTX_UNITY;KTX_UNITY_1_3_OR_NEWER;KTX_UNITY_2_2_OR_NEWER;USING_URP;USING_HDRP;USING_HDRP_10_OR_NEWER;UNITY_PHYSICS;UNITY_IMAGECONVERSION;UNITY_WEBREQUEST_TEXTURE;MESHOPT;USING_URP_12_OR_NEWER;UNITY_SHADER_GRAPH;UNITY_SHADER_GRAPH_12_OR_NEWER;UNITY_ANIMATION;UNITY_ENTITIES_GRAPHICS;NEWTONSOFT_JSON"
}
5 changes: 2 additions & 3 deletions Documentation~/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ The glTF 2.0 specification is fully supported, with only a few minor remarks.
| KHR_materials_clearcoat | ✅ | ✅
| KHR_materials_sheen | [ℹ️][Sheen] |
| KHR_materials_transmission | [ℹ️][Transmission] |
| KHR_materials_variants | [ℹ️][Variants] |
| KHR_materials_variants | |
| KHR_materials_ior | [ℹ️][IOR] |
| KHR_materials_specular | [ℹ️][Specular] |
| KHR_materials_volume | [ℹ️][Volume] |
Expand Down Expand Up @@ -164,7 +164,7 @@ See [glTFast Add-on API](UseCaseCustomExtras.md) for an example to import the `e
| Clear coat | ☑️³ || [⛔️][ClearCoat] |
| Sheen | [ℹ️][Sheen] | [ℹ️][Sheen] | [⛔️][Sheen] |
| Transmission | [☑️][Transmission]| [☑️][Transmission]| [☑️][Transmission]|
| Variants | [ℹ️][Variants] | [ℹ️][Variants] | [ℹ️][Variants] |
| Variants | | | |
| IOR | [ℹ️][IOR] | [ℹ️][IOR] | [⛔️][IOR] |
| Specular | [ℹ️][Specular] | [ℹ️][Specular] | [⛔️][Specular] |
| Volume | [ℹ️][Volume] | [ℹ️][Volume] | [⛔️][Volume] |
Expand Down Expand Up @@ -328,5 +328,4 @@ Possibly incomplete list of things that are known to not work with Entities yet:
[Unity]: https://unity.com
[URP]: https://unity.com/srp/universal-render-pipeline
[UVsets]: https://github.com/atteneder/glTFast/issues/206
[Variants]: https://github.com/atteneder/glTFast/issues/112
[Volume]: https://github.com/atteneder/glTFast/issues/209
134 changes: 97 additions & 37 deletions Editor/Scripts/GltfImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,48 +137,29 @@ public override void OnImportAsset(AssetImportContext ctx)
instantiationLogger = new CollectingLogger();
for (var sceneIndex = 0; sceneIndex < m_Gltf.SceneCount; sceneIndex++)
{
var scene = m_Gltf.GetSourceScene(sceneIndex);
var sceneName = m_Gltf.GetSceneName(sceneIndex);
var go = new GameObject(sceneName);
var instantiator = new GameObjectInstantiator(m_Gltf, go.transform, instantiationLogger, instantiationSettings);
var index = sceneIndex;
success = AsyncHelpers.RunSync(() => m_Gltf.InstantiateSceneAsync(instantiator, index));
if (!success) break;
var useFirstChild = true;
var multipleNodes = scene.nodes.Length > 1;
var hasAnimation = false;
#if UNITY_ANIMATION
if (importSettings.AnimationMethod != AnimationMethod.None
&& (instantiationSettings.Mask & ComponentType.Animation) != 0) {
var animationClips = m_Gltf.GetAnimationClips();
if (animationClips != null && animationClips.Length > 0) {
hasAnimation = true;
}
try
{
ImportScene(ctx, sceneIndex, instantiationLogger);
}
#endif

if (instantiationSettings.SceneObjectCreation == SceneObjectCreation.Never
|| instantiationSettings.SceneObjectCreation == SceneObjectCreation.WhenMultipleRootNodes && !multipleNodes)
catch (InvalidOperationException)
{
// No scene GameObject was created, so the first
// child is the first (and in this case only) node.

// If there's animation, its clips' paths are relative
// to the root GameObject (which will also carry the
// `Animation` component. If not, we can import the the
// first and only node as root directly.

useFirstChild = !hasAnimation;
instantiationLogger.Error($"Failed creating scene {sceneIndex} instance.");
}

var sceneTransform = useFirstChild
? go.transform.GetChild(0)
: go.transform;
var sceneGo = sceneTransform.gameObject;
AddObjectToAsset(ctx, $"scenes/{sceneName}", sceneGo, gltfIcon);
if (sceneIndex == m_Gltf.DefaultSceneIndex)
if (m_Gltf.MaterialsVariantsCount > 0)
{
ctx.SetMainObject(sceneGo);
for (var variantIndex = 0; variantIndex < m_Gltf.MaterialsVariantsCount; variantIndex++)
{
try
{
ImportScene(ctx, sceneIndex, instantiationLogger, variantIndex);
}
catch (InvalidOperationException)
{
instantiationLogger.Error($"Failed creating scene {sceneIndex} materials variant " +
$"{variantIndex} instance.");
}
}
}
}

Expand Down Expand Up @@ -313,6 +294,85 @@ public override void OnImportAsset(AssetImportContext ctx)
reportItems = reportItemList.ToArray();
}

void ImportScene(
AssetImportContext ctx,
int sceneIndex,
CollectingLogger instantiationLogger,
int? materialsVariantIndex = null
)
{
var scene = m_Gltf.GetSourceScene(sceneIndex);
var sceneName = m_Gltf.GetSceneName(sceneIndex);
string sceneObjectName = null;
string variantNameSuffix = null;
if (materialsVariantIndex.HasValue)
{
variantNameSuffix = m_Gltf.GetMaterialsVariantName(materialsVariantIndex.Value);
if (string.IsNullOrEmpty(variantNameSuffix))
{
variantNameSuffix = $"variant_{materialsVariantIndex.Value}";
}
sceneObjectName = $"{sceneName}_{variantNameSuffix}";
}
else
{
sceneObjectName = sceneName;
}

var go = new GameObject(sceneObjectName);
var instantiator = new GameObjectInstantiator(m_Gltf, go.transform, instantiationLogger, instantiationSettings);
var index = sceneIndex;
var success = AsyncHelpers.RunSync(() => m_Gltf.InstantiateSceneAsync(instantiator, index));
if (!success)
{
throw new InvalidOperationException("Instantiating scene failed");
}
var useFirstChild = true;
var multipleNodes = scene.nodes.Length > 1;
var hasAnimation = false;
#if UNITY_ANIMATION
if (importSettings.AnimationMethod != AnimationMethod.None
&& (instantiationSettings.Mask & ComponentType.Animation) != 0) {
var animationClips = m_Gltf.GetAnimationClips();
if (animationClips != null && animationClips.Length > 0) {
hasAnimation = true;
}
}
#endif

if (instantiationSettings.SceneObjectCreation == SceneObjectCreation.Never
|| instantiationSettings.SceneObjectCreation == SceneObjectCreation.WhenMultipleRootNodes && !multipleNodes)
{
// No scene GameObject was created, so the first
// child is the first (and in this case only) node.

// If there's animation, its clips' paths are relative
// to the root GameObject (which will also carry the
// `Animation` component. If not, we can import the the
// first and only node as root directly.

useFirstChild = !hasAnimation;
}

var sceneTransform = useFirstChild
? go.transform.GetChild(0)
: go.transform;
var sceneGo = sceneTransform.gameObject;

if (materialsVariantIndex.HasValue)
{
sceneGo.name = $"{sceneGo.name}_{variantNameSuffix}";

var variantsControl = instantiator.SceneInstance.MaterialsVariantsControl;
AsyncHelpers.RunSync(() => variantsControl.ApplyMaterialsVariantAsync(materialsVariantIndex.Value));
}
AddObjectToAsset(ctx, $"scenes/{sceneObjectName}", sceneGo);
if (sceneIndex == m_Gltf.DefaultSceneIndex && !materialsVariantIndex.HasValue)
{
ctx.SetMainObject(sceneGo);
}
}

void AddObjectToAsset(AssetImportContext ctx, string originalName, Object obj, Texture2D thumbnail = null)
{
if (m_ImportedObjects.Contains(obj))
Expand Down
97 changes: 97 additions & 0 deletions Editor/Scripts/MaterialsVariantsComponentInspector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// SPDX-FileCopyrightText: 2024 Unity Technologies and the glTFast authors
// SPDX-License-Identifier: Apache-2.0

using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

namespace GLTFast.Editor
{
[CustomEditor(typeof(MaterialsVariantsComponent))]
class MaterialsVariantsComponentInspector : UnityEditor.Editor
{
[SerializeField] VisualTreeAsset m_MainMarkup;

List<string> m_VariantNames;
#if UNITY_2021_2_OR_NEWER
DropdownField m_Dropdown;
#endif

public override VisualElement CreateInspectorGUI()
{
if (m_VariantNames == null)
{
var control = (target as MaterialsVariantsComponent)?.Control;
if (control != null)
{
var count = control.MaterialsVariantsCount;
m_VariantNames = new List<string>(count + 1)
{
"<no variant>"
};
for (var variantIndex = 0; variantIndex < count; variantIndex++)
{
m_VariantNames.Add(control.GetMaterialsVariantName(variantIndex));
}
}
}
var myInspector = new VisualElement();
#if UNITY_2021_2_OR_NEWER
m_MainMarkup.CloneTree(myInspector);
m_Dropdown = myInspector.Query<DropdownField>().First();

if (m_VariantNames == null)
{
myInspector.SetEnabled(false);
}
else
{
m_Dropdown.choices = m_VariantNames;
m_Dropdown.index = 0;
m_Dropdown.RegisterValueChangedCallback(OnMaterialsVariantChanged);
myInspector.Add(m_Dropdown);
}
#else
if (m_VariantNames == null)
{
myInspector.SetEnabled(false);
}
else
{
for (var i = 0; i < m_VariantNames.Count; i++)
{
var button = new Button
{
text = m_VariantNames[i]
};

button.RegisterCallback<ClickEvent, int>(OnVariantButtonClicked, i - 1); // asset is the root visual element that will be closed
myInspector.Add(button);
}
}
#endif
return myInspector;
}

#if UNITY_2021_2_OR_NEWER
void OnMaterialsVariantChanged(ChangeEvent<string> evt)
{
var control = (target as MaterialsVariantsComponent)?.Control;
if (control != null)
{
_ = control.ApplyMaterialsVariantAsync(m_Dropdown.index - 1);
}
}
#else
void OnVariantButtonClicked(ClickEvent evt, int variantIndex)
{
var control = (target as MaterialsVariantsComponent)?.Control;
if (control != null)
{
_ = control.ApplyMaterialsVariantAsync(variantIndex);
}
}
#endif
}
}
13 changes: 13 additions & 0 deletions Editor/Scripts/MaterialsVariantsComponentInspector.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Editor/UI/MaterialsVariantsComponentInspector.uxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<ui:DropdownField label="Materials Variant" />
</ui:UXML>
10 changes: 10 additions & 0 deletions Editor/UI/MaterialsVariantsComponentInspector.uxml.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Runtime/Scripts/Export/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace GLTFast.Export
{
static class Constants
{
public const string version = "6.6.0";
public const string version = "6.7.0";

internal const string mimeTypePNG = "image/png";
internal const string mimeTypeJPG = "image/jpeg";
Expand Down
8 changes: 1 addition & 7 deletions Runtime/Scripts/Export/GltfMaterialExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,7 @@ out var textureTransform

if (TryGetValue(unityMaterial, MaterialProperty.BaseColor, out Color baseColor))
{
material.pbrMetallicRoughness.baseColorFactor = new[]
{
baseColor.r,
baseColor.g,
baseColor.b,
baseColor.a
};
material.pbrMetallicRoughness.BaseColor = baseColor.linear;
}

material = HandleMetallicRoughness(gltf, material, unityMaterial);
Expand Down
10 changes: 2 additions & 8 deletions Runtime/Scripts/Export/GltfUnlitMaterialExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
namespace GLTFast.Export
{
/// <summary>
/// Converts Unity Materials that use a glTFast shader to glTF materials
/// Converts Unity Materials that use the glTFast shader `glTF/Unlit` to glTF materials
/// </summary>
public class GltfUnlitMaterialExporter : IMaterialExport
{
Expand Down Expand Up @@ -81,13 +81,7 @@ out var textureTransform

if (GltfMaterialExporter.TryGetValue(unityMaterial, MaterialProperty.BaseColor, out Color baseColor))
{
material.pbrMetallicRoughness.baseColorFactor = new[]
{
baseColor.r,
baseColor.g,
baseColor.b,
baseColor.a
};
material.pbrMetallicRoughness.BaseColor = baseColor.linear;
}

return material;
Expand Down
Loading

0 comments on commit 1674ff3

Please sign in to comment.