-
-
Notifications
You must be signed in to change notification settings - Fork 35.5k
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
FBXLoader: Support more texture formats. #28515
Changes from 4 commits
7e6377a
5e72a2c
b3bc369
35322b0
236444b
b19dfb8
248856c
f756cd3
fb50379
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,19 +31,33 @@ | |
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; | ||
import { FBXLoader } from 'three/addons/loaders/FBXLoader.js'; | ||
import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; | ||
import { EXRLoader } from 'three/addons/loaders/EXRLoader.js'; | ||
import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; | ||
import { TGALoader } from 'three/addons/loaders/TGALoader.js'; | ||
import { TIFFLoader } from 'three/addons/loaders/TIFFLoader.js'; | ||
import { DDSLoader } from 'three/addons/loaders/DDSLoader.js'; | ||
|
||
let camera, scene, renderer, stats, object, loader, guiMorphsFolder; | ||
const clock = new THREE.Clock(); | ||
const manager = new THREE.LoadingManager(); | ||
|
||
manager.addHandler( /\.tga$/i, new TGALoader() ); | ||
manager.addHandler( /\.dds$/i, new DDSLoader() ); | ||
manager.addHandler( /\.exr$/i, new EXRLoader() ); | ||
manager.addHandler( /\.hdr$/i, new RGBELoader() ); | ||
manager.addHandler( /\.tiff$/i, new TIFFLoader() ); | ||
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. Um, now that I look at the code I'm not so happy that the FBX example loads all the modules by default. In production, that makes the example considerably slower to load. I vote to remove the modifications to 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. I'll try to make a checkbox in UI that when checked will asynchronously import the loaders. Let's see (if I manage to do that) how would you like it that way. 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. Wouldn't it be more simple to test for 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. Better idea indeed. import the loaders when selecting the 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. I pushed a new commit, now lazily importing loaders. 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.
This is unfortunately not possible since we have to stick to ECMA 2018 and lint addon and src code respectively. Please revert the changes to Sorry, I think it's best to remove the asset from the example. It makes things just too complicated. We want to keep the example as simple as possible so devs can quickly start coding. Using the examples to test every possible code path of an addon is not top-priority. 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. I understand. I reverted it. I let there though some improvements on Regarding testing, if there would be a possibility to unit-test the assets we won't need to pile up to HTML examples. Maybe I will come up with such PR at some point. Related to ESLint ECMA version, should I make an issue about it to increase it to something more recent, to gain access to features like async import among others? Or there is some hard reason (which escapes me) for sticking with 2018 ? |
||
|
||
let camera, scene, renderer, stats, object, loader, guiMorphsFolder; | ||
let mixer; | ||
|
||
const clock = new THREE.Clock(); | ||
|
||
const params = { | ||
asset: 'Samba Dancing' | ||
}; | ||
|
||
const assets = [ | ||
'Samba Dancing', | ||
'morph_test' | ||
'morph_test', | ||
'with_non_native_textures' | ||
]; | ||
|
||
|
||
|
@@ -87,7 +101,7 @@ | |
grid.material.transparent = true; | ||
scene.add( grid ); | ||
|
||
loader = new FBXLoader( ); | ||
loader = new FBXLoader( manager ); | ||
loadAsset( params.asset ); | ||
|
||
renderer = new THREE.WebGLRenderer( { antialias: true } ); | ||
|
@@ -126,8 +140,18 @@ | |
|
||
object.traverse( function ( child ) { | ||
|
||
if ( child.material ) child.material.dispose(); | ||
if ( child.material && child.material.map ) child.material.map.dispose(); | ||
if ( child.material ) { | ||
|
||
const materials = Array.isArray( child.material ) ? child.material : [ child.material ]; | ||
materials.forEach( material => { | ||
|
||
if ( material.map ) material.map.dispose(); | ||
material.dispose(); | ||
|
||
} ); | ||
|
||
} | ||
|
||
if ( child.geometry ) child.geometry.dispose(); | ||
|
||
} ); | ||
|
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.
With this new code... If a
fbx
file usespsd
as textures, we no longer log a warning...? 🤔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.
Correct.
I searched globally in the repo for
psd
and did not find another place where it is handled specifically.I was thinking: do we need a dedicated handling for things that are not supported?
I mean, it does not need to be just
.psd
.It could be a hardcoded black list (possibly quite large) of things that we should throw a warning for if encountered.
What if we apply the same approach everywhere ?
IMO, that adds complexity without adding value.
That's why a dropped that branch.
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.
Ideally we could just do this:
But I guess for that to work we may need to add default handlers in
LoadingManager
?https://github.com/mrdoob/three.js/blob/dev/src/loaders/LoadingManager.js#L140C1-L140C66
Or even populate this array directly?
@Mugen87 What do you think?
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.
Um, I'm not sure I understand why it is required to add default handlers.
If a loader for an extension isn't found, an empty texture is returned and a warning is logged. That seems sufficient.
I was never a fan of the following branch in
FBXLoader
for processing non-supported images:Simply doing
texture = new Texture();
is better, imo.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.
const loader = this.manager.getHandler(
.${extension});
will return null for native images which are supposed to be handled without user adding default TextureLoader to the regex map for native extensions.That's why there is this fallback :
texture = this.textureLoader.load( fileName );
@mrdoob would eventually like to not return null for native images, but that would require prepopulating the regex map with default TextureLoader. My only fear that I can think of with that is that the list of native extensions would not be comprehensive enough, preventing handling images that the browser could have handled.
If we'd like to set default TextureLoader for native images (which I'm afraid of possible other implications) we have to make sure to not override an eventual existing loader if it was setup by the user
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.
Couldn't we have a second set with native extensions intended for
TextureLoader
(orImageBitmapLoader
). Meaning[ 'png', 'jpeg', ' jpg', 'gif', 'avif', 'webp' ]
. If an extension is not in that set, we check the non-native one ([ 'tga', 'tif', 'tiff', 'exr', 'dds', 'hdr', 'ktx2' ]
). If the check isfalse
, we return an empty texture.If we ever have an issue that something in the set is missing, we can add an entry.
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.
I see the will to simplify the logic especially those nested
if
branches. I pushed a new commit. The only reason for keeping around non native extensions is to be able to throw a warning in the console. If we won't want that warning, we don't need them around making theloader = specificLoader || defaultTextureLoader
simplifying even more.I believe though that we want that warning there, hence keeping around non native extensions set.