From dd79faeffa41ac89be545b0feda27c2965aa92a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=94?= Date: Mon, 27 Jan 2025 08:52:26 +0100 Subject: [PATCH] chore: docs --- docs/API/additional-exports.mdx | 2 +- docs/API/canvas.mdx | 114 +++++++++++++++------ docs/API/events.mdx | 2 +- docs/API/hooks.mdx | 2 +- docs/API/objects.mdx | 4 +- docs/{tutorials => API}/testing.mdx | 4 +- docs/{tutorials => API}/typescript.mdx | 10 +- docs/advanced/pitfalls.mdx | 2 +- docs/advanced/scaling-performance.mdx | 2 +- docs/tutorials/basic-animations.mdx | 2 +- docs/tutorials/events-and-interaction.mdx | 2 +- docs/tutorials/how-it-works.mdx | 2 +- docs/tutorials/loading-models.mdx | 2 +- docs/tutorials/loading-textures.mdx | 2 +- docs/tutorials/using-with-react-spring.mdx | 101 ------------------ docs/tutorials/v9-migration-guide.mdx | 43 +++++--- readme.md | 15 --- 17 files changed, 129 insertions(+), 182 deletions(-) rename docs/{tutorials => API}/testing.mdx (98%) rename docs/{tutorials => API}/typescript.mdx (89%) delete mode 100644 docs/tutorials/using-with-react-spring.mdx diff --git a/docs/API/additional-exports.mdx b/docs/API/additional-exports.mdx index 075def88bb..886f572a40 100644 --- a/docs/API/additional-exports.mdx +++ b/docs/API/additional-exports.mdx @@ -1,6 +1,6 @@ --- title: Additional Exports -nav: 9 +nav: 8 --- | export | usage | diff --git a/docs/API/canvas.mdx b/docs/API/canvas.mdx index 7723e69230..366bcbc542 100644 --- a/docs/API/canvas.mdx +++ b/docs/API/canvas.mdx @@ -1,6 +1,6 @@ --- title: Canvas -description: 'The Canvas object is your portal into three.js.' +description: The Canvas object is your portal into three.js nav: 4 --- @@ -27,7 +27,7 @@ const App = () => ( | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | | children | three.js JSX elements or regular components | | | fallback | optional DOM JSX elements or regular components in case GL is not supported | | -| gl | Props that go into the default renderer, or your own renderer. Also accepts a synchronous callback like `gl={canvas => new Renderer({ canvas })}` | `{}` | +| gl | Props that go into the default renderer. Accepts sync/async callback with default props `gl={defaults => new Renderer({ ...defaults })}` | `{}` | | camera | Props that go into the default camera, or your own `THREE.Camera` | `{ fov: 75, near: 0.1, far: 1000, position: [0, 0, 5] }` | | scene | Props that go into the default scene, or your own `THREE.Scene` | `{}` | | shadows | Props that go into `gl.shadowMap`, can be set true for `PCFsoft` or one of the following: 'basic', 'percentage', 'soft', 'variance' | `false` | @@ -99,6 +99,29 @@ function App() { > [!NOTE] > Ideally, and if possible, your fallback is a seamless, visual replacement for what the canvas would have otherwise rendered. +## WebGPU + +Recent Three.js now includes a WebGPU renderer. While still a work in progress and not fully backward-compatible with all of Three's features, the renderer requires an async initialization method. R3F streamlines this by allowing the gl prop to return a promise. + +```jsx +import * as THREE from 'three/webgpu' +import * as TSL from 'three/tsl' +import { Canvas, extend, useFrame, useThree } from '@react-three/fiber' + +export default () => ( + { + extend(THREE) + const renderer = new THREE.WebGPURenderer(props) + return renderer.init().then(() => renderer) + }}> + + + + + +``` + ## Custom Canvas R3F can render to a root, similar to how `react-dom` and all the other React renderers work. This allows you to shave off `react-dom` (~40kb), `react-use-measure` (~3kb) and, if you don't need them, `pointer-events` (~7kb) (you need to explicitly import `events` and add them to the config otherwise). @@ -120,22 +143,27 @@ extend(THREE) // Create a react root const root = createRoot(document.querySelector('canvas')) -// Configure the root, inject events optionally, set camera, etc -root.configure({ events, camera: { position: [0, 0, 50] } }) +async function app() { + // Configure the root, inject events optionally, set camera, etc + // This *must* be called before render, and it must be awaited + await root.configure({ events, camera: { position: [0, 0, 50] } }) -// createRoot by design is not responsive, you have to take care of resize yourself -window.addEventListener('resize', () => { - root.configure({ size: { width: window.innerWidth, height: window.innerHeight } }) -}) + // createRoot by design is not responsive, you have to take care of resize yourself + window.addEventListener('resize', () => { + root.configure({ size: { width: window.innerWidth, height: window.innerHeight } }) + }) + + // Trigger resize + window.dispatchEvent(new Event('resize')) -// Trigger resize -window.dispatchEvent(new Event('resize')) + // Render entry point + root.render() -// Render entry point -root.render() + // Unmount and dispose of memory + // root.unmount() +} -// Unmount and dispose of memory -// root.unmount() +app() ``` ## Tree-shaking @@ -150,14 +178,20 @@ import { Mesh, BoxGeometry, MeshStandardMaterial } from 'three' extend({ Mesh, BoxGeometry, MeshStandardMaterial }) -createRoot(canvas).render( - <> - - - - - , -) +async function app() { + const root = createRoot(document.querySelector('canvas')) + await root.configure() + root.render( + <> + + + + + , + ) +} + +app() ``` There's an [official babel plugin](https://github.com/pmndrs/react-three-babel) which will do this for you automatically: @@ -167,12 +201,18 @@ There's an [official babel plugin](https://github.com/pmndrs/react-three-babel) import { createRoot } from '@react-three/fiber' -createRoot(canvasNode).render( - - - - , -) +async function app() { + const root = createRoot(document.querySelector('canvas')) + await root.configure() + root.render( + + + + , + ) +} + +app() // Out: @@ -185,10 +225,16 @@ extend({ MeshStandardMaterial: _MeshStandardMaterial, }) -createRoot(canvasNode).render( - - - - , -) +async function app() { + const root = createRoot(document.querySelector('canvas')) + await root.configure() + root.render( + + + + , + ) +} + +app() ``` diff --git a/docs/API/events.mdx b/docs/API/events.mdx index 1286b16a11..602b840397 100644 --- a/docs/API/events.mdx +++ b/docs/API/events.mdx @@ -1,7 +1,7 @@ --- title: Events description: All the events you can hook up to -nav: 8 +nav: 7 --- `three.js` objects that implement their own `raycast` method (meshes, lines, etc) can be interacted with by declaring events on them. We support pointer events, clicks and wheel-scroll. Events contain the browser event as well as the `three.js` event data (object, point, distance, etc). You may want to [polyfill](https://github.com/jquery/PEP) them, if that's a concern. diff --git a/docs/API/hooks.mdx b/docs/API/hooks.mdx index 03cd152eb0..f39c8a8704 100644 --- a/docs/API/hooks.mdx +++ b/docs/API/hooks.mdx @@ -1,7 +1,7 @@ --- title: Hooks description: Hooks are the heart of react-three-fiber -nav: 7 +nav: 6 --- Hooks allow you to tie or request specific information to your component. For instance, components that want to participate in the renderloop can use `useFrame`, components that need to be informed of three.js specifics can use `useThree` and so on. All hooks clean up after themselves once the component unmounts. diff --git a/docs/API/objects.mdx b/docs/API/objects.mdx index 69837c4d4e..b10e3827ca 100644 --- a/docs/API/objects.mdx +++ b/docs/API/objects.mdx @@ -1,7 +1,7 @@ --- title: Objects, properties and constructor arguments -description: 'All the effective ways of using React Three Fiber' -nav: 6 +description: All the effective ways of using React Three Fiber +nav: 5 --- ## Declaring objects diff --git a/docs/tutorials/testing.mdx b/docs/API/testing.mdx similarity index 98% rename from docs/tutorials/testing.mdx rename to docs/API/testing.mdx index 6a69cc24d8..4434f34ec1 100644 --- a/docs/tutorials/testing.mdx +++ b/docs/API/testing.mdx @@ -1,7 +1,7 @@ --- title: 'Testing' -description: Let's test our 3D Scene -nav: 19 +description: How to handle unit tests +nav: 10 --- Like with every other application testing is an important factor when it comes to releasing an application into the wild and when it comes to React Three Fiber we can use React Three Test Renderer to achieve this. diff --git a/docs/tutorials/typescript.mdx b/docs/API/typescript.mdx similarity index 89% rename from docs/tutorials/typescript.mdx rename to docs/API/typescript.mdx index f1b334a556..059f83abd5 100644 --- a/docs/tutorials/typescript.mdx +++ b/docs/API/typescript.mdx @@ -1,11 +1,9 @@ --- -title: Using with TypeScript -description: This guide will help through common scenarios and how to approach them with TypeScript. -nav: 18 +title: TypeScript +description: Common scenarios and how to approach them with TypeScript +nav: 9 --- -This tutorial will assume some React and TypeScript knowledge. You can fork and follow along from [this starter codesandbox](https://codesandbox.io/s/brnsm). - ## Typing with `useRef` React's `useRef` won't automatically infer types despite pointing it to a typed ref. @@ -85,7 +83,7 @@ declare module '@react-three/fiber' { } // react-three-fiber will create your custom component and TypeScript will understand it -; + ``` ## Exported types diff --git a/docs/advanced/pitfalls.mdx b/docs/advanced/pitfalls.mdx index 3b974aaa00..ea690e05c7 100644 --- a/docs/advanced/pitfalls.mdx +++ b/docs/advanced/pitfalls.mdx @@ -1,7 +1,7 @@ --- title: Performance pitfalls description: Performance 1x1 -nav: 11 +nav: 12 --- ## Tips and Tricks diff --git a/docs/advanced/scaling-performance.mdx b/docs/advanced/scaling-performance.mdx index 9ffda44498..8825894747 100644 --- a/docs/advanced/scaling-performance.mdx +++ b/docs/advanced/scaling-performance.mdx @@ -1,7 +1,7 @@ --- title: Scaling performance description: This is a short primer on how to scale performance. -nav: 10 +nav: 11 --- Running WebGL can be quite expensive depending on how powerful your devices are. In order to mitigate this, especially if you want to make your application available to a broad variety of devices, including weaker options, you should look into performance optimizations. This article goes through a couple of them. diff --git a/docs/tutorials/basic-animations.mdx b/docs/tutorials/basic-animations.mdx index eb237a314e..6638e44694 100644 --- a/docs/tutorials/basic-animations.mdx +++ b/docs/tutorials/basic-animations.mdx @@ -1,7 +1,7 @@ --- title: Basic Animations description: This guide will help you understand refs, useFrame and how to make basic animations with Fiber -nav: 16 +nav: 17 --- This tutorial will assume some React knowledge, and will be based on [this starter codesandbox](https://codesandbox.io/s/getting-started-01-12q81?from-embed), so just fork it and follow along! diff --git a/docs/tutorials/events-and-interaction.mdx b/docs/tutorials/events-and-interaction.mdx index 7e0c0b4853..a437393c2f 100644 --- a/docs/tutorials/events-and-interaction.mdx +++ b/docs/tutorials/events-and-interaction.mdx @@ -1,7 +1,7 @@ --- title: 'Events and Interaction' description: Let's make our meshes react to user input. -nav: 13 +nav: 14 --- This tutorial will assume some React knowledge, and will be based on [this starter codesandbox](https://codesandbox.io/s/getting-started-01-12q81?from-embed), so just fork it and follow along! diff --git a/docs/tutorials/how-it-works.mdx b/docs/tutorials/how-it-works.mdx index 3dbfd8fce8..c56817a060 100644 --- a/docs/tutorials/how-it-works.mdx +++ b/docs/tutorials/how-it-works.mdx @@ -2,7 +2,7 @@ title: How does it work? description: This is an advanced guide on the inner workings of Fiber, if you are just getting started, take a look at our introduction! -nav: 20 +nav: 18 --- React Three Fiber is a React renderer for **three.js**. diff --git a/docs/tutorials/loading-models.mdx b/docs/tutorials/loading-models.mdx index d53052476c..2ddb4b03eb 100644 --- a/docs/tutorials/loading-models.mdx +++ b/docs/tutorials/loading-models.mdx @@ -1,7 +1,7 @@ --- title: 'Loading Models' description: 3D Software to the web! -nav: 14 +nav: 15 --- > All the models in this page were created by Sara Vieira and are freely available to download from any of the sandboxes. diff --git a/docs/tutorials/loading-textures.mdx b/docs/tutorials/loading-textures.mdx index 2555d92227..0cc20ed460 100644 --- a/docs/tutorials/loading-textures.mdx +++ b/docs/tutorials/loading-textures.mdx @@ -1,7 +1,7 @@ --- title: 'Loading Textures' description: Let's load some fancy textures. -nav: 15 +nav: 16 --- > All textures used in this chapter were downloaded from [cc0textures](https://cc0textures.com/). diff --git a/docs/tutorials/using-with-react-spring.mdx b/docs/tutorials/using-with-react-spring.mdx deleted file mode 100644 index 497095144e..0000000000 --- a/docs/tutorials/using-with-react-spring.mdx +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: 'Using with React Spring' -description: Animating props with ease. -nav: 17 ---- - -This tutorial will assume some React knowledge, and will be based on [this starter codesandbox](https://codesandbox.io/s/interaction-98ppy?file=/src/App.js), so just fork it and follow along! - -We learned how to create small animations and also how to react to user interactions, but we haven't yet learned how to change these props in a way to create animations. - -For that, we are gonna use `react-spring`. `react-spring` is a spring physics based animation library and it works perfectly with React Three Fiber as it comes from the same maintainers, and it also has exports specifically created for use with React Three Fiber. - -## Spring Animations - -Let's start by defining some concepts about `react-spring` as it works with animations in a way you may not be used to. Usually when defining an animation or even a transition in CSS, you tell the code how much time you want the transition to last. - -```css -transition: opacity 200ms ease; -``` - -This is not how `react-spring` works, it instead works with `springs` and what that means is, the animation's flow depends on things like the mass, tension and friction of what you want to animate, and this is exactly what makes it so perfect to use with 3D. - -## Using `react-spring` - -Let's start by installing it: - -```bash -npm install three @react-spring/three -``` - -After that, we import everything from `@react-spring/three` as it contains the components that were created specifically for use with React Three Fiber. - -We need to import two things from `react-spring`: - -```js -import { useSpring, animated } from '@react-spring/three' -``` - -Let's go over them, shall we? - -- `useSpring` - A hook to transform values into animated-values -- `animated` - A component that is used instead of your DOM or mesh, so instead of using `mesh` you will be using `animated.mesh` if you want it to be affected by `react-spring` - -Let's create our first spring and attach it to our mesh when the user clicks. - -```js -const springs = useSpring({ scale: active ? 1.5 : 1 }) -``` - -What we did here is create a constant called `springs`, this constant will hold the animated values. - -`useSpring` itself takes one argument, and that is an object with all the things you want to animate. In this case, we just want to animate the scale and to hop between the value of 1 and the value of 1.5 depending on the active state. - -We can also deconstruct the return value of `useSpring` and just get the value we want, like so: - -```js -const { scale } = useSpring({ scale: active ? 1.5 : 1 }) -``` - -Now that we have this animated value, let's place it in our mesh: - -```jsx - setActive(!active)} ref={myMesh}> - - - -``` - -If you now click on the cube, you can see that it doesn't just jump from one value to the other, but instead it animates smoothly between the two values. - -One last touch we might want to add is the wobblier effect to the animation. For that we can import the `config` object from `react-spring`: - -```js -import { useSpring, animated, config } from '@react-spring/three' -``` - -Lastly when we call the hook, we can pass a value for config and pass the `wobbly` configuration: - -```js -const { scale } = useSpring({ - scale: active ? 1.5 : 1, - config: config.wobbly, -}) -``` - -You can check the other configuration options at the [`react-spring` documentation](https://react-spring.io). - -What we did in this chapter was: - -- Learn how to use `react-spring` with React Three Fiber -- Animate props in our 3D Mesh - - - -**Exercises** - -- Animate the position of the mesh using `react-spring` - -**Further Reading** - -- [React Spring Documentation](https://www.react-spring.io/) diff --git a/docs/tutorials/v9-migration-guide.mdx b/docs/tutorials/v9-migration-guide.mdx index 87ba19fcad..fdb07d5011 100644 --- a/docs/tutorials/v9-migration-guide.mdx +++ b/docs/tutorials/v9-migration-guide.mdx @@ -1,7 +1,7 @@ --- title: 'v9 Migration Guide' -description: Changes and new features with v9 and react 19 -nav: 12 +description: Changes and new features with v9 and React 19 +nav: 13 --- This is a compatability release for React 19, which brings further performance, stability, and type improvements. You can check out the React 19 changelog [here](https://react.dev/blog/2024/04/25/react-19). @@ -20,6 +20,7 @@ import { useLoader } from '@react-three/fiber' function Model() { const gltf = useLoader(GLTFLoader, '/path/to/model.glb') + // ... } // or, @@ -27,6 +28,7 @@ function Model() { const loader = new GLTFLoader() function Model() { const gltf = useLoader(loader, '/path/to/model.glb') + // ... } ``` @@ -54,17 +56,40 @@ const Controls = extend(OrbitControls) ``` +## WebGPU + +Recent Three.js now includes a WebGPU renderer. While still a work in progress and not fully backward-compatible with all of Three's features, the renderer requires an async initialization method. R3F streamlines this by allowing the gl prop to return a promise. + +```jsx +import * as THREE from 'three/webgpu' +import * as TSL from 'three/tsl' +import { Canvas, extend, useFrame, useThree } from '@react-three/fiber' + +export default () => ( + { + extend(THREE) + const renderer = new THREE.WebGPURenderer(props) + return renderer.init().then(() => renderer) + }}> + + + + + +``` + ## Fixes ### Color Management of Textures -Automatic sRGB conversion of texture props is removed, and color textures are handled automatically for known built-in materials. This aligns with vanilla three behavior and fixes hard-to-debug errors where data textures like normals or displacement are corrupted or made non-linear (math and interpolation must be done linearly). For custom materials or shaders, make sure to annotate color textures with `texture.colorSpace = THREE.SRGBColorSpace` or `texture-colorSpace={THREE.SRGBColorSpace}` with JSX. +Automatic sRGB conversion of texture props has been removed. Color textures are now handled automatically for built-in materials, aligning with vanilla Three.js behavior. This prevents issues where data textures (e.g., normals or displacement) become corrupted or non-linear. For custom materials or shaders, annotate color textures with texture.colorSpace = THREE.SRGBColorSpace or texture-colorSpace={THREE.SRGBColorSpace} in JSX. For more details, see https://threejs.org/docs/#manual/en/introduction/Color-management. ### Suspense and Side-Effects -Correctness and handling of `Suspense` and fallback content have improved between both React and R3F. Side-effects like `attach` and constructor side-effects (e.g., controls, which may add event listeners) will no longer fire repeatedly without cleanup while a tree is suspending. This required a major rearchitecture over the last 2 years and collaboration upstream to iterate towards a robust solution. +The handling of Suspense and fallback content has improved in React and R3F. Side-effects like attach and constructor effects (e.g., controls adding event listeners) no longer fire repeatedly without proper cleanup during suspension. ```jsx import { ThreeElement, useThree } from '@react-three/fiber' @@ -94,15 +119,9 @@ function Controls() { ### Swapping with args and primitives -Internal handling of swapping elements when changing the `args` or primitive `object` prop has improved for structured children like an array or iterator (yes, React supports iterators and async iterators). Previously, primitives who shared an `object` could be updated out-of-order or removed from the scene along with their children. - -```jsx -// ✅ Mounts a,b,c,d -[a, b, c, d].map((object, i) => ) +Swapping elements when changing the `args` or primitive `object` prop has been improved for structured children like arrays or iterators (React supports both, including async iterators). Previously, primitives sharing an object could update out of order or be removed from the scene along with their children. -// ❌ Updates undefined,undefined,c,d -[d, c, b, a].map((object, i) => ) -``` +See: https://github.com/pmndrs/react-three-fiber/pull/3272 ## TypeScript Changes diff --git a/readme.md b/readme.md index cc00ca3d97..b2bf347c1e 100644 --- a/readme.md +++ b/readme.md @@ -1,9 +1,3 @@ -> [!WARNING] -> R3F v8 is not compatible with React 19 or Next 15, which uses React 19. Use the R3F v9 RC instead which can be installed with `@react-three/fiber@rc`. - -> [!NOTE] -> While we work on R3F v9 you can track compatibility of different libraries and common workarounds [here](https://github.com/verekia/three-gpu-ecosystem-tests). -

@react-three/fiber

[![Version](https://img.shields.io/npm/v/@react-three/fiber?style=flat&colorA=000000&colorB=000000)](https://npmjs.com/package/@react-three/fiber) @@ -26,15 +20,6 @@ npm install three @types/three @react-three/fiber --- - - ---- - #### Does it have limitations? None. Everything that works in Threejs will work here without exception.