Preview glTF 2.0 models in WebGL using three.js and a drag-and-drop interface.
Viewer: gltf-viewer.donmccurdy.com
npm install
npm run dev
- Limited drag-and-drop support in Safari.
Drag-and-drop preview for glTF 2.0 models in WebGL using three.js.
Home Page: https://gltf-viewer.donmccurdy.com/
License: MIT License
Preview glTF 2.0 models in WebGL using three.js and a drag-and-drop interface.
Viewer: gltf-viewer.donmccurdy.com
npm install
npm run dev
So I tried exporting a thing from Minecraft.
The textures don't show up at all. I haven't looked inside the glb yet to know whether this is just a non-compliant export or there's actually a bug here.
FWIW, the textures do show up in Babylon Sandbox. But if this turns out to be a glTF "dialect" or something not in spec, we should pester the Minecraft folks to fix.
An object with the "default" material does not support vertex skinning. For example, the "SimpleSkin" model at https://github.com/javagl/gltfTutorialModels/tree/2.0/SimpleSkin right now passes validation and should show the animation that is shown in the screenshot.
This is likely due to the default vertex shader not having the joint matrix uniforms.
(It's a bit unfortunate that there can be no "universal" default material/shader. It's probably necessary to create an own shader, at runtime, for each number of joints. At least, that's what I did in JglTF. Maybe uniform buffer objects could solve this, but I'm not an expert here).
Hopefully this is not just me doing anything silly, but lights don't seem to be applied to the scene. They are loaded, though, but the same 2 DirectionalLights + Ambient light are always applied instead of the ones defined by the GLTF file.
For testing, this is the default Blender cube (painted red) with a green point light on top +
an ambient light (which I think should replace any default light the viewer adds), created using the official Blender exporter:
{
"accessors" : [
{
"bufferView" : 0,
"componentType" : 5121,
"count" : 36,
"max" : [
23
],
"min" : [
0
],
"type" : "SCALAR"
},
{
"bufferView" : 1,
"componentType" : 5126,
"count" : 24,
"max" : [
1.0000004768371582,
1.0,
1.0000005960464478
],
"min" : [
-1.0000003576278687,
-1.0,
-1.0000003576278687
],
"type" : "VEC3"
},
{
"bufferView" : 2,
"componentType" : 5126,
"count" : 24,
"max" : [
1.0,
1.0,
1.0
],
"min" : [
-1.0,
-1.0,
-1.0
],
"type" : "VEC3"
}
],
"asset" : {
"generator" : "Khronos Blender glTF 2.0 exporter",
"version" : "2.0"
},
"bufferViews" : [
{
"buffer" : 0,
"byteLength" : 36,
"byteOffset" : 0,
"target" : 34963
},
{
"buffer" : 0,
"byteLength" : 288,
"byteOffset" : 36,
"target" : 34962
},
{
"buffer" : 0,
"byteLength" : 288,
"byteOffset" : 324,
"target" : 34962
}
],
"buffers" : [
{
"byteLength" : 612,
"uri" : "data:application/octet-stream;base64,AAECAwEABAUGBAcFCAkKCAsJDA0ODA8NEBESEBMRFBUWFBcVAACAPwAAgL///3+/AQCAvwAAgL/9/38/+v9/vwAAgL8DAIC/AACAPwAAgL8AAIA/AwCAvwAAgD/6/38/BACAPwAAgD/3/3+///9/vwAAgD8AAIC/9f9/PwAAgD8FAIA/BACAPwAAgD/3/3+/AACAPwAAgL8AAIA/AACAPwAAgL///3+/9f9/PwAAgD8FAIA/9f9/PwAAgD8FAIA/AQCAvwAAgL/9/38/AACAPwAAgL8AAIA/AwCAvwAAgD/6/38/AwCAvwAAgD/6/38/+v9/vwAAgL8DAIC/AQCAvwAAgL/9/38///9/vwAAgD8AAIC///9/vwAAgD8AAIC/AACAPwAAgL///3+/+v9/vwAAgL8DAIC/BACAPwAAgD/3/3+/AAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAACAP+z/PzMAAJg0AACAP+z/PzMAAJg0AACAP+z/PzMAAJg0AACAP+z/PzMAAJg0AACYtAkA4LMAAIA/AACYtAkA4LMAAIA/AACYtAkA4LMAAIA/AACYtAkA4LMAAIA/AACAv///D7QCAHC0AACAv///D7QCAHC0AACAv///D7QCAHC0AACAv///D7QCAHC0AACANAAAYDQAAIC/AACANAAAYDQAAIC/AACANAAAYDQAAIC/AACANAAAYDQAAIC/"
}
],
"cameras" : [
{
"name" : "Camera",
"perspective" : {
"aspectRatio" : 1.703595982340029,
"yfov" : 0.5033799409866333,
"zfar" : 100.0,
"znear" : 0.10000000149011612
},
"type" : "perspective"
}
],
"extensions" : {
"KHR_lights" : {
"lights" : [
{
"color" : [
0.0,
1.0,
0.004836175590753555
],
"name" : "Lamp",
"quadraticAttenuation" : 0.03333335240683057,
"type" : "point"
},
{
"color" : [
0.0,
0.0,
0.0
],
"name" : "Ambient_Scene",
"type" : "ambient"
}
]
}
},
"extensionsRequired" : [
"KHR_materials_common",
"KHR_lights"
],
"extensionsUsed" : [
"KHR_materials_common",
"KHR_lights"
],
"materials" : [
{
"emissiveFactor" : [
0.0,
0.0,
0.0
],
"extensions" : {
"KHR_materials_common" : {
"ambientFactor" : [
1.0,
1.0,
1.0
],
"diffuseFactor" : [
0.640000066757203,
0.09475075743721062,
0.24241738680627023,
1.0
],
"shininessFactor" : 12.298039215686275,
"specularFactor" : [
0.44219279289245605,
0.5,
0.12052442133426666
],
"type" : "commonPhong"
}
},
"name" : "Material"
}
],
"meshes" : [
{
"name" : "Cube",
"primitives" : [
{
"attributes" : {
"NORMAL" : 2,
"POSITION" : 1
},
"indices" : 0,
"material" : 0
}
]
}
],
"nodes" : [
{
"camera" : 0,
"name" : "Correction_Camera",
"rotation" : [
-0.7071067690849304,
-0.0,
0.0,
0.7071067690849304
]
},
{
"children" : [
0
],
"name" : "Camera",
"rotation" : [
0.483536034822464,
0.33687159419059753,
-0.20870360732078552,
0.7804827094078064
],
"translation" : [
7.481131553649902,
5.34366512298584,
6.5076398849487305
]
},
{
"mesh" : 0,
"name" : "Cube"
},
{
"extensions" : {
"KHR_lights" : {
"light" : 0
}
},
"name" : "Correction_Lamp",
"rotation" : [
-0.7071067690849304,
-0.0,
0.0,
0.7071067690849304
]
},
{
"children" : [
3
],
"name" : "Lamp",
"rotation" : [
0.16907575726509094,
0.7558802962303162,
-0.27217137813568115,
0.570947527885437
],
"scale" : [
1.0,
1.0,
0.9999999403953552
],
"translation" : [
-0.9681686162948608,
2.3538269996643066,
-0.8437037467956543
]
}
],
"scene" : 0,
"scenes" : [
{
"extensions" : {
"KHR_lights" : {
"light" : 1
}
},
"name" : "Scene",
"nodes" : [
2,
4,
1
]
}
]
}
Large models may require larger far
plane, and changes to OrbitControls min/max distance. This should be inferred from the model's size automatically.
In view of KhronosGroup/glTF-Sample-Models#53 I wanted to update the remaining (material-related) simple test models to glTF 2.0, but already got stuck with the first one. This model https://github.com/javagl/glTF-Sample-Models/blob/c25938698c36c7530d2572725de4bafc894c0985/2.0/SimpleMaterial/glTF-Embedded-buffer/SimpleMaterial.gltf
(it should be complete and "standalone") seems to be displayed as a gray, semi-transparent triangle, although it should be a "gold" material.
Is the viewer supposed to support textureless materials?
(This was tested on FireFox 52.1.1. In Chrome, nothing is displayed at all, but that may be due to being an old version of Chrome - I'll test it with a newer one later. The BabylonJS viewer doesn't display anything either, ... these are basically different flavors of what I referred to in KhronosGroup/glTF-Sample-Models#53 (comment) ...)
E.g. try dragging in a single folder containing all of the assets.
Drag&Drop only makes the viewer unusable in environment that do provide it e.g. I'm using ratpoison as a window manager and I do not have an integrated file browser.
e.g. tree.GLTF
does not work, says "no .gltf asset found".
If a buffer references "foo.bin" but the file is actually "foo.BIN", that's also unsupported, but less surprising.
This is more of a GLTF2Loader
issue... ๐
The attached file doesn't have normal
attribute. So this code fails:
(1) there should be more than one camera?
(2) white blocks everywhere (this might be a problem in the model?
Tested in Chrome, Windows, flask_centred model, upload button fails on zip, selecting files drops textures.
Hi! I tried drag-and-drop of the Metal-Rough Spheres sample model in Chrome 57, and I got a result that doesn't look like the metal/rough channels are in use.
Is this a known issue? I would expect the model to behave more like this.
seeing scrollbars in windows screenshots
After dragging in just the .gltf
file, without the necessary .bin
, I see "[object Event]" as the error message.
Automatically detect morph targets in scene, and create sliders to test the targets if no animation clips use them already.
It appears the viewer is rendering all glTF materials with back-face culling enabled. A flag was added in the past few months to address this:
materials[n].doubleSided
(schema)
You can test this with the same model used for testing in #10.
Note that the discussion surrounding this flag resulted in a decision that the rear-facing polygons should have flipped normal vectors (typically using gl_FrontFace
to test). The schema description field mentions the normal vectors specifically.
When working with the sample models from the GLTF sample models repo, I found this mesh outputs unexpectedly.
https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/WalkingLady
I am looking into the solution, just wanted to check if this is something you were aware of or could point me in the right direction with fixing it.
Thanks,
Clark
Sorry if this is nitpicking, I'm not really sure what is your goal with this viewer and this is something I think is not "right behavior" for a viewer, but again, it depends on what your goal with the viewer is.
The rotation will be around the previous point of rotation. I think this should be reset every time a new model is loaded, as going back to the center is impossible (because there are no buttons or references). For now, the obvious workaround is reloading the whole page, but that should not be necessary in my opinion.
Again, sorry if this is nitpicking, and thanks for reading :).
I have a test model called Normal-Tangent Test, where I try rotating the UVs of a normal map around. The reflected vectors are not supposed to be swayed by such shenanigans.
In particular, the light source is not supposed to "spin around", and in this screenshot I'm using the "Bridge" environment and you can clearly see the bridge spinning around.
Here's sbtron's viewer with correct reflections.
And here are some notes I made when creating this model showing it working correctly in ThreeJS.
because i think we all have enough RAM for just one more copy of Chromium...
But also being able to double-click and open glTF on macOS would be nice.
For GIF-making purposes, object should appear to rotate in place.
Sorry for opening so many issues, but I'm using your viewer as the way to check a exporter I'm writing, and I'm going feature by feature :).
In this case, I took a model you uploaded to the Blender glTF exporter repository for an issue with skinning. I've converted the "Dog.blend" file, but the model doesn't play in the viewer. Maybe it's an issue with the exporter, but I can't see anything wrong with the converted file.
I'm getting lots of errors on the console with the viewer, which I'm guessing they should not happen even if the model is somehow broken.
I've modified locally the viewer to get the animations play 10x slower by doing:
const dt = (time - this.prevTime) / 1000 / 10;
Here's how the flamingo from KhronosGroup/glTF-Blender-Exporter#48 looks like:
https://drive.google.com/file/d/0B6qxNbhuunW8X1hRSXdqb1haN28/view
I think it would be nice if one could directly drag&drop a zip file download from sketchfab.
I think I should be a matter of refactoring a bit the folder code you have but using http://stuk.github.io/jszip/
Especially helpful for remotely hosted models. Should probably also have some indicator when JS loads, as it won't work to drag-and-drop a model before that.
Workflow:
It would be interesting to let users import a .gltf
to the viewer, select a mesh (???), then drag-and-drop their textures and assign them as PBR maps, then export the result.
This needs a bit more thought. See obj2gltf issue 67.
e.g. wrong format, wrong glTF version, ...
I'm using three-point lighting now, but it doesn't seem to generalize especially well, even to the https://github.com/KhronosGroup/glTF-Sample-Models/ examples. Would appreciate suggestions/PRs to improve this.
I'm missing a way to access the loaded scene directly so I could check how the attributes are loaded and so on. It could be just as simple as a console.log(scene)
or defining it globally.
diffuseFactor
values with alpha != 1.0 are not respected on KHR_material_common, although they are working with PBR SpecularGlossiness. The fix seems just adding the alpha value to the opacity
on materialParams
, but I'm not sure if something else is required, hence the bug report :)
Drag-and-drop API isn't implemented fully enough, as far as I can tell.
Viewer doesn't render in Safari; after opening dev tools (triggering a resize) i see a very narrow canvas. Possibly missing a flexbox vendor prefix?
aside: drag-and-drop not working in Safari is a known, and unrelated, issue.
@donmccurdy is this using the latest glTF loader in three.js?
Should this load all sample models in https://github.com/KhronosGroup/glTF-Sample-Models/?
Currently all animations are played by default. Instead, play only the first, and provide UI controls to enable/disable additional animations.
Causes bad lighting with cube/voxel-based models.
I tried a few files, including the standard Duck.gltf but always get the error below. I confirmed that the same Duck file can be imported into threejs.org/editor and displays correctly.
bundle.js:3285 Uncaught TypeError: skins.forEach is not a function at GLTFParser.THREE.GLTF2Loader.GLTFParser.loadNodes (bundle.js:3285) at GLTFParser.THREE.GLTF2Loader.GLTFParser._withDependencies (bundle.js:2318) at GLTFParser.THREE.GLTF2Loader.GLTFParser.loadScenes (bundle.js:3542) at GLTFParser.THREE.GLTF2Loader.GLTFParser._withDependencies (bundle.js:2318) at GLTFParser.THREE.GLTF2Loader.GLTFParser.parse (bundle.js:2343) at GLTF2Loader.parse (bundle.js:790) at bundle.js:715 at XMLHttpRequest. (bundle.js:51687)
Some feature requests to think about...
The default environment is "None", and most new users don't know to change this default. PBR models that make good use of metallic surfaces look particularly bad in this environment. Perhaps another environment, such as Park (Day), would be a better default?
Allow The model to be shown against flat gray, but reflecting an environment that is otherwise unseen. Several PBR viewers/editors including Substance Painter actually use this mode as the default, as it allows the model to be presented with high-quality reflections, without the distraction of rendering the environment directly behind the model.
Offer an option to rotate the environment.
this looks very weird on my MBP.. gpu/driver issue? or a bug somewhere?
For debugging purposes, a slider to adjust animation speed would be very useful.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.