Closed Bersaelor closed 1 year ago
Hmm, the difference seems to be:
"alphaMode": "OPAQUE",
"doubleSided": true,
"extensions": {
"KHR_materials_transmission": {
"transmissionFactor": 1
}
},
"name": "Plastic.002",
vs
"alphaMode": "BLEND",
"doubleSided": true,
"extensions": {
"KHR_materials_transmission": {
"transmissionFactor": 0.5
}
},
"name": "Plastic.001",
I'm not quite sure how one should interpret "transmissionFactor": 1
together with "alphaMode": "OPAQUE"
. But even when I set it to BLEND, it still looks wrong (no color); might help to reduce the transmissionFactor. In any case, this is a three.js rendering issue, so I'd recommend you file an issue there are get a discussion going.
Thank you for your reply @elalish!
So the last weeks I've been using transmission: 1
with three.js version "^0.146.0" in our plain Three.js app with no problem. There I setup the THREE.MeshPhysicalMaterial
manually , e.g.
var material: THREE.MeshPhysicalMaterial = new THREE.MeshPhysicalMaterial({
opacity: opacity,
color: Number(hex),
reflectivity: m.parameters.reflectivity,
metalness: m.parameters.metallicity,
roughness: m.parameters.roughness,
transmission: m.parameters.transmission
});
and never had any issues with the colors.
The materials can be fine-tuned with the live-preview in Three.js. Then I use blender and a python script to assemble the whole scene in blender, based on the chosen materials and 3D objects, which are then exported as *.glb
.
The material that made the above images looked fine in Three.js before:
PS: And you're right, I tried both BLEND
and OPAQUE
to see if it makes any difference in the gltf but that doesn't seem to be it. Also, either way the color should be applied correctly.
Thanks, that's helpful. We use three.js under the hood, so what this really implies is that the exporters and importers are not managing to do a lossless round-trip of a three.js material. Not sure if the bug is on the three.js side, the Blender side, or if you've just selected some combination that's not representable in glTF. You can set a break point in MV, maybe down in the three.js render method and take a look at the MeshPhysicalMaterial
you actually ended up with. Hopefully that will help with filing bugs on the upstream tools.
. You can set a break point in MV, maybe down in the three.js render method and take a look at the MeshPhysicalMaterial you actually ended up with.
Good idea, I'm not super deep in the tools necessary to put breakpoints into dependencies, but will see what I can do (I.e. the three.js thats in the node_modules folder is minified and not running the src
folder, I have to google how to put breakpoints in the un-minified code).
In the mean time, I built the following minimal example:
// npm installed is "three": "^0.146.0",
import { Collada, ColladaLoader } from 'three/examples/jsm/loaders/ColladaLoader';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import planga from './planga.glb';
//...
scene.current = new THREE.Scene();
scene.current.background = new THREE.Color( 0xffffff );
const loader = new GLTFLoader( );
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath( 'https://www.gstatic.com/draco/versioned/decoders/1.4.1/' );
loader.setDRACOLoader( dracoLoader );
loader.load(planga, function (main) {
const g = main.scene.childNamed("Glasses")
if (scene.current) scene.current.add(g);
})
// ... plus the usual camera positioning and render mounting
planga is the same model linked above and the result looks fine (you can see the transmission since the internal metal parts of correctly blurred on the left and right end of the lenses:
so it seems plain THREE.js can load the linked model fine.
Alright, I managed to put a breakpoint in
node_modules/@google/model-viewer/src/three-components/Renderer.ts/Renderer/render
method and log the scene:
scene._model.children[0].children[0].children[0]
should be the part named FRONT
.
console.log(scene._model.children[0].children[0].children[0].material)
:
The line
color: Color {isColor: true, r: 0.1119324266910553, g: 0.061246052384376526, b: 0.6307571530342102}
looks like it should be fine to me, still no color in model-viewer.
In comparison let's also log the MeshPhysicalMaterial
from the minimal Three.js example above, that just loads the glb and shows it fine (JSON.stringified this time):
Yeah, this is strange, I too looked at the materials between the working and non-working version and couldn't find any difference. Can you repro with a simpler model? Perhaps with just one material?
Where can I find a link to the working version of the model?
Where can I find a link to the working version of the model?
It's the same model one time I imported it via a plain THREE.js implementation (works, see https://github.com/google/model-viewer/issues/4047#issuecomment-1384066921 ) . But then importing via modelviewer the material failed to work (as in og post)
I just had an inspiration on why this is different in MV vs the three.js editor: MV renders transparently, compositing afterward into whatever DOM content is behind it, while three's editor renders a background into its own buffers. You can see the difference in our own editor by loading up your model and in the second tab, choosing a different environment image and then checking "use environment as skybox" - suddenly it looks like the other renderers.
This is a helpful feature of MV for web design, but I believe there's also improvement that could be made in three's shaders for transparent materials with no background images behind them. As a workaround, you can set a simple single-color skybox-image and use environment-image="neutral"
or whatever you want.
So if there's no background we render the environment as background in the transmission buffer?
So if there's no background we render the environment as background in the transmission buffer?
I hope the answer to this is no. I just want to see if our little non-PBR hack for rendering to a transparent buffer can be improved to save the transmissive color better.
Hmm, I can't see how to make that work...
If it was me, I would make it so <model-viewer>
's background (white by default?) goes opaque and logs a warning in the console saying that models with refractive materials only work when <model-viewer>
has a opaque background and display the API to change the background color.
And then remove the hack from three.js shader 😅
I think I have a promising solution: https://github.com/mrdoob/three.js/pull/25819
Fixed by #4314 - by pulling in the above change.
Description
When I preview our model using modelviewer the
Plastic.002
material is missing it's color. Other renderers like bablyonjs look fine.I have been trying the new
transmission
property, so somehow the different parameters betweenPlastic.001
(which just has alpha < 1) and the new way of achieving transparency using thetransmission
parameter remove the color from the material.Live Demo
Drag the model into the above mentioned viewers and it will look like this:
Version
Browser Affected
OS
[ ] Android
[ ] iOS
[ ] Linux
[x] MacOS
[ ] Windows