Closed kourion11 closed 9 months ago
You're going to need to fix this further up your pipeline, or dig into the code to adapt it to your needs.
The framework maps glTF properties to SceneKit properties as closely as it can, but it's not possible to vary the opacity of a node by setting its base color factor's alpha channel. There's simply nowhere for that information to go in SceneKit.
One possible solution would be to preprocess any textures that need to be transparent by multiplying them by their respective factors. In the Christmas Ball example, this would entail modulating baseColor_1.png by the alpha of its base color factor (0.4681818).
Another possible solution is to adapt the loader to carry information about the base color factor into the SceneKit conversion routine and use shader modifiers to apply it to the corresponding material. This is an intrusive change and one that I've wanted to try for a long time, but haven't gotten around to yet.
In addition to the above suggestions, if you find you get better results from dual-layer blending, you can modify all alpha-blended materials to use it upon import rather than targeting specific materials in specific assets. Just iterate over the materials in the GLTFSceneSource
before performing conversion:
let source = GLTFSCNSceneSource(asset: asset)
for material in source.materials {
if material.blendMode == .alpha {
material.transparencyMode = .dualLayer
}
}
To be clear, setting the transparency mode by itself won't solve your issues with opacity; it's a supplemental suggestion that may improve image quality after fixing your alpha channel woes.
Okay, I have some maybe-good news for you. I implemented better handling of base color factor modulation via shader modifiers, and the Christmas Ball asset looks better by default, without having to do any runtime modifications.
You should be aware that macOS Sonoma 14.0 (and iOS 17.0, I think) have a bug in SceneKit that affects transparency, so you may notice differences in how assets render on these OS versions.
In the meantime, you should find that things look better as of ce58ae6 if you want to give it a try.
Thank you!
Do you consider this issue resolved, or is there more to do here?
This issue will be automatically closed in seven days if no further reply is received.
Closing.
The problem with transparency of the model and similar to it, as far as I understand when using metacity on a transparent element makes it opaque and fills it. You wrote a solution for a specific model, but unfortunately we have different models coming in and we would like to correct this at the conversion stage. Is there any way to solve this?
node.enumerateChildNodes { child, _ in if child.name == "glass" { child.opacity = 0.568 child.geometry?.firstMaterial?.transparencyMode = .dualLayer } }
This helped solve the problem, but only for a specific model unfortunately...