This Is a Simple yet Powerful Three.js Boilerplate | by Franky Hung | Nov, 2022

Effortlessly use Three.js in your projects using my open-source library

Sample view used by this boilerplate

When you start a new Three.js project, you often get tired of copy-pasting all the boilerplate stuff to a single setup of scenes, cameras, and stuff. I get that completely because that’s my story as well. So I start developing my own three.js boilerplate code that feels like home.

I will share the one I am currently using and still perfecting. It might take a little longer to get you started at first, but if you take the time to understand the material and use it a couple more times, you’ll be able to start a new three.js project with ease!

  • Have all the usual three.js setup code for you so that you can focus on your own scene and objects.
  • Uses async/await to load textures/images such that the scene appears only after all resources have been loaded. You’ll never see suddenly texture-like things on your objects again!
  • Uses Parcel with minimal configuration, so you don’t need to care about setting up bundler.

Repo link. Feel free to fork it or make a pull request!

To run the repo locally, execute the following commands in sequence. After creation is finished in a few seconds a new browser tab will be opened for you:

  1. npm i
  2. make dev

In earlier versions of my three.js boilerplate, I used webpack As a bundling tool. It is a versatile and popular bundler, but I find it to have slow build times and too complex for simple projects.

Recently I started using the parcel, which is really easy to use. There is almost no admission cost, follow tutorials to build web apps with Parcel; It only takes five minutes to get started!

Parcel does all the JavaScript transpiling configuration for you. You need to specify which target browsers you want your app to work on. For example, provide this line in your package.json File and Parcel does all the dirty work for you:

"browserslist": "> 0.5%, last 2 versions, not dead"

It’s going to be a little long. If you are more practical person, just read the docs given in the code and give it a try! Everything I’ll explain is documented in the code anyway.

i won’t spend much time index.html file because it’s just the standard setup that imports index.js file. One additional thing I’ve added is the veil which appears only when all the time consuming resources (eg, images/textures) are loaded into the view.

index.js The file is where you put most, if not all, of your scene-building code. The essence of this boilerplate is in the convenience methods I wrote core-utils.jswhich is used by index.js, index.js The file consists of three main sections, which you should also see in the code for numbered comment sections:

  1. Initializing Core Three.js Components
  2. build your scene
  3. running the app

There’s also section 0, where you define tweakable parameters for your scene, which can also be tuned in the GUI control panel at the top-right. For example, if I want to change a particular color or material roughness/metallicity, I like to group the parameters there so I don’t have to scroll and find them throughout my code.

Here we use the following convenience methods (designed to work with default values ​​if no parameters are passed to them) core-utils.js To create basic three.js components:

  • createRenderer(rendererProps, configureRenderer)By default, it sets the pixel ratio and renderer size for you. You can pass additional configuration properties on the 1st param (eg antialias: true ), and pass a callback to configure the renderer on the second parameter.
  • createCamera(fov, near, far, camPos, camLookAt, aspect)By default, it uses PerspectiveCamera And it sets the camera position and look-at-point for you. If you do not pass any of these parameters, you can also see the default camera value.
  • createComposer(renderer, scene, camera, extraPasses)By default, it creates EffectComposer and adds RenderPass for you, so you just have to focus on which post-processing pass you want to add extraPasses call back.

We need to define a app object with a initScene way. The object structure here is quite tightly coupled with boilerplate code, but once you get used to it I find it fairly easy. and if your scene needs to be animated, define an additional updateScene Method to host your animation code.

  • initScene(): This function is called after the native three.js environment is set up so that you can insert your scene-building code (for example, add OrbitControls, Add Lighting, Spheres or Boxes, GUI Controls, FPS stats, etc.) here. Note that this function has async prefix so that you can use await To load textures and time consuming material within it. The default boilerplate mechanics here will just unveil your scene and start animating all your stuff at once initScene is loaded synchronously. This is important because we don’t want the rendered objects to wait for a second or two before the texture suddenly appears, which looks messy and unprofessional.
  • updateScene(interval, elapsed): This is where you animate your scene (eg, update OrbitControl, update FPS stats, rotate/move your mesh). Note that you do not need to call requestAnimationFrame method that is handled as core-utils.js, You also have two time-related parameters at your disposal:
    1. interval : elapsed time between two frames
    2. elapsed : the total time elapsed since the app was started

Finally, in section 3, you call runApp To start the app to display the rendered view in the browser. It sets up the normal HTML container, on-window resize listener, and mouse move/touch listeners for you before moving app.initScene() And later the animation.

If your scene is static and you don’t want the app to run idle frame redrawing 60 times per second, you can skip defining app.updateScene and pass false To enableAnimation the ultimate runApp,

Leave a Reply