Skip to content

Commit

Permalink
[v9] refactor(core)!: always set colormanagement, use r141 WebXR types (
Browse files Browse the repository at this point in the history
  • Loading branch information
CodyJasonBennett committed Jul 29, 2022
1 parent 43b82f3 commit 5c9544f
Show file tree
Hide file tree
Showing 11 changed files with 46 additions and 59 deletions.
6 changes: 3 additions & 3 deletions docs/tutorials/v8-migration-guide.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ The `vr` prop was removed in favor of automatic WebXR switching. Whenever a sess
In addition to the automatic rendering, useFrame will expose the current [`XRFrame`](https://developer.mozilla.org/en-US/docs/Web/API/XRFrame) obtained via [XRSession#requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/XRSession/requestAnimationFrame).

```ts
useFrame((state: RootState, delta: number, frame?: THREE.XRFrame) => { ... })
useFrame((state: RootState, delta: number, frame?: XRFrame) => { ... })
```

This removes the need for custom rendering loops when using WebXR pose data and abstractions like `useXRFrame` of [@react-three/xr](https://github.com/pmndrs/react-xr).
Expand All @@ -218,7 +218,7 @@ This is also supported by all cameras that you create, be it a THREE.Perspective
```jsx
import { PerspectiveCamera } from '@react-three/drei'

<Canvas>
;<Canvas>
<PerspectiveCamera makeDefault manual />
</Canvas>
```
Expand Down Expand Up @@ -333,7 +333,7 @@ window.addEventListener('resize', () => {
root.configure({
events,
camera: { position: [0, 0, 50], fov: 50 },
size: { width: window.innerWidth, height: window.innerHeight }
size: { width: window.innerWidth, height: window.innerHeight },
})
root.render(<App />)
})
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"@types/react-native": "0.67.4",
"@types/react-test-renderer": "^17.0.1",
"@types/scheduler": "^0.16.2",
"@types/three": "^0.139.0",
"@types/three": "^0.141.0",
"@typescript-eslint/eslint-plugin": "^5.17.0",
"@typescript-eslint/parser": "^5.17.0",
"eslint": "^8.12.0",
Expand All @@ -78,7 +78,7 @@
"react-native": "0.67.4",
"react-test-renderer": "^18.0.0",
"regenerator-runtime": "^0.13.9",
"three": "^0.139.0",
"three": "^0.141.0",
"three-stdlib": "^2.8.11",
"ts-jest": "^27.1.4",
"typescript": "^4.6.3"
Expand Down
2 changes: 1 addition & 1 deletion packages/fiber/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
"react": ">=18.0",
"react-dom": ">=18.0",
"react-native": ">=0.64",
"three": ">=0.133"
"three": ">=0.141"
},
"peerDependenciesMeta": {
"react-dom": {
Expand Down
12 changes: 4 additions & 8 deletions packages/fiber/src/core/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import {
useIsomorphicLayoutEffect,
Camera,
updateCamera,
setDeep,
} from './utils'
import { useStore } from './hooks'
import { Stage, Lifecycle, Stages } from './stages'
Expand Down Expand Up @@ -136,7 +135,7 @@ const createStages = (stages: Stage[] | undefined, store: UseBoundStore<RootStat

// Add useFrame loop to update stage
const frameCallback = {
current: (state: RootState, delta: number, frame?: THREE.XRFrame | undefined) => {
current: (state: RootState, delta: number, frame?: XRFrame | undefined) => {
subscribers = state.internal.subscribers
for (let i = 0; i < subscribers.length; i++) {
subscription = subscribers[i]
Expand Down Expand Up @@ -248,7 +247,7 @@ function createRoot<TCanvas extends Element>(canvas: TCanvas): ReconcilerRoot<TC
// Set up XR (one time only!)
if (!state.xr) {
// Handle frame behavior in WebXR
const handleXRFrame: THREE.XRFrameRequestCallback = (timestamp: number, frame?: THREE.XRFrame) => {
const handleXRFrame: XRFrameRequestCallback = (timestamp: number, frame?: XRFrame) => {
const state = store.getState()
if (state.frameloop === 'never') return
advance(timestamp, true, state, frame)
Expand Down Expand Up @@ -294,11 +293,8 @@ function createRoot<TCanvas extends Element>(canvas: TCanvas): ReconcilerRoot<TC
}
}

// Safely set color management if available.
// Avoid accessing THREE.ColorManagement to play nice with older versions
if ('ColorManagement' in THREE) {
setDeep(THREE, legacy, ['ColorManagement', 'legacyMode'])
}
// Set color management
;(THREE as any).ColorManagement.legacyMode = legacy
const outputEncoding = linear ? THREE.LinearEncoding : THREE.sRGBEncoding
const toneMapping = flat ? THREE.NoToneMapping : THREE.ACESFilmicToneMapping
if (gl.outputEncoding !== outputEncoding) gl.outputEncoding = outputEncoding
Expand Down
9 changes: 2 additions & 7 deletions packages/fiber/src/core/loop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function run(effects: Set<SubItem>, timestamp: number) {
effects.forEach(({callback}) => callback(timestamp))
}

function update(timestamp: number, state: RootState, frame?: THREE.XRFrame) {
function update(timestamp: number, state: RootState, frame?: XRFrame) {
// Run local effects
let delta = state.clock.getDelta()
// In frameloop='never' mode, clock times are updated using the provided timestamp
Expand Down Expand Up @@ -112,12 +112,7 @@ export function createLoop<TCanvas>(roots: Map<TCanvas, Root>) {
}
}

function advance(
timestamp: number,
runGlobalEffects: boolean = true,
state?: RootState,
frame?: THREE.XRFrame,
): void {
function advance(timestamp: number, runGlobalEffects: boolean = true, state?: RootState, frame?: XRFrame): void {
if (runGlobalEffects) run(globalEffects, timestamp)
if (!state) roots.forEach((root) => update(timestamp, root.store.getState()))
else update(timestamp, state, frame)
Expand Down
27 changes: 13 additions & 14 deletions packages/fiber/src/core/stages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { StoreApi, UseBoundStore } from 'zustand'
import { RootState } from './store'

export interface UpdateCallback {
(state: RootState, delta: number, frame?: THREE.XRFrame | undefined): void
(state: RootState, delta: number, frame?: XRFrame): void
}

export type UpdateCallbackRef = MutableRefObject<UpdateCallback>
Expand All @@ -28,10 +28,10 @@ export class Stage {

/**
* Executes all callback subscriptions on the stage.
* @param {number} delta - Delta time between frame calls.
* @param {THREE.XRFrame | undefined} [frame] - The XR frame if it exists.
* @param delta - Delta time between frame calls.
* @param [frame] - The XR frame if it exists.
*/
frame(delta: number, frame?: THREE.XRFrame | undefined) {
frame(delta: number, frame?: XRFrame) {
const subs = this.subscribers
const initialTime = performance.now()

Expand All @@ -44,9 +44,9 @@ export class Stage {

/**
* Adds a callback subscriber to the stage.
* @param {UpdateCallbackRef} ref - The mutable callback reference.
* @param {Store} store - The store to be used with the callback execution.
* @returns {() => void} A function to remove the subscription.
* @param ref - The mutable callback reference.
* @param store - The store to be used with the callback execution.
* @returns A function to remove the subscription.
*/
add(ref: UpdateCallbackRef, store: Store) {
this.subscribers.push({ ref, store })
Expand All @@ -68,10 +68,9 @@ const FPS_50 = 1 / 50

/**
* Class representing a stage that updates every frame at a fixed rate.
* @param {string} name - Name of the stage.
* @param {number} [fixedStep] - Fixed step rate.
* @param {number} [maxSubsteps] - Maximum number of substeps.
* @extends Stage
* @param name - Name of the stage.
* @param [fixedStep] - Fixed step rate.
* @param [maxSubsteps] - Maximum number of substeps.
*/
export class FixedStage extends Stage {
private _fixedStep: number
Expand All @@ -94,10 +93,10 @@ export class FixedStage extends Stage {

/**
* Executes all callback subscriptions on the stage.
* @param {number} delta - Delta time between frame calls.
* @param {THREE.XRFrame | undefined} [frame] - The XR frame if it exists.
* @param delta - Delta time between frame calls.
* @param [frame] - The XR frame if it exists.
*/
frame(delta: number, frame?: THREE.XRFrame | undefined) {
frame(delta: number, frame?: XRFrame) {
const initialTime = performance.now()
let substeps = 0
this._substepTimes = []
Expand Down
4 changes: 2 additions & 2 deletions packages/fiber/src/core/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export type Viewport = Size & {
aspect: number
}

export type RenderCallback = (state: RootState, delta: number, frame?: THREE.XRFrame) => void
export type RenderCallback = (state: RootState, delta: number, frame?: XRFrame) => void

type LegacyAlways = 'always'
export type FrameloopMode = LegacyAlways | 'auto' | 'demand' | 'never'
Expand Down Expand Up @@ -170,7 +170,7 @@ const context = React.createContext<UseBoundStore<RootState>>(null!)

const createStore = (
invalidate: (state?: RootState, frames?: number) => void,
advance: (timestamp: number, runGlobalEffects?: boolean, state?: RootState, frame?: THREE.XRFrame) => void,
advance: (timestamp: number, runGlobalEffects?: boolean, state?: RootState, frame?: XRFrame) => void,
): UseBoundStore<RootState> => {
const rootState = create<RootState>((set, get) => {
const position = new THREE.Vector3()
Expand Down
15 changes: 0 additions & 15 deletions packages/fiber/src/core/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,11 +321,6 @@ export function applyProps(instance: Instance, data: InstanceProps | DiffSet) {
else if (targetProp instanceof THREE.Layers && value instanceof THREE.Layers) targetProp.mask = value.mask
// Otherwise just set ...
else targetProp.set(value)
// For versions of three which don't support THREE.ColorManagement,
// Auto-convert sRGB colors
// https://github.com/pmndrs/react-three-fiber/issues/344
const supportsColorManagement = 'ColorManagement' in THREE
if (!supportsColorManagement && !rootState.linear && isColor) targetProp.convertSRGBToLinear()
}
// Else, just overwrite the value
} else {
Expand Down Expand Up @@ -381,13 +376,3 @@ export function updateCamera(camera: Camera & { manual?: boolean }, size: Size)
camera.updateMatrixWorld()
}
}

/**
* Safely sets a deeply-nested value on an object.
*/
export function setDeep(obj: any, value: any, keys: string[]) {
const key = keys.pop()!
const target = keys.reduce((acc, key) => acc[key], obj)

return (target[key] = value)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ exports[`web Canvas should correctly mount 1`] = `
style="width: 100%; height: 100%;"
>
<canvas
data-engine="three.js r139"
data-engine="three.js r141"
height="800"
style="display: block; width: 1280px; height: 800px;"
width="1280"
Expand Down
2 changes: 1 addition & 1 deletion packages/test-renderer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@
"peerDependencies": {
"react": ">=18.0",
"@react-three/fiber": ">=9.0.0",
"three": ">=0.133"
"three": ">=0.141"
}
}
22 changes: 17 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2263,10 +2263,17 @@
"@types/react" "*"
csstype "^3.0.2"

"@types/three@^0.139.0":
version "0.139.0"
resolved "https://registry.yarnpkg.com/@types/three/-/three-0.139.0.tgz#69af1f0c52f8eea390f513e05478af1dd7f49e6f"
integrity sha512-4V/jZhyq7Mv05coUzxL3bz8AuBOSi/1F0RY7ujisHTV0Amy/fnYJ+s7TSJ1/hXjZukSkpuFRgV+wvWUEMbsMbQ==
"@types/three@^0.141.0":
version "0.141.0"
resolved "https://registry.yarnpkg.com/@types/three/-/three-0.141.0.tgz#d9d81a54b28ebc2a56931dfd4d9c54d25c20d6c8"
integrity sha512-OJdKDgTPVBUgc+s74DYoy4aLznbFFC38Xm4ElmU1YwGNgR7GGFVvFCX7lpVgOsT6S1zSJtGdajTsOYE8/xY9nA==
dependencies:
"@types/webxr" "*"

"@types/webxr@*":
version "0.4.0"
resolved "https://registry.yarnpkg.com/@types/webxr/-/webxr-0.4.0.tgz#ad06c96a324293e0d5175d13dd5ded5931f90ba3"
integrity sha512-LQvrACV3Pj17GpkwHwXuTd733gfY+D7b9mKdrTmLdO7vo7P/o6209Qqtk63y/FCv/lspdmi0pWz6Qe/ull9kQg==

"@types/yargs-parser@*":
version "21.0.0"
Expand Down Expand Up @@ -8660,11 +8667,16 @@ three-stdlib@^2.8.11, three-stdlib@^2.8.12, three-stdlib@^2.9.1:
potpack "^1.0.1"
zstddec "^0.0.2"

three@^0.139.0, three@^0.139.2:
three@^0.139.2:
version "0.139.2"
resolved "https://registry.yarnpkg.com/three/-/three-0.139.2.tgz#b110799a15736df673b9293e31653a4ac73648dd"
integrity sha512-gV7q7QY8rogu7HLFZR9cWnOQAUedUhu2WXAnpr2kdXZP9YDKsG/0ychwQvWkZN5PlNw9mv5MoCTin6zNTXoONg==

three@^0.141.0:
version "0.141.0"
resolved "https://registry.yarnpkg.com/three/-/three-0.141.0.tgz#16677a12b9dd0c3e1568ebad0fd09de15d5a8216"
integrity sha512-JaSDAPWuk4RTzG5BYRQm8YZbERUxTfTDVouWgHMisS2to4E5fotMS9F2zPFNOIJyEFTTQDDKPpsgZVThKU3pXA==

throat@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b"
Expand Down

0 comments on commit 5c9544f

Please sign in to comment.