-
-
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
Use clamped material.emissiveIntensity at GLTF export #22007
Conversation
// note: `emissiveIntensity` is clamped between 0 and 1 to accommodate glTF spec. see #21849 and #22000. | ||
const emissiveIntensity = Math.min( Math.max( material.emissiveIntensity, 0 ), 1 ); | ||
const emissive = material.emissive.clone().multiplyScalar( emissiveIntensity ).toArray(); |
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.
That is not what I tried to suggest :-) . See #22000 (comment).
First scale the color by intensity.
If any RGB component exceeds 1, scale the color by ( 1 / max-component ) and throw a warning.
I think that is the best temporary workaround until the glTF specification is updated.
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.
@WestLangley but if we do that, then we might end up with a color that is much different than the original, right ? (in most cases, just white)
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.
Ok scrap my previous comment, I see what you mean. If one component exceeds 1, then scale ALL components by (1 / max component). It will indeed keep the right hue and scale closer to the intended emissiveIntensity
than if we just clamp it before scaling
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.
Right. Something like this:
const emissive = material.emissive.clone().multiplyScalar( material.emissiveIntensity );
const maxEmissiveComponent = Math.max( emissive.r, emissive.g, emissive.b );
if ( maxEmissiveComponent > 1 ) {
emissive.multiplyScalar( 1 / maxEmissiveComponent );
console.warn( 'THREE.GLTFExporter: Some emissive components exceed 1; emissive has been limited' );
}
if ( maxEmissiveComponent > 0 ) {
materialDef.emissiveFactor = emissive.toArray();
}
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.
@SBRK I think @WestLangley's suggestion is more readable 👍
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.
You're right. I implemented his suggestion
Thanks! |
Related issue: Fixed #22000
Description
With the recent change that exported
emissive
without multiplying byemissiveIntensity
, materials that had anemissiveIntensity
between 0 and 1 would come out too bright on exported gltf.Clamping the
emissiveIntensity
between 0 and 1 before multiplying by it ensures the output GLTF complies with specs andemissiveFactor
r g b components are between 0 and 1