-
Notifications
You must be signed in to change notification settings - Fork 73
Material refactoring #134
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
base: v3.0.0-dev
Are you sure you want to change the base?
Material refactoring #134
Conversation
A bit more specific information about this point: The current I'm hesitating a bit about this one. When a client wants to obtain the |
|
Tagging @Nadwey (because you interacted with this PR), and @LocutusV0nB0rg (because of your general interest in JglTF - even though you might be less interested in details of the material than in other things). I just marked this as "Ready For Review". Note that this is only supposed to go into the Some details and justificationsAgain: This is not final. There may still be caveats and things that have to be adjusted when further (or even "all") (PBR) extensions are supposed to be implemented. But the general approach taken here seems to go in the right direction. The proof-of-concept usage of this state in the implementations of A basic summary of the approach was already given in the initial post of this PR: The idea is to more closely reflect the actual structures of glTF materials on the "model" side. And I think that reflecting some of these structures (like the Some of the changes here do (in their current form) make aspects of the material handling a bit less convenient. The former PbrMaterialModel materialModel = (PbrMaterialModel)gltfModel.getMaterialModel(0);
DefaultPbrMetallicRoughnessModel pbr =
(DefaultPbrMetallicRoughnessModel) materialModel.getPbrMetallicRoughnessModel();
DefaultTextureInfoModel tim = (DefaultTextureInfoModel)pbr.getBaseColorTextureInfoModel();
tim.setTextureInfoModel(example);There are two options that I'm still considering for improving or simplifying this. (This may happen at a later point, maybe as a new PR into the Option 1: Covariant return types.The current structure here follows the structure of other model classes, namely that of read-only interfaces, and modifiable interface PbrMaterialModel extends MaterialModel
{
PbrMetallicRoughnessModel getPbrMetallicRoughnessModel();
}
interface PbrMetallicRoughnessModel
{
TextureInfoModel getBaseColorTextureInfoModel();
}
interface TextureInfoModel
{
TextureModel getTextureModel();
}With the corresponding One way of avoiding these casts would be to assume that the class DefaultPbrMaterialModel implements PbrMaterialModel
{
// ...
@Override
public DefaultPbrMetallicRoughnessModel getPbrMetallicRoughnessModel()
{
return pbrMetallicRoughnessModel;
}
}(Siimilarly, for all other types down the hierarchy). With this, the actual types are "pinned" to the // Only cast once...
DefaultPbrMaterialModel materialModel =
(DefaultPbrMaterialModel)gltfModel.getMaterialModel(0);
// No additional cast necessary here
DefaultPbrMetallicRoughnessModel pbr = materialModel.getPbrMetallicRoughnessModel();
DefaultTextureInfoModel tim = pbr.getBaseColorTextureInfoModel();
tim.setTextureInfoModel(example);This would somehow defeat the (little) purpose of the interfaces. I'm hesitating whether that's a sensible trade-off. But I'm deferring that change, because changing the return type to the Option 2: Convenience functionsThere could always be some convenience functions, either in the classes themself, or in some // Unavoidable cast:
DefaultPbrMaterialModel materialModel = (DefaultPbrMaterialModel)gltfModel.getMaterialModel(0);
// Convenience function to hide the casts and/or instanceof-checks:
materialModel.setBaseColorTextureInfoTextureModel(example);or even MaterialModel materialModel = gltfModel.getMaterialModel(0);
// Convenience function to hide the casts and/or instanceof-checks:
MaterialModels.setPbrBaseColorTextureInfoTextureModel(
materialModel, example);But similar to Option 1: These can be added later, without breaking anyhing. If the (common) usage patterns turn out to be too cumbersome and repetitive, and if/when I have a clearer idea about what the best structure of these convenience functions should be, I'll consider to add them. |
Addresses #133
As mentioned in the issue: The
MaterialModelV2class (andMaterialModelV1) have been attempts to handle glTF 1.0 and glTF 2.0, with their main difference being in the material models. TheMaterialModelV2tried to offer a "flattened" access to the information that is stored in the glTF PBR material model. This "flattening" consisted of omitting theTextureInfostructures, which turned out to not be ideal: TheTextureInfoactually carries certain extensions, which consequently could not be modeled nicely with this class.This PR is a first draft of a possible refactoring here. This will involve some breaking changes - specifically, for those who explicitly used these classes by creating instances of them. The changes for clients will roughly fall into the categories of 1. using a different constructor and 2. creating the (new) PBR-based materials including the structures for the
TextureInfo.As ... some sort of justification: Some of this was already on the radar. The
MaterialModelV2class carried a noteSimiarly, the
MaterialModelV1class carried a noteThis is essentially what is done here.
The
MaterialModelV1is relatively simple (and hardly anyone is using that anyhow). It has been renamed toDefaultTechniqueMaterialModel, and implements a new interfaceTechniqueMaterialModelwhich just offers the technique-based material representation.There are more changes for the
MaterialModelV2. There now are structures that more closely resemble the actual structure of the materials in glTF 2.0.:PbrMaterialModel, corresponding to glTF materialPbrMetallicRoughnessModel, corresponding to glTF pbrMetallicRoughnessTextureInfo, corresponding to glTF textureInfoNormalTextureInfo(extendingTextureInfo), corresponding to glTF normalTextureInfoOcclusionTextureInfo(extendingTextureInfo), corresponding to glTF occlusionTextureInfoas well as
Default...implementations for all of them.Accessing these structures can be a bit inconvenient, compared to the
MaterialModelV2that flattened all this out. Previously, theMaterialModelV2offered functions likeTextureModel texture = material.getBaseColorTexture();The new structures would make this rather tedious:
🤕
So there are some convenience functions for that, via default methods in the interface, meaning that it is still possible to do
TextureModel texture = material.getBaseColorTexture();But I'm hesitating and going back and forth about which of convenience functions should be offered. I could offer nearly all the functions that have been in
MaterialModelV2. Maybe I'll do this to make the change "less breaking"...The question is even more important for the case of creating a material: The
MaterialModelV2offered convenient functions likematerial.setBaseColorFactor(values);Trying to offer similar functions in the new implementation raises a few questions about consistencies.
For both (reading and creating materials), some questions about the handling of default values still have to be sorted out.
Hopefully, people preferred the
MaterialBuilder, which should be largely unaffected by all this.Done.
One TODO for me: The extensions and extras from theTextureInfo-related structures are not yet passed to the model or copied accordingly. Some functions that are involved here still require a cleanup.