diff --git a/packages/fiber/src/core/index.tsx b/packages/fiber/src/core/index.tsx index 32e18c5669..ed2f76f2f5 100644 --- a/packages/fiber/src/core/index.tsx +++ b/packages/fiber/src/core/index.tsx @@ -28,7 +28,7 @@ import { useIsomorphicLayoutEffect, Camera, updateCamera, - ColorManagement, + getColorManagement, } from './utils' import { useStore } from './hooks' import type { Properties } from '../three-types' @@ -286,6 +286,7 @@ function createRoot(canvas: TCanvas): ReconcilerRoot void (catalogue = { ...catalogue, ...objects }) +export const catalogue: Catalogue = {} +const extend = (objects: object): void => void Object.assign(catalogue, objects) function createRenderer(_roots: Map, _getEventPriority?: () => any) { function createInstance( diff --git a/packages/fiber/src/core/utils.ts b/packages/fiber/src/core/utils.ts index d2c1b3faaf..01ca430dc3 100644 --- a/packages/fiber/src/core/utils.ts +++ b/packages/fiber/src/core/utils.ts @@ -2,21 +2,15 @@ import * as THREE from 'three' import * as React from 'react' import { UseBoundStore } from 'zustand' import { EventHandlers } from './events' -import { AttachType, Instance, InstanceProps, LocalState } from './renderer' +import { AttachType, catalogue, Instance, InstanceProps, LocalState } from './renderer' import { Dpr, RootState, Size } from './store' -/** - * Safely accesses a deeply-nested value on an object to get around static bundler analysis. - */ -const getDeep = (obj: any, ...keys: string[]): any => keys.reduce((acc, key) => acc?.[key], obj) - export type ColorManagementRepresentation = { enabled: boolean | never } | { legacyMode: boolean | never } /** * The current THREE.ColorManagement instance, if present. */ -export const ColorManagement: ColorManagementRepresentation | null = - ('ColorManagement' in THREE && getDeep(THREE, 'ColorManagement')) || null +export const getColorManagement = (): ColorManagementRepresentation | null => (catalogue as any).ColorManagement ?? null export type Camera = THREE.OrthographicCamera | THREE.PerspectiveCamera export const isOrthographicCamera = (def: Camera): def is THREE.OrthographicCamera => @@ -356,7 +350,7 @@ export function applyProps(instance: Instance, data: InstanceProps | DiffSet) { // For versions of three which don't support THREE.ColorManagement, // Auto-convert sRGB colors // https://github.com/pmndrs/react-three-fiber/issues/344 - if (!ColorManagement && !rootState.linear && isColor) targetProp.convertSRGBToLinear() + if (!getColorManagement() && !rootState.linear && isColor) targetProp.convertSRGBToLinear() } // Else, just overwrite the value } else { diff --git a/packages/fiber/tests/core/renderer.test.tsx b/packages/fiber/tests/core/renderer.test.tsx index 6c53ee9312..c9c54fe730 100644 --- a/packages/fiber/tests/core/renderer.test.tsx +++ b/packages/fiber/tests/core/renderer.test.tsx @@ -734,6 +734,14 @@ describe('renderer', () => { }) it('should respect legacy prop', async () => { + // <= r138 internal fallback + const material = React.createRef() + extend({ ColorManagement: null }) + await act(async () => root.render()) + expect((THREE as any).ColorManagement.legacyMode).toBe(false) + expect(material.current!.color.toArray()).toStrictEqual(new THREE.Color('#111111').convertSRGBToLinear().toArray()) + extend({ ColorManagement: (THREE as any).ColorManagement }) + // r139 legacyMode await act(async () => { root.configure({ legacy: true }).render()