-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Adding full support for custom materials to GltfLoader #2725
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
theMinka
wants to merge
14
commits into
jMonkeyEngine:master
Choose a base branch
from
theMinka:theMinka_Custom-material-support-in-GltfLoader
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
ef06795
Fixed multiple extension handling in CustomContentManager
theMinka 317a56a
Added a flag to GltfModelKey to switch between the old and new materi…
theMinka c164633
Implemented new material creation process in GltfLoader
theMinka fef2d6e
Added handling of GltfMaterialData objects for all material-based Ext…
theMinka 11eded3
Added GltfMaterialFactory implementations for BPRLighting and Unshade…
theMinka ae12167
Move default values for material parameters to material factories
theMinka 53b75ca
Deprecating most parts of the old MaterialAdapter system
theMinka 13ad8ba
Fixed vertex color flag in GltfLoader
theMinka 58410b6
Fixed QueueBucket for BlendMode.AlphaAdditive in GltfLoader
theMinka 2921b83
Fixed typo in emissive constants in GltfMaterialData
theMinka d005d0b
Fixed missing vertex coloring flag in GltfLoader
theMinka 7909f1b
Smaller fixes in some components for loading GLTF files
theMinka b245ada
PBREmissiveStrengthExtensionLoader no longer replaces other MaterialA…
theMinka ccec70a
Added material parameter tests to GltfLoaderTest
theMinka File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,6 +31,7 @@ | |
| */ | ||
| package com.jme3.scene.plugins.gltf; | ||
|
|
||
| import static com.jme3.scene.plugins.gltf.GltfMaterialData.*; | ||
| import static com.jme3.scene.plugins.gltf.GltfUtils.assertNotNull; | ||
| import static com.jme3.scene.plugins.gltf.GltfUtils.findCommonAncestor; | ||
| import static com.jme3.scene.plugins.gltf.GltfUtils.getAdapterForMaterial; | ||
|
|
@@ -82,7 +83,7 @@ | |
| import com.jme3.asset.AssetLoader; | ||
| import com.jme3.asset.TextureKey; | ||
| import com.jme3.material.Material; | ||
| import com.jme3.material.RenderState; | ||
| import com.jme3.material.RenderState.BlendMode; | ||
| import com.jme3.math.ColorRGBA; | ||
| import com.jme3.math.FastMath; | ||
| import com.jme3.math.Matrix4f; | ||
|
|
@@ -109,6 +110,7 @@ | |
| import com.jme3.util.BufferInputStream; | ||
| import com.jme3.util.BufferUtils; | ||
| import com.jme3.util.IntMap; | ||
| import com.jme3.util.SafeArrayList; | ||
| import com.jme3.util.mikktspace.MikktspaceTangentGenerator; | ||
|
|
||
| /** | ||
|
|
@@ -143,13 +145,20 @@ public class GltfLoader implements AssetLoader { | |
| private final Vector3fArrayPopulator vector3fArrayPopulator = new Vector3fArrayPopulator(); | ||
| private final QuaternionArrayPopulator quaternionArrayPopulator = new QuaternionArrayPopulator(); | ||
| private final Matrix4fArrayPopulator matrix4fArrayPopulator = new Matrix4fArrayPopulator(); | ||
| private final Map<String, MaterialAdapter> defaultMaterialAdapters = new HashMap<>(); | ||
| @Deprecated private final Map<String, MaterialAdapter> defaultMaterialAdapters = new HashMap<>(); | ||
| private final CustomContentManager customContentManager = new CustomContentManager(); | ||
| private boolean useNormalsFlag = false; | ||
|
|
||
| Map<SkinData, List<Spatial>> skinnedSpatials = new HashMap<>(); | ||
| private final IntMap<SkinBuffers> skinBuffers = new IntMap<>(); | ||
|
|
||
| private static SafeArrayList<GltfMaterialFactory> materialFactoryList = new SafeArrayList<>(GltfMaterialFactory.class); | ||
|
|
||
| static { | ||
| materialFactoryList.add(new UnshadedMaterialFactory()); | ||
| materialFactoryList.add(new PBRLightingMaterialFactory()); | ||
| } | ||
|
|
||
| public GltfLoader() { | ||
| defaultMaterialAdapters.put("pbrMetallicRoughness", new PBRMetalRoughMaterialAdapter()); | ||
| } | ||
|
|
@@ -523,12 +532,17 @@ public Geometry[] readMeshPrimitives(int meshIndex) throws IOException { | |
|
|
||
| Integer materialIndex = getAsInteger(meshObject, "material"); | ||
| if (materialIndex == null) { | ||
| geom.setMaterial(defaultMat); | ||
| // Create a new default material | ||
| Material material = defaultMat.clone(); | ||
| material.setBoolean("UseVertexColor", useVertexColors); | ||
| geom.setMaterial(material); | ||
|
|
||
| } else { | ||
| useNormalsFlag = false; | ||
| geom.setMaterial(readMaterial(materialIndex)); | ||
| if (geom.getMaterial().getAdditionalRenderState() | ||
| .getBlendMode() == RenderState.BlendMode.Alpha) { | ||
| Material material = readMaterial(materialIndex, useVertexColors); | ||
| geom.setMaterial(material); | ||
| BlendMode blendMode = material.getAdditionalRenderState().getBlendMode(); | ||
| if (blendMode == BlendMode.Alpha || blendMode == BlendMode.AlphaAdditive) { | ||
| // Alpha blending is enabled for this material. Let's place the geom in the | ||
| // transparent bucket. | ||
| geom.setQueueBucket(RenderQueue.Bucket.Transparent); | ||
|
|
@@ -540,10 +554,6 @@ public Geometry[] readMeshPrimitives(int meshIndex) throws IOException { | |
| } | ||
| } | ||
|
|
||
| if (useVertexColors) { | ||
| geom.getMaterial().setBoolean("UseVertexColor", useVertexColors); | ||
| } | ||
|
|
||
| geom.setName(name + "_" + index); | ||
|
|
||
| geom.updateModelBound(); | ||
|
|
@@ -802,7 +812,75 @@ protected ByteBuffer getBytes(int bufferIndex, String uri, Integer bufferLength) | |
| return data; | ||
| } | ||
|
|
||
| public Material readMaterial(int materialIndex) throws IOException { | ||
| public Material readMaterial(int materialIndex, boolean usesVertexColors) throws IOException { | ||
| // Fallback to the old material adapter system, if the legacy flag is set. | ||
| if (GltfUtils.isMaterialAdaptersEnabled(info)) { | ||
| return readMaterialUsingMaterialAdapters(materialIndex, usesVertexColors); | ||
| } | ||
|
|
||
| assertNotNull(materials, "There is no material defined yet a mesh references one"); | ||
| JsonObject materialJson = materials.get(materialIndex).getAsJsonObject(); | ||
|
|
||
| GltfMaterialData gltfMaterialData = readStandardMaterialParameters(materialJson); | ||
| gltfMaterialData.setHasVertexColors(usesVertexColors); | ||
| gltfMaterialData = customContentManager.readExtensionAndExtras("material", materialJson, gltfMaterialData); | ||
| return createMaterial(gltfMaterialData, materialIndex); | ||
|
Comment on lines
+815
to
+827
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added many new tests for various material parameter combinations to the GltfLoaderTest. |
||
| } | ||
|
|
||
| protected GltfMaterialData readStandardMaterialParameters(JsonObject materialJson) throws IOException { | ||
| GltfMaterialData gltfMaterialData = new GltfMaterialData(); | ||
| gltfMaterialData.setGltfParam(MATERIAL_NAME_PARAM, getAsString(materialJson, "name")); | ||
|
|
||
| JsonObject pbrMetallicRoughnessJson = materialJson.getAsJsonObject("pbrMetallicRoughness"); | ||
| if (pbrMetallicRoughnessJson != null) { | ||
| gltfMaterialData.setGltfParam(BASE_COLOR_PARAM, getAsColor(pbrMetallicRoughnessJson, "baseColorFactor")); | ||
| gltfMaterialData.setGltfParam(BASE_COLOR_TEXTURE_PARAM, getAsTexture2D(pbrMetallicRoughnessJson, "baseColorTexture")); | ||
| gltfMaterialData.setGltfParam(METALLIC_FACTOR_PARAM, getAsFloat(pbrMetallicRoughnessJson, "metallicFactor")); | ||
| gltfMaterialData.setGltfParam(ROUGHNESS_FACTOR_PARAM, getAsFloat(pbrMetallicRoughnessJson, "roughnessFactor")); | ||
| gltfMaterialData.setGltfParam(METALLIC_ROUGHNESS_TEXTURE_PARAM, getAsTexture2D(pbrMetallicRoughnessJson, "metallicRoughnessTexture")); | ||
| } | ||
|
|
||
| JsonObject normalTextureJson = materialJson.getAsJsonObject("normalTexture"); | ||
| if (normalTextureJson != null) { | ||
| gltfMaterialData.setGltfParam(NORMAL_TEXTURE_PARAM, readTexture(normalTextureJson)); | ||
| gltfMaterialData.setGltfParam(NORMAL_SCALE_PARAM, getAsFloat(normalTextureJson, "scale")); | ||
| useNormalsFlag = true; | ||
| } | ||
|
|
||
| JsonObject occlusionTextureJson = materialJson.getAsJsonObject("occlusionTexture"); | ||
| if (occlusionTextureJson != null) { | ||
| gltfMaterialData.setGltfParam(OCCLUSION_TEXTURE_PARAM, readTexture(occlusionTextureJson)); | ||
| gltfMaterialData.setGltfParam(OCCLUSION_TEXTURE_STRENGTH_PARAM, getAsFloat(occlusionTextureJson, "strength")); | ||
| } | ||
|
|
||
| gltfMaterialData.setGltfParam(EMISSIVE_TEXTURE_PARAM, getAsTexture2D(materialJson, "emissiveTexture")); | ||
| gltfMaterialData.setGltfParam(EMISSIVE_COLOR_PARAM, getAsColor(materialJson, "emissiveFactor")); | ||
|
|
||
| String alphaMode = getAsString(materialJson, "alphaMode"); | ||
| gltfMaterialData.setGltfParam(ALPHA_MODE_PARAM, alphaMode); | ||
| if ("MASK".equals(alphaMode)) { | ||
| gltfMaterialData.setGltfParam(ALPHA_CUTOFF_PARAM, getAsFloat(materialJson, "alphaCutoff")); | ||
| } | ||
|
|
||
| gltfMaterialData.setGltfParam(DOUBLE_SIDED_PARAM, getAsBoolean(materialJson, "doubleSided")); | ||
|
|
||
| return gltfMaterialData; | ||
| } | ||
|
|
||
| protected Material createMaterial(GltfMaterialData gltfMaterialData, int materialIndex) { | ||
| for (GltfMaterialFactory gltfMaterialFactory : materialFactoryList) { | ||
| if (gltfMaterialFactory.accepts(info.getKey(), gltfMaterialData)) { | ||
| return gltfMaterialFactory.createMaterial(info.getManager(), info.getKey(), gltfMaterialData); | ||
| } | ||
| } | ||
|
|
||
| logger.log(Level.WARNING, "Couldn't find any matching GltfMaterialFactory for material " + materialIndex); | ||
| useNormalsFlag = false; | ||
| return defaultMat; | ||
| } | ||
|
|
||
| @Deprecated | ||
| protected Material readMaterialUsingMaterialAdapters(int materialIndex, boolean usesVertexColors) throws IOException { | ||
| assertNotNull(materials, "There is no material defined yet a mesh references one"); | ||
|
|
||
| JsonObject matData = materials.get(materialIndex).getAsJsonObject(); | ||
|
|
@@ -875,6 +953,8 @@ public Material readMaterial(int materialIndex) throws IOException { | |
|
|
||
| adapter.setParam("emissiveTexture", readTexture(matData.getAsJsonObject("emissiveTexture"))); | ||
|
|
||
| adapter.setParam("usesVertexColors", usesVertexColors); | ||
|
|
||
| return adapter.getMaterial(); | ||
| } | ||
|
|
||
|
|
@@ -922,6 +1002,10 @@ public void readCameras() throws IOException { | |
| } | ||
| } | ||
|
|
||
| protected Texture2D getAsTexture2D(JsonObject jsonObject, String textureName) throws IOException { | ||
| return readTexture(jsonObject.getAsJsonObject(textureName)); | ||
| } | ||
|
|
||
| public Texture2D readTexture(JsonObject texture) throws IOException { | ||
| return readTexture(texture, false); | ||
| } | ||
|
|
@@ -1715,4 +1799,44 @@ public static void registerDefaultExtrasLoader(Class<? extends ExtrasLoader> loa | |
| public static void unregisterDefaultExtrasLoader() { | ||
| CustomContentManager.defaultExtraLoaderClass = UserDataLoader.class; | ||
| } | ||
|
|
||
| /** | ||
| * Registers a new material factory and places it before all existing factories.<br/> | ||
| * The ordering of these factories defines their priority. When a new material needs to be created, | ||
| * the loader searches for the first material factory that accepts the given material data. | ||
| * | ||
| * @param materialFactory The {@link GltfMaterialFactory} to register. | ||
| */ | ||
| public static void registerMaterialFactoryFirst(GltfMaterialFactory materialFactory) { | ||
| unregisterMaterialFactory(materialFactory.getClass()); | ||
| materialFactoryList.add(0, materialFactory); | ||
| } | ||
|
|
||
| /** | ||
| * Registers a new material factory and places it behind all existing factories.<br/> | ||
| * The ordering of these factories defines their priority. When a new material needs to be created, | ||
| * the loader searches for the first material factory that accepts the given material data. | ||
| * | ||
| * @param materialFactory The {@link GltfMaterialFactory} to register. | ||
| */ | ||
| public static void registerMaterialFactoryLast(GltfMaterialFactory materialFactory) { | ||
| unregisterMaterialFactory(materialFactory.getClass()); | ||
| materialFactoryList.add(materialFactory); | ||
| } | ||
|
|
||
| /** | ||
| * Unregisters a material factory by its class. | ||
| * | ||
| * @param materialFactoryClass The class of the {@link GltfMaterialFactory} to unregister. | ||
| */ | ||
| public static void unregisterMaterialFactory(Class<? extends GltfMaterialFactory> materialFactoryClass) { | ||
| materialFactoryList.removeIf(materialFactoryClass::isInstance); | ||
| } | ||
|
|
||
| /** | ||
| * Unregisters all material factories. | ||
| */ | ||
| public static void unregisterAllMaterialFactories() { | ||
| materialFactoryList.clear(); | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The vertex coloring flag is now also set correctly in the legacy system.