Skip to content

[FIX] Convert sRGB colors to linear when writing glTF#8267

Merged
willeastcott merged 7 commits intomainfrom
gltf-linear-srgb
Dec 19, 2025
Merged

[FIX] Convert sRGB colors to linear when writing glTF#8267
willeastcott merged 7 commits intomainfrom
gltf-linear-srgb

Conversation

@willeastcott
Copy link
Contributor

@willeastcott willeastcott commented Dec 19, 2025

This PR fixes the color space handling in the glTF exporter and refactors the importer for consistency.

Problem

The glTF exporter was writing material colors (baseColorFactor, emissiveFactor) directly from the engine's sRGB color space without converting to linear space as required by the glTF specification. This caused colors to become brighter on each import/export cycle.

Changes

Exporter (gltf-exporter.js):

  • Added Color.linear() conversion when writing baseColorFactor and emissiveFactor to convert from engine sRGB to glTF linear space

Parser (glb-parser.js):

  • Refactored manual Math.pow(x, 1/2.2) calls to use Color.gamma() method for:
    • baseColorFactor
    • emissiveFactor
    • diffuseFactor (KHR_materials_pbrSpecularGlossiness)
    • specularFactor (KHR_materials_pbrSpecularGlossiness)
    • specularColorFactor (KHR_materials_specular)
    • sheenColorFactor (KHR_materials_sheen)
    • attenuationColor (KHR_materials_volume)

Result

Import and export now use symmetric operations:

  • Import: Color.gamma() - linear (glTF) → sRGB (engine)
  • Export: Color.linear() - sRGB (engine) → linear (glTF)

Material colors are now preserved correctly through import/export roundtrips.

Checklist

  • I have read the contributing guidelines
  • My code follows the project's coding standards
  • This PR focuses on a single change

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a critical bug in the glTF exporter where material colors were not being converted from sRGB to linear color space, causing colors to become progressively brighter with each import/export cycle. It also refactors the parser to use cleaner Color API methods for consistency.

Key Changes:

  • Added proper color space conversion in the glTF exporter using Color.linear() for baseColorFactor and emissiveFactor
  • Refactored the glTF parser to replace manual Math.pow(x, 1/2.2) calls with the cleaner Color.gamma() method
  • Established symmetric operations: Color.gamma() for import (linear → sRGB) and Color.linear() for export (sRGB → linear)

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/extras/exporters/gltf-exporter.js Added sRGB to linear color space conversion when writing baseColorFactor and emissiveFactor to glTF, fixing the export color space bug
src/framework/parsers/glb-parser.js Refactored linear to sRGB conversions to use Color.gamma() method instead of manual Math.pow() calls for improved code clarity and consistency across all material color factors

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@willeastcott willeastcott changed the title [FIX] Convert linear colors to sRGB when writing glTF [FIX] Convert sRGB colors to linear when writing glTF Dec 19, 2025
Copy link
Contributor

@mvaligursky mvaligursky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one.

@willeastcott willeastcott merged commit 041aa9e into main Dec 19, 2025
7 checks passed
@willeastcott willeastcott deleted the gltf-linear-srgb branch December 19, 2025 09:47
mvaligursky pushed a commit that referenced this pull request Dec 19, 2025
* [FIX] Convert linear colors to sRGB when writing glTF

* Drop comments

* Tweak exporter

* Use clone

* Use array destructuring
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants