Core points
- Using React to drive 3D scenes in game development has many advantages, including clear separation of scene rendering from game logic, easy-to-understand components, real-time reloading of game resources, and the ability to use native browser tools to 3D scenes Check and debug as markers.
- react-three-renderer (R3R) provides a declarative API that encapsulates Three.js, allows decoupling view code from game logic, and creates small, easy-to-understand components.
- As game engines grow, it is crucial to use reducer mode to organize game logic into separate functions. This mode allows creating a clean and clear game loop and easily add more logic to the game loop.
- Draining and performance considerations are unique in building games using Three.js, React and WebGL. Using Chrome DevTools' timeline functionality is invaluable for debugging performance, and implementing strategies such as minimizing the number of re-renders in React can help optimize performance.
I am making a game called "Chameleon Charm". It is built using Three.js, React and WebGL. This article describes how these technologies work together using react-three-renderer (abbreviated as R3R).
Please check out the WebGL Getting Started Guide and the React and JSX Getting Started Guide on SitePoint for an introduction to React and WebGL. This article and the accompanying code use ES6 syntax.
The beginning of everything
A while ago, Pete Hunt made a joke in the #reactjs IRC channel, saying that he would use React to create a game:
I bet we can make a first-person shooter with React! The enemy has
A few years later, I did exactly this.
Chameleon Charm is a game that collects enhanced props that will allow you to narrow down to solve the infinite fractal maze. I've been working as a React developer for a few years and I'm curious to know if there is a way to use React to drive Three.js. At this time, R3R attracted my attention.
Why choose React?
I know what you are thinking: Why? Please let me explain. Here are some reasons to consider using React to drive 3D scenes:
- The "Declarative" view allows you to clearly separate scene rendering from game logic.
- Design easy-to-understand components such as
<player></player>
,<wall></wall>
,<level></level>
, and more. - "hot" (real-time) reload of game resources. Change textures and models and see their updates in the scene in real time!
- Check and debug 3D scenes as tags using native browser tools such as Chrome Inspector.
- Manage game resources in dependency graphs using Webpack, e.g.
<texture require="" src="%7B"></texture>
Let's set up a scenario to see how this all works.
React and WebGL
I created a sample GitHub repository to work with this article. Clone the repository and run the code as in the README and continue learning. It features SitePointy 3D robot as the main character!
Warning: R3R is still in the testing phase. Its API is unstable and may change in the future. Currently it only processes a subset of Three.js. I found it complete enough to build a complete game, but your results may vary.
Organization view code
The main benefit of using React to drive WebGL is that our view code is decoupled from the game logic. This means that the entities we render are small and easy to understand components.
R3R exposes a declarative API that encapsulates Three.js. For example, we can write:
<code><scene>></scene> <perspectivecamera> position={ new THREE.Vector3( 1, 1, 1 ) /> > </perspectivecamera></code>
Now we have an empty 3D scene with a camera. Adding a mesh to a scene is as simple as including a <mesh></mesh>
component and giving it <geometry></geometry>
is as easy as <material></material>
.
<code><scene>></scene> … <mesh>></mesh> <boxgeometry></boxgeometry> width={ 1 } height={ 1 } depth={ 1 } /> <meshbasicmaterial></meshbasicmaterial> color={ 0x00ff00 } /> > </code>
Behind the scenes, this will create a THREE.Scene and automatically add a grid with THREE.BoxGeometry. R3R handles the differences between old scenes and any changes. If you add a new mesh to the scene, the original mesh will not be recreated. Just like using normal React and DOM, 3D scenes only update the differences.
Because we work in React, we can detach the game entity into the component file. The Robot.js file in the sample repository demonstrates how to represent a major role using pure React view code. It is a "stateless function" component, which means it does not save any local state:
<code>const Robot = ({ position, rotation }) => <group></group> position={ position } rotation={ rotation } > <mesh> rotation={ localRotation }></mesh> <geometryresource></geometryresource> resourceId="robotGeometry" /> <materialresource></materialresource> resourceId="robotTexture" /> > >; </code>
Now we will include <robot></robot>
in our 3D scene!
<code><scene>></scene> … <mesh>></mesh>…> <robot></robot> position={…} rotation={…} /> > </code>
You can view more API examples on the R3R GitHub repository, or see the full sample settings in the included project.
Organizing game logic
The other half of the equation is to deal with game logic. Let's add some simple animations to our robot SitePointy.
How does traditional game loop work? They accept user input, analyze the old "world state", and return to the new world state for rendering. For convenience, let's store the "Game State" object in the component state. In a more mature project, you can move game state to Redux or Flux storage.
We will use the browser's requestAnimationFrame
API callback to drive our game loop and run the loop in GameContainer.js
. To animation the robot, let's calculate a new location based on the timestamp passed to requestAnimationFrame
and then store the new location in the state.
<code><scene>></scene> <perspectivecamera> position={ new THREE.Vector3( 1, 1, 1 ) /> > </perspectivecamera></code>
Calling setState()
will trigger the re-render of the child component and update the 3D scene. We pass state from container component to demo component: <game></game>
<code><scene>></scene> … <mesh>></mesh> <boxgeometry></boxgeometry> width={ 1 } height={ 1 } depth={ 1 } /> <meshbasicmaterial></meshbasicmaterial> color={ 0x00ff00 } /> > </code>We can apply a useful pattern to help organize this code. Updating the robot location is a simple time-based calculation. In the future, it may also consider previous robot locations from previous game states. A function that accepts some data, processes it, and returns new data is often called a reducer. We can abstract the moving code into a reducer function!
Now we can write a concise and clear game loop that contains only function calls:
<code>const Robot = ({ position, rotation }) => <group></group> position={ position } rotation={ rotation } > <mesh> rotation={ localRotation }></mesh> <geometryresource></geometryresource> resourceId="robotGeometry" /> <materialresource></materialresource> resourceId="robotTexture" /> > >; </code>To add more logic to the game loop, such as handling physics, create another reducer function and pass it to the result of the previous reducer:
<code><scene>></scene> … <mesh>></mesh>…> <robot></robot> position={…} rotation={…} /> > </code>As the growth of game engines, it becomes crucial to organize game logic into separate functions. Using reducer mode, this organization is very simple.
Resource Management
This is still an area of development for R3R. For textures, you can specify a url property on the JSX tag. Using Webpack, you can ask for the local image path:
<code>// … gameLoop( time ) { this.setState({ robotPosition: new THREE.Vector3( Math.sin( time * 0.01 ), 0, 0 ) }); } </code>With this setting, if you change the image on disk, your 3D scene will be updated in real time! This is invaluable for fast iterating game design and content.
For other resources (such as 3D models), you still have to use Three.js' built-in loader (such as JSONLoader) to handle them. I've tried using a custom webpack loader to load 3D model files, but ended up with too much work and no benefit. It is easier to think of models as binary data and use a file loader to load them. This can still implement real-time overloading of model data. You can see this in the sample code.
Debug
R3R supports React developer tool extensions for Chrome and Firefox. You can check your scene like you would check a normal DOM! Hovering over elements in the inspector displays their bounding boxes in the scene. You can also hover over the texture definition to see which objects in the scene use these textures.
Performance Precautions
When building Chameleon Charm, I encountered some performance issues that are unique to this workflow.
- I use Webpack for a hot reload time of up to 30 seconds! This is because each overload has to write large resources to the package. The solution is to implement Webpack's DLLPlugin, which reduces the reload time to less than 5 seconds.
- Ideally, your scene should be called only once per frame of rendering. After analyzing my game, React itself is the main bottleneck. Calling
setState()
multiple times per frame will result in double rendering and degrade performance.setState()
After exceeding a certain number of objects, R3R's performance will be worse than ordinary Three.js code. To me, it's about 1000 objects. You can compare R3R with Three.js in the "Benchmark" in the example.
That's it!
Check out Chameleon Charm to learn what you can do with this setting. While this toolchain is still young, I found that using R3R's React is crucial to clearly organize my WebGL game code. You can also check out the small but growing R3R sample page to see some well-organized code examples.
This article was peer-reviewed by Mark Brown and Kev Zettler. Thanks to all the peer reviewers at SitePoint for getting SitePoint content to its best!
FAQ for Building Games with ReactJS and WebGLWhat are the prerequisites for building games with ReactJS and WebGL?
To start building games with ReactJS and WebGL, you need a basic understanding of JavaScript, HTML, and CSS. Also need to know ReactJS (a popular JavaScript library for building user interfaces). In addition, it is crucial to understand WebGL (Web Graphics Library), a JavaScript API for rendering interactive 3D and 2D graphics. It will also be of great benefit to be familiar with ES6 syntax, npm (Node package manager) and command line.
How to integrate Unity with ReactJS?
Unity can be integrated with ReactJS using the react-unity-webgl package. This package allows you to embed Unity WebGL builds into ReactJS applications. You can install it using npm and import it into your project. You can then use the Unity component provided by the package to embed your Unity game into your ReactJS application.
What are the different ways to create 3D applications using React?
There are several ways to create a 3D application using React. One of the most popular methods is to use Three.js, a cross-browser JavaScript library for creating and displaying animated 3D computer graphics. Another approach is to use WebGL directly, but this may be more complicated. Other libraries such as react-three-fiber and react-unity-webgl can also be used to create 3D applications using React.
How to create interactive 3D graphics using WebGL?
WebGL allows you to create interactive 3D graphics directly in your browser, without plug-ins. You can use WebGL's API to create complex 3D graphics, animations, and games. However, WebGL's API is low-level and it can be complicated to use directly. Therefore, many developers prefer to use libraries like Three.js that provide a higher level of interface to WebGL.
What is the role of react-unity-webgl in game development?
react-unity-webgl package allows you to embed Unity WebGL builds into ReactJS applications. This means you can create complex 3D games with Unity and then easily integrate them into your ReactJS application. This is especially useful if you want to create a web-based game or interactive 3D application.
How to optimize my ReactJS and WebGL games for performance?
Optimizing games built with ReactJS and WebGL may involve multiple strategies. These strategies include minimizing the number of rerenders in React, using WebGL's built-in performance features such as requestAnimationFrame
to achieve smooth animations, and optimizing 3D models and textures for the web.
Can I build mobile games using ReactJS and WebGL?
Yes, you can use ReactJS and WebGL to build games running in a web browser on your mobile device. However, for native mobile games, you may want to consider using game development platforms like Unity or Unreal Engine, which can be exported directly to iOS and Android.
How to process user input in my ReactJS and WebGL games?
User input can be processed in ReactJS and WebGL games using standard JavaScript event handlers. You can listen to keyboard, mouse, and touch events and then update the game status accordingly. ReactJS also provides synthesis events that can be used to process user input across different browsers in a consistent manner.
Can I use other JavaScript libraries with ReactJS and WebGL?
Yes, you can use other JavaScript libraries with ReactJS and WebGL. For example, you might use Three.js for 3D graphics, Howler.js for audio, or Matter.js for physical processing. The key is to make sure these libraries work seamlessly in your game.
How to debug my ReactJS and WebGL games?
Games built using ReactJS and WebGL can be debugged using developer tools in a web browser. These tools allow you to check HTML, CSS, and JavaScript code, view console logs, and debug the code step by step. Additionally, React Developer Tools is a browser extension that allows you to check React component hierarchy, props, and state.
The above is the detailed content of Building a Game with Three.js, React and WebGL. For more information, please follow other related articles on the PHP Chinese website!

Choosing Python or JavaScript should be based on career development, learning curve and ecosystem: 1) Career development: Python is suitable for data science and back-end development, while JavaScript is suitable for front-end and full-stack development. 2) Learning curve: Python syntax is concise and suitable for beginners; JavaScript syntax is flexible. 3) Ecosystem: Python has rich scientific computing libraries, and JavaScript has a powerful front-end framework.

The power of the JavaScript framework lies in simplifying development, improving user experience and application performance. When choosing a framework, consider: 1. Project size and complexity, 2. Team experience, 3. Ecosystem and community support.

Introduction I know you may find it strange, what exactly does JavaScript, C and browser have to do? They seem to be unrelated, but in fact, they play a very important role in modern web development. Today we will discuss the close connection between these three. Through this article, you will learn how JavaScript runs in the browser, the role of C in the browser engine, and how they work together to drive rendering and interaction of web pages. We all know the relationship between JavaScript and browser. JavaScript is the core language of front-end development. It runs directly in the browser, making web pages vivid and interesting. Have you ever wondered why JavaScr

Node.js excels at efficient I/O, largely thanks to streams. Streams process data incrementally, avoiding memory overload—ideal for large files, network tasks, and real-time applications. Combining streams with TypeScript's type safety creates a powe

The differences in performance and efficiency between Python and JavaScript are mainly reflected in: 1) As an interpreted language, Python runs slowly but has high development efficiency and is suitable for rapid prototype development; 2) JavaScript is limited to single thread in the browser, but multi-threading and asynchronous I/O can be used to improve performance in Node.js, and both have advantages in actual projects.

JavaScript originated in 1995 and was created by Brandon Ike, and realized the language into C. 1.C language provides high performance and system-level programming capabilities for JavaScript. 2. JavaScript's memory management and performance optimization rely on C language. 3. The cross-platform feature of C language helps JavaScript run efficiently on different operating systems.

JavaScript runs in browsers and Node.js environments and relies on the JavaScript engine to parse and execute code. 1) Generate abstract syntax tree (AST) in the parsing stage; 2) convert AST into bytecode or machine code in the compilation stage; 3) execute the compiled code in the execution stage.

The future trends of Python and JavaScript include: 1. Python will consolidate its position in the fields of scientific computing and AI, 2. JavaScript will promote the development of web technology, 3. Cross-platform development will become a hot topic, and 4. Performance optimization will be the focus. Both will continue to expand application scenarios in their respective fields and make more breakthroughs in performance.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Dreamweaver CS6
Visual web development tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Linux new version
SublimeText3 Linux latest version

MantisBT
Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

SublimeText3 Chinese version
Chinese version, very easy to use
