three.js manual

Summary: The main index page for the three.js manual, listing all available guides, tutorials, references, and solutions organized by topic category including Getting Started, Fundamentals, Tips, Optimization, Solutions, WebGPU, and WebXR.

Getting Started

- Installation
- Creating a Scene
- Creating Text
- Drawing Lines
- FAQ
- Libraries and Plugins
- Loading 3D Models
- Uniform Types
- Useful Links
- WebGL Compatibility Check

Next Steps

- Animation System
- Color Management
- How to create VR content
- How to dispose of Objects
- How to update Things
- How to use Post Processing
- Matrix Transformations

Basics

- Fundamentals
- Responsive Design
- Prerequisites
- Setup

Fundamentals

- Primitives
- Scenegraph
- Materials
- Textures
- Lights
- Cameras
- Shadows
- Fog
- Render Targets
- Custom BufferGeometry
- Physics

Tips

- Rendering On Demand
- Debugging JavaScript
- Debugging GLSL
- Taking a screenshot
- Prevent the Canvas Being Cleared
- Get Keyboard Input From a Canvas
- Make the Canvas Transparent
- Use three.js as Background in HTML

Optimization

- Optimizing Lots of Objects
- Optimizing Lots of Objects Animated
- Using OffscreenCanvas in a Web Worker

Solutions

- Load an .OBJ file
- Load a .GLTF file
- Add a Background or Skybox
- How to Draw Transparent Objects
- Multiple Canvases, Multiple Scenes
- Picking Objects with the mouse
- Post Processing
- Using Shadertoy shaders
- Aligning HTML Elements to 3D
- Using Indexed Textures for Picking and Color
- Using A Canvas for Dynamic Textures
- Billboards and Facades
- Freeing Resources
- Making Voxel Geometry (Minecraft)
- Start making a Game

WebGPU

- WebGPURenderer
- Post-Processing

WebXR

- VR - Basics
- VR - Look To Select
- VR - Point To Select

Reference

- Material Table


three.js docs

Summary: The main documentation index for three.js, a JavaScript 3D library. This page provides a categorized listing of all classes, modules, and functions available in the Core library, Addons, and the Three Shading Language (TSL).

Core

The Core library provides the fundamental classes and modules for three.js, organized into the following categories: Animation, Audio, Cameras, Core, Extras, Geometries, Helpers, Lights, Loaders, Materials, Math, Nodes, Objects, Renderers, Scenes, and Textures.

Core / Animation

AnimationAction, AnimationClip, AnimationMixer, AnimationObjectGroup, AnimationUtils, BooleanKeyframeTrack, ColorKeyframeTrack, KeyframeTrack, NumberKeyframeTrack, PropertyBinding, PropertyMixer, QuaternionKeyframeTrack, StringKeyframeTrack, VectorKeyframeTrack

Core / Audio

Audio, AudioAnalyser, AudioContext, AudioListener, PositionalAudio

Core / Cameras

ArrayCamera, Camera, CubeCamera, OrthographicCamera, PerspectiveCamera, StereoCamera

Core / Core

BufferAttribute, BufferGeometry, Clock, EventDispatcher, Float16BufferAttribute, Float32BufferAttribute, GLBufferAttribute, InstancedBufferAttribute, InstancedBufferGeometry, InstancedInterleavedBuffer, Int16BufferAttribute, Int32BufferAttribute, Int8BufferAttribute, InterleavedBuffer, InterleavedBufferAttribute, Layers, Object3D, Raycaster, RenderTarget, RenderTarget3D, Timer, Uint16BufferAttribute, Uint32BufferAttribute, Uint8BufferAttribute, Uint8ClampedBufferAttribute, Uniform, UniformsGroup

Core / Extras

ArcCurve, CatmullRomCurve3, Controls, CubicBezierCurve, CubicBezierCurve3, Curve, CurvePath, DataUtils, Earcut, EllipseCurve, ImageUtils, LineCurve, LineCurve3, PMREMGenerator, Path, QuadraticBezierCurve, QuadraticBezierCurve3, Shape, ShapePath, ShapeUtils, SplineCurve, TextureUtils, Interpolations

Core / Geometries

BoxGeometry, CapsuleGeometry, CircleGeometry, ConeGeometry, CylinderGeometry, DodecahedronGeometry, EdgesGeometry, ExtrudeGeometry, IcosahedronGeometry, LatheGeometry, OctahedronGeometry, PlaneGeometry, PolyhedronGeometry, RingGeometry, ShapeGeometry, SphereGeometry, TetrahedronGeometry, TorusGeometry, TorusKnotGeometry, TubeGeometry, WireframeGeometry

Core / Helpers

ArrowHelper, AxesHelper, Box3Helper, BoxHelper, CameraHelper, DirectionalLightHelper, GridHelper, HemisphereLightHelper, PlaneHelper, PointLightHelper, PolarGridHelper, SkeletonHelper, SpotLightHelper

Core / Lights

AmbientLight, DirectionalLight, DirectionalLightShadow, HemisphereLight, IESSpotLight, Light, LightProbe, LightShadow, PointLight, PointLightShadow, ProjectorLight, RectAreaLight, SpotLight, SpotLightShadow

Core / Loaders

AnimationLoader, AudioLoader, BufferGeometryLoader, Cache, CompressedTextureLoader, CubeTextureLoader, DataTextureLoader, FileLoader, ImageBitmapLoader, ImageLoader, Loader, LoaderUtils, LoadingManager, MaterialLoader, NodeLoader, NodeMaterialLoader, NodeObjectLoader, ObjectLoader, TextureLoader

Core / Materials

Line2NodeMaterial, LineBasicMaterial, LineBasicNodeMaterial, LineDashedMaterial, LineDashedNodeMaterial, Material, MeshBasicMaterial, MeshBasicNodeMaterial, MeshDepthMaterial, MeshDistanceMaterial, MeshLambertMaterial, MeshLambertNodeMaterial, MeshMatcapMaterial, MeshMatcapNodeMaterial, MeshNormalMaterial, MeshNormalNodeMaterial, MeshPhongMaterial, MeshPhongNodeMaterial, MeshPhysicalMaterial, MeshPhysicalNodeMaterial, MeshSSSNodeMaterial, MeshStandardMaterial, MeshStandardNodeMaterial, MeshToonMaterial, MeshToonNodeMaterial, NodeMaterial, NodeMaterialObserver, PointsMaterial, PointsNodeMaterial, RawShaderMaterial, SSSLightingModel, ShaderMaterial, ShadowMaterial, ShadowNodeMaterial, SpriteMaterial, SpriteNodeMaterial, VolumeNodeMaterial

Core / Math

BezierInterpolant, Box2, Box3, Color, CubicInterpolant, Cylindrical, DiscreteInterpolant, Euler, Frustum, FrustumArray, Interpolant, Line3, LinearInterpolant, MathUtils, Matrix2, Matrix3, Matrix4, Plane, Quaternion, QuaternionLinearInterpolant, Ray, Sphere, Spherical, SphericalHarmonics3, Triangle, Vector2, Vector3, Vector4

Core / Nodes

AONode, AmbientLightNode, AnalyticLightNode, ArrayElementNode, ArrayNode, AssignNode, AtomicFunctionNode, AttributeNode, BarrierNode, BasicEnvironmentNode, BasicLightMapNode, BasicLightingModel, BitcastNode, BitcountNode, BufferAttributeNode, BufferNode, BuiltinNode, BumpMapNode, BypassNode, ClippingNode, CodeNode, ColorSpaceNode, ComputeBuiltinNode, ComputeNode, ConditionalNode, ConstNode, ContextNode, ConvertNode, CubeMapNode, CubeTextureNode, DirectionalLightNode, EnvironmentNode, EventNode, ExpressionNode, FlipNode, FrontFacingNode, FunctionCallNode, FunctionNode, FunctionOverloadingNode, GLSLNodeFunction, GLSLNodeParser, HemisphereLightNode, IESSpotLightNode, IndexNode, InputNode, InspectorNode, IrradianceNode, IsolateNode, JoinNode, LightProbeNode, LightingContextNode, LightingModel, LightingNode, LightsNode, LoopNode, MRTNode, MaterialNode, MaterialReferenceNode, MathNode, MaxMipLevelNode, MemberNode, ModelNode, Node, NodeAttribute, NodeBuilder, NodeCache, NodeCode, NodeError, NodeFrame, NodeFunction, NodeFunctionInput, NodeParser, NodeUniform, NodeVar, NodeVarying, NormalMapNode, Object3DNode, OperatorNode, OutputStructNode, OverrideContextNode, PMREMNode, PackFloatNode, ParameterNode, PassMultipleTextureNode, PassNode, PassTextureNode, PhongLightingModel, PhysicalLightingModel, PointLightNode, PointShadowNode, PointUVNode, ProjectorLightNode, PropertyNode, RTTNode, RangeNode, RectAreaLightNode, ReferenceBaseNode, ReferenceElementNode, ReferenceNode, ReflectorNode, RenderOutputNode, RendererReferenceNode, RotateNode, SampleNode, ScreenNode, SetNode, ShadowBaseNode, ShadowMaskModel, ShadowNode, SplitNode, SpotLightNode, StackNode, StackTrace, StorageArrayElementNode, StorageBufferNode, StorageTexture3DNode, StorageTextureNode, StructNode, StructTypeNode, SubBuildNode, SubgroupFunctionNode, TempNode, Texture3DNode, TextureNode, TextureSizeNode, ToneMappingNode, ToonLightingModel, ToonOutlinePassNode, UniformArrayElementNode, UniformArrayNode, UniformGroupNode, UniformNode, UnpackFloatNode, UserDataNode, VarNode, VaryingNode, VelocityNode, VertexColorNode, ViewportDepthNode, ViewportDepthTextureNode, ViewportSharedTextureNode, ViewportTextureNode, VolumetricLightingModel, WorkgroupInfoElementNode, WorkgroupInfoNode

Core / Objects

BatchedMesh, Bone, ClippingGroup, Group, InstancedMesh, LOD, Line, LineLoop, LineSegments, Mesh, Points, Skeleton, SkinnedMesh, Sprite

Core / Renderers

Backend, BlendMode, BundleGroup, CanvasTarget, CubeRenderTarget, GLSLNodeBuilder, IndirectStorageBufferAttribute, Info, InspectorBase, PostProcessing, QuadMesh, ReadbackBuffer, RenderPipeline, Renderer, StandardNodeLibrary, Storage3DTexture, StorageArrayTexture, StorageBufferAttribute, StorageInstancedBufferAttribute, StorageTexture, TimestampQueryPool, WGSLNodeBuilder, WGSLNodeFunction, WGSLNodeParser, WebGL3DRenderTarget, WebGLArrayRenderTarget, WebGLCubeRenderTarget, WebGLRenderTarget, WebGLRenderer, WebGLTimestampQueryPool, WebGPURenderer, WebGPUTimestampQueryPool, WebXRDepthSensing, WebXRManager, XRManager, UniformsUtils

Core / Scenes

Fog, FogExp2, Scene

Core / Textures

CanvasTexture, CompressedArrayTexture, CompressedCubeTexture, CompressedTexture, CubeDepthTexture, CubeTexture, Data3DTexture, DataArrayTexture, DataTexture, DepthTexture, ExternalTexture, FramebufferTexture, HTMLTexture, Source, Texture, VideoFrameTexture, VideoTexture

Addons

The Addons section provides additional classes and modules extending three.js functionality, organized into the following categories: Animation, Capabilities, Controls, Csm, Curves, Effects, Environments, Exporters, Generators, Geometries, Gpgpu, Helpers, Inspector, Interaction, Interactive, Lighting, Lights, Lines, Loaders, Materials, Math, Misc, Modifiers, Objects, Physics, Postprocessing, Renderers, Shaders, TSL, Textures, Transpiler, Utils, and Webxr.

Addons / Animation

AnimationClipCreator, CCDIKHelper, CCDIKSolver

Addons / Capabilities

WebGL, WebGPU

Addons / Controls

ArcballControls, DragControls, FirstPersonControls, FlyControls, MapControls, OrbitControls, PointerLockControls, TrackballControls, TransformControls

Addons / Csm

CSM, CSMFrustum, CSMHelper, CSMShadowNode, CSMShader

Addons / Curves

CinquefoilKnot, DecoratedTorusKnot4a, DecoratedTorusKnot4b, DecoratedTorusKnot5a, DecoratedTorusKnot5c, FigureEightPolynomialKnot, GrannyKnot, HeartCurve, HelixCurve, KnotCurve, NURBSCurve, NURBSSurface, NURBSVolume, TorusKnot, TrefoilKnot, TrefoilPolynomialKnot, VivianiCurve, NURBSUtils

Addons / Effects

AnaglyphEffect, AsciiEffect, OutlineEffect, ParallaxBarrierEffect, StereoEffect

Addons / Environments

ColorEnvironment, DebugEnvironment, RoomEnvironment

Addons / Exporters

DRACOExporter, EXRExporter, GLTFExporter, KTX2Exporter, OBJExporter, PLYExporter, STLExporter, USDZExporter

Addons / Generators

CityGenerator, FaceFrame, ForestGenerator, SidewalkGenerator, SkyscraperGenerator, TerrainGenerator, TreeGenerator

Addons / Geometries

BoxLineGeometry, ConvexGeometry, DecalGeometry, LoftGeometry, ParametricGeometry, RoundedBoxGeometry, TeapotGeometry, TextGeometry, ParametricFunctions

Addons / Gpgpu

BitonicSort

Addons / Helpers

AnimationPathHelper, LightProbeGridHelper, LightProbeHelper, OctreeHelper, PositionalAudioHelper, RapierHelper, RectAreaLightHelper, TextureHelper, VertexNormalsHelper, VertexTangentsHelper, ViewHelper

Addons / Inspector

Tab

Addons / Interaction

InteractionManager

Addons / Interactive

HTMLMesh, InteractiveGroup, SelectionBox, SelectionHelper

Addons / Lighting

ClusteredLighting, DynamicLighting, LightProbeGrid

Addons / Lights

LightProbeGenerator, RectAreaLightTexturesLib, RectAreaLightUniformsLib

Addons / Lines

Line2, LineGeometry, LineMaterial, LineSegments2, LineSegmentsGeometry, Wireframe, WireframeGeometry2

Addons / Loaders

AMFLoader, BVHLoader, ColladaComposer, ColladaLoader, ColladaParser, DDSLoader, DRACOLoader, EXRLoader, FBXLoader, Font, FontLoader, GCodeLoader, GLTFLoader, HDRCubeTextureLoader, HDRLoader, IESLoader, KMZLoader, KTX2Loader, KTXLoader, LDrawLoader, LUT3dlLoader, LUTCubeLoader, LUTImageLoader, LWOLoader, LottieLoader, MD2Loader, MDDLoader, MTLLoader, MaterialXLoader, NRRDLoader, OBJLoader, PCDLoader, PDBLoader, PLYLoader, PVRLoader, Rhino3dmLoader, STLLoader, SVGLoader, TDSLoader, TGALoader, TIFFLoader, TTFLoader, ThreeMFLoader, USDComposer, USDLoader, UltraHDRLoader, VOXLoader, VRMLLoader, VTKLoader, XYZLoader

Addons / Materials

LDrawConditionalLineMaterial, WoodNodeMaterial

Addons / Math

Capsule, ColorConverter, ConvexHull, ImprovedNoise, Lut, MeshSurfaceSampler, OBB, Octree, SimplexNoise, ColorSpaces

Addons / Misc

ConvexObjectBreaker, GPUComputationRenderer, Gyroscope, MD2Character, MD2CharacterComplex, MorphAnimMesh, MorphBlendMesh, ProgressiveLightMap, RollerCoasterGeometry, RollerCoasterLiftersGeometry, RollerCoasterShadowGeometry, SkyGeometry, TileCreasedNormalsPlugin, TreesGeometry, TubePainter, Volume, VolumeSlice

Addons / Modifiers

EdgeSplitModifier, Flow, InstancedFlow, SimplifyModifier, TessellateModifier

Addons / Objects

GroundedSkybox, Lensflare, LensflareElement, LensflareMesh, MarchingCubes, Reflector, ReflectorForSSRPass, Refractor, ShadowMesh, Sky, SkyMesh, Water, WaterMesh

Addons / Physics

AmmoPhysics, JoltPhysics, RapierPhysics

Addons / Postprocessing

AfterimagePass, BloomPass, BokehPass, ClearMaskPass, ClearPass, CubeTexturePass, DotScreenPass, EffectComposer, FXAAPass, FilmPass, FullScreenQuad, GTAOPass, GlitchPass, HalftonePass, LUTPass, MaskPass, OutlinePass, OutputPass, Pass, RenderPass, RenderPixelatedPass, RenderTransitionPass, SAOPass, SMAAPass, SSAARenderPass, SSAOPass, SSRPass, SavePass, ShaderPass, TAARenderPass, TexturePass, UnrealBloomPass

Addons / Renderers

CSS2DObject, CSS2DRenderer, CSS3DObject, CSS3DRenderer, CSS3DSprite, Projector, SVGObject, SVGRenderer

Addons / Shaders

ACESFilmicToneMappingShader, AfterimageShader, BasicShader, BleachBypassShader, BlendShader, BokehShader, BokehShader2, BrightnessContrastShader, ColorCorrectionShader, ColorifyShader, ConvolutionShader, CopyShader, DOFMipMapShader, DepthLimitedBlurShader, DigitalGlitch, DotScreenShader, ExposureShader, FXAAShader, FilmShader, FocusShader, FreiChenShader, GTAOShader, GammaCorrectionShader, HalftoneShader, HorizontalBlurShader, HorizontalTiltShiftShader, HueSaturationShader, KaleidoShader, LuminosityHighPassShader, LuminosityShader, MirrorShader, NormalMapShader, OutputShader, PoissonDenoiseShader, RGBShiftShader, SAOShader, SMAAShader, SSAOShader, SSRShader, SepiaShader, SobelOperatorShader, SubsurfaceScatteringShader, TriangleBlurShader, UnpackDepthRGBAShader, VelocityShader, VerticalBlurShader, VerticalTiltShiftShader, VignetteShader, VolumeShader, WaterRefractionShader

Addons / TSL

AfterImageNode, AmbientLightDataNode, AnaglyphPassNode, BilateralBlurNode, BloomNode, ChromaticAberrationNode, ClusteredLightsNode, DenoiseNode, DepthOfFieldNode, DirectionalLightDataNode, DotScreenNode, DynamicLightsNode, EnvMapCDFGenerator, FSR1Node, FXAANode, FilmNode, GTAONode, GaussianBlurNode, GodraysNode, HemisphereLightDataNode, ImportanceSampledEnvironment, LensflareNode, Lut3DNode, OutlineNode, ParallaxBarrierPassNode, PixelationNode, PixelationPassNode, PointLightDataNode, RGBShiftNode, RecurrentDenoiseNode, RetroPassNode, SMAANode, SSAAPassNode, SSGINode, SSRNode, SSSNode, SharpenNode, SobelOperatorNode, SpotLightDataNode, StereoCompositePassNode, StereoPassNode, TAAUNode, TRAANode, TemporalReprojectNode, TileShadowNode, TileShadowNodeHelper, TransitionNode, WebGLNodesHandler, Bayer, GroundedSkybox, Raymarching

Addons / Textures

FlakesTexture

Addons / Transpiler

Transpiler

Addons / Utils

LDrawUtils, SceneOptimizer, ShadowMapViewer, WorkerPool, BufferGeometryUtils, CameraUtils, ColorUtils, GeometryCompressionUtils, GeometryUtils, SceneUtils, SkeletonUtils, SortUtils, UVsDebug, WebGLTextureUtils, WebGPUTextureUtils

Addons / Webxr

ARButton, OculusHandModel, OculusHandPointerModel, VRButton, XRButton, XRControllerModel, XRControllerModelFactory, XREstimatedLight, XRHandMeshModel, XRHandModel, XRHandModelFactory, XRHandPrimitiveModel, XRPlanes, Text2D

TSL

The Three Shading Language (TSL) is a JavaScript-based shading language for three.js. It provides functions for building shader graphs and manipulating nodes in a programmatic way. TSL entries include control flow functions, math operations, lighting models, texture sampling, geometry access, and screen-space effects. Key entries include: Break, Const, Continue, Discard, EPSILON, HALF_PI, INFINITY, If, Loop, PI, PI2, Return, Switch, TBNViewMatrix, TWO_PI, Var, VarIntent, abs, acesFilmicToneMapping, acos, acosh, add, afterImage, agxToneMapping, all, alphaLine, alphaT, ambientOcclusion, anaglyphPass, and, anisotropy, anisotropyB, anisotropyT, any, ao, append, applyVarianceClipping, array, asin, asinh, assign, atan, atanh, atomicAdd, atomicAnd, atomicFunc, atomicLoad, atomicMax, atomicMin, atomicNode, atomicOr, atomicStore, atomicSub, atomicXor, attenuationColor, attenuationDistance, attribute, attributeArray, backgroundBlurriness, backgroundIntensity, backgroundRotation, barrelMask, barrelUV, barrier, batch, beautyTexelFromScreen, bentNormalView, bilateralBlur, billboarding, bitAnd, bitNot, bitOr, bitXor, bitangentGeometry, bitangentLocal, bitangentView, bitangentViewFrame, bitangentWorld, bitcast, bleach, blendBurn, blendColor, blendDodge, blendOverlay, blendScreen, bloom, boxBlur, buffer, bufferAttribute, builtin, builtinAOContext, builtinShadowContext, bumpMap, bypass, cache, cameraFar, cameraIndex, cameraNear, cameraNormalMatrix, cameraPosition, cameraProjectionMatrix, cameraProjectionMatrixInverse, cameraViewMatrix, cameraViewport, cameraWorldMatrix, cbrt, cdl, ceil, checker, chromaticAberration, cineonToneMapping, circle, clamp, clearcoat, clearcoatNormalView, clearcoatRoughness, clipSpace, clipToAABB, clipping, clippingAlpha, clusteredLights, code, collectNeighborhood, colorBleeding, colorSpaceToWorking, colorToDirection, compute, computeBuiltin, computeFrustumSize, computeHitDistFactor, computeKernel, computeSkinning, context, convertColorSpace, convertToTexture, cos, cosh, countLeadingZeros, countOneBits, countTrailingZeros, createVar, cross, cubeMapNode, cubeTexture, cubeTextureBase, curlNoise, dFdx, dFdy, dashSize, debug, decrement, decrementBefore, degrees, deltaTime, denoise, densityFogFactor, depth, depthBase, depthPass, determinant, difference, diffuseColor, diffuseColorDistance, diffuseContribution, directionToColor, directionToFaceDirection, dispersion, distance, div, dof, dot, dotScreen, drawIndex, dynamicBufferAttribute, dynamicLights, emissive, equal, equirectDirection, equirectUV, exp, exp2, exponentialHeightFogFactor, expression, faceDirection, faceForward, film, floatBitsToInt, floatBitsToUint, floor, fog, fract, frameGroup, frameId, frontFacing, fsr1, fwidth, fxaa, gain, gapSize, gaussianBlur, getNormalFromDepth, getParallaxCorrectNormal, getScreenPosition, getShadowMaterial, getShadowRenderObjectFunction, getSpecularDominantDirection, getTemporalVarianceFactor, getViewPosition, globalId, glsl, godrays, grayscale, greaterThan, greaterThanEqual, hardwareClipping, hash, hashBlur, highpModelNormalViewMatrix, highpModelViewMatrix, hue, increment, incrementBefore, inspector, instance, instanceIndex, instancedArray, instancedBufferAttribute, instancedDynamicBufferAttribute, instancedMesh, intBitsToFloat, interleavedGradientNoise, inverse, inverseSqrt, invocationLocalIndex, invocationSubgroupIndex, ior, iridescence, iridescenceIOR, iridescenceThickness, isolate, js, karisTemporalBlend, label, length, lengthSq, lensflare, lessThan, lessThanEqual, lightPosition, lightProjectionUV, lightShadowMatrix, lightTargetDirection, lightTargetPosition, lightViewPosition, lights, linearDepth, linearToneMapping, lobeNormalFalloff, lobeNormalWeight


Installation

Summary: This page covers how to set up a three.js project, including the basic project structure and two installation methods: installing via NPM with a build tool, or importing from a CDN.

Project structure

Every three.js project needs at least one HTML file to define the webpage, and a JavaScript file to run your three.js code. The structure and naming choices below aren't required, but will be used throughout this guide for consistency.

- *index.html*

- *main.js*

- *public/*

The *public/* folder is sometimes also called a "static" folder, because the files it contains are pushed to the website unchanged. Usually textures, audio, and 3D models will go here.

Now that we've set up the basic project structure, we need a way to run the project locally and access it through a web browser. Installation and local development can be accomplished with npm and a build tool, or by importing three.js from a CDN. Both options are explained in the sections below.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>My first three.js app</title>
    <style>
      body { margin: 0; }
    </style>
  </head>
  <body>
    <script type="module" src="/main.js"></script>
  </body>
</html>

Option 1: Install with NPM and a build tool

Installing from the npm package registry and using a build tool is the recommended approach for most users — the more dependencies your project needs, the more likely you are to run into problems that the static hosting cannot easily resolve. With a build tool, importing local JavaScript files and npm packages should work out of the box, without import maps.

Steps:
- Install Node.js. We'll need it to manage dependencies and to run our build tool.
- Install three.js and a build tool, Vite, using a terminal in your project folder. Vite will be used during development, but it isn't part of the final webpage. If you prefer to use another build tool, that's fine — we support modern build tools that can import ES Modules.

Installation added *node_modules/* and *package.json* to my project. What are they?

npm uses *package.json* to describe which versions of each dependency you've installed. If you have other people working on the project with you, they can install the original versions of each dependency simply by running *npm install*. If you're using version history, commit *package.json*.

npm installs the code for each dependency in a new *node_modules/* folder. When Vite builds your application, it sees imports for 'three' and pulls three.js files automatically from this folder. The *node_modules/* folder is used only during development, and shouldn't be uploaded to your web hosting provider or committed to version history.

Using three.js with TypeScript: Community-maintained TypeScript type definitions for three.js are available at three-types/three-ts-types.

From your terminal, run:

What is *npx*? npx is installed with Node.js, and runs command line programs like Vite so that you don't have to search for the right file in *node_modules/* yourself. If you prefer, you can put Vite's common commands into the package.json:scripts list, and use *npm run dev* instead.

If everything went well, you'll see a URL like *http://localhost:5173* appear in your terminal, and can open that URL to see your web application.

The page will be blank — you're ready to create a scene.

If you want to learn more about these tools before you continue, see:
- three.js journey: Local Server
- Vite: Command Line Interface
- MDN: Package management basics

Later, when you're ready to deploy your web application, you'll just need to tell Vite to run a production build — *npx vite build*. Everything used by the application will be compiled, optimized, and copied into the *dist/* folder. The contents of that folder are ready to be hosted on your website.

# three.js
npm install --save three

# vite
npm install --save-dev vite

Option 2: Import from a CDN

Installing without build tools will require some changes to the project structure given above.

We imported code from 'three' (an npm package) in *main.js*, and web browsers don't know what that means. In *index.html* we'll need to add an import map defining where to get the package. Put the code below inside the  tag, after the styles.

Don't forget to replace *<version>* with an actual version of three.js, like *"v0.149.0"*. The most recent version can be found on the npm version list.

We'll also need to run a *local server* to host these files at URL where the web browser can access them. While it's technically possible to double-click an HTML file and open it in your browser, important features that we'll later implement, do not work when the page is opened this way, for security reasons.

Install Node.js, then run serve to start a local server in the project's directory:

If everything went well, you'll see a URL like http://localhost:3000 appear in your terminal, and can open that URL to see your web application.

The page will be blank — you're ready to create a scene.

Many other local static servers are available — some use different languages instead of Node.js, and others are desktop applications. They all work basically the same way, and we've provided a few alternatives below.

More local servers:

Command Line: Command line local servers run from a terminal window. The associated programming language may need to be installed first.
- *npx http-server* (Node.js)
- *npx five-server* (Node.js)
- *python -m SimpleHTTPServer* (Python 2.x)
- *python -m http.server* (Python 3.x)
- *php -S localhost:8000* (PHP 5.4+)

GUI: GUI local servers run as an application window on your computer, and may have a user interface.
- Servez

Code Editor Plugins: Some code editors have plugins that spawn a simple server on demand.
- Five Server for Visual Studio Code
- Live Server for Visual Studio Code
- Live Server for Atom

When you're ready to deploy your web application, push the source files to your web hosting provider — no need to build or compile anything. The downside of that tradeoff is that you'll need to be careful to keep the import map updated with any dependencies (and dependencies of dependencies!) that your application requires. If the CDN hosting your dependencies goes down temporarily, your website will stop working too.

**IMPORTANT:** Import all dependencies from the same version of three.js, and from the same CDN. Mixing files from different sources may cause duplicate code to be included, or even break the application in unexpected ways.

<script type="importmap">
{
  "imports": {
    "three": "https://cdn.jsdelivr.net/npm/three@<version>/build/three.module.js",
    "three/addons/": "https://cdn.jsdelivr.net/npm/three@<version>/examples/jsm/"
  }
}
</script>

Addons

Out of the box, three.js includes the fundamentals of a 3D engine. Other three.js components — such as controls, loaders, and post-processing effects — are part of the addons/ directory. Addons do not need to be *installed* separately, but do need to be *imported* separately.

The example below shows how to import three.js with the `OrbitControls` and `GLTFLoader` addons. Where necessary, this will also be mentioned in each addon's documentation or examples.

Some excellent third-party projects are available for three.js, too. These need to be installed separately — see Libraries and Plugins.

import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

const controls = new OrbitControls( camera, renderer.domElement );
const loader = new GLTFLoader();

Next Steps

You're now ready to create a scene.


Creating a scene

Summary: A brief introduction to three.js that walks through setting up a scene with a spinning cube, covering scene/camera/renderer setup, geometry, materials, meshes, and animation loops.

Before we start

The goal of this section is to give a brief introduction to three.js. We will start by setting up a scene, with a spinning cube. A working example is provided at the bottom of the page in case you get stuck and need help.

If you haven't yet, go through the `Installation` guide. We'll assume you've already set up the same project structure (including *index.html* and *main.js* ), have installed three.js, and are either running a build tool, or using a local server with a CDN and import maps.

Creating the scene

To actually be able to display anything with three.js, we need three things: scene, camera and renderer, so that we can render the scene with camera.

Let's take a moment to explain what's going on here. We have now set up the scene, our camera and the renderer.

There are a few different cameras in three.js. For now, let's use a `PerspectiveCamera`.

The first attribute is the `field of view`. FOV is the extent of the scene that is seen on the display at any given moment. The value is in degrees.

The second one is the `aspect ratio`. You almost always want to use the width of the element divided by the height, or you'll get the same result as when you play old movies on a widescreen TV - the image looks squished.

The next two attributes are the `near` and `far` clipping plane. What that means, is that objects further away from the camera than the value of `far` or closer than `near` won't be rendered. You don't have to worry about this now, but you may want to use other values in your apps to get better performance.

Next up is the renderer. In addition to creating the renderer instance, we also need to set the size at which we want it to render our app. It's a good idea to use the width and height of the area we want to fill with our app - in this case, the width and height of the browser window. For performance intensive apps, you can also give `setSize` smaller values, like `window.innerWidth/2` and `window.innerHeight/2`, which will make the app render at quarter size.

If you wish to keep the size of your app but render it at a lower resolution, you can do so by calling `setSize` with false as `updateStyle` (the third argument). For example, `setSize(window.innerWidth/2, window.innerHeight/2, false)` will render your app at half resolution, given that your <canvas> has 100% width and height.

Last but not least, we add the `renderer` element to our HTML document. This is a <canvas> element the renderer uses to display the scene to us.

"That's all good, but where's that cube you promised?" Let's add it now.

To create a cube, we need a `BoxGeometry`. This is an object that contains all the points (`vertices`) and fill (`faces`) of the cube. We'll explore this more in the future.

In addition to the geometry, we need a material to color it. Three.js comes with several materials, but we'll stick to the `MeshBasicMaterial` for now. All materials take an object of properties which will be applied to them. To keep things very simple, we only supply a color attribute of `0x00ff00`, which is green. This works the same way that colors work in CSS or Photoshop (`hex colors`).

The third thing we need is a `Mesh`. A mesh is an object that takes a geometry, and applies a material to it, which we then can insert to our scene, and move freely around.

By default, when we call `scene.add()`, the thing we add will be added to the coordinates `(0,0,0)`. This would cause both the camera and the cube to be inside each other. To avoid this, we simply move the camera out a bit.

import * as THREE from 'three';

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

Rendering the scene

If you copied the code from above into the main.js file we created earlier, you wouldn't be able to see anything. This is because we're not actually rendering anything yet. For that, we need what's called a render or animation loop.

This will create a loop that causes the renderer to draw the scene every time the screen is refreshed (on a typical screen this means 60 times per second). If you're new to writing games in the browser, you might say "why don't we just create a setInterval ?" The thing is - we could, but `requestAnimationFrame` which is internally used in `WebGLRenderer` has a number of advantages. Perhaps the most important one is that it pauses when the user navigates to another browser tab, hence not wasting their precious processing power and battery life.

function animate( time ) {
  renderer.render( scene, camera );
}
renderer.setAnimationLoop( animate );

Animating the cube

If you insert all the code above into the file you created before we began, you should see a green box. Let's make it all a little more interesting by rotating it.

Add the following code right above the `renderer.render` call in your `animate` function:

This will be run every frame (normally 60 times per second), and give the cube a nice rotation animation. Basically, anything you want to move or change while the app is running has to go through the animation loop. You can of course call other functions from there, so that you don't end up with an `animate` function that's hundreds of lines.

The result

Congratulations! You have now completed your first three.js application. It's simple, but you have to start somewhere.

The full code is available below and as an editable live example. Play around with it to get a better understanding of how it works.

import * as THREE from 'three';

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setAnimationLoop( animate );
document.body.appendChild( renderer.domElement );

const geometry = new THREE.BoxGeometry( 1, 1, 1 );
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );

camera.position.z = 5;

function animate( time ) {

  cube.rotation.x = time / 2000;
  cube.rotation.y = time / 1000;

  renderer.render( scene, camera );

}


Creating Text

Summary: A guide covering multiple approaches to adding and rendering text in a three.js application, from simple DOM overlays to procedural 3D text geometries, bitmap fonts, and Troika Text.

1. DOM + CSS

Using HTML is generally the easiest and fastest manner to add text. This is the method used for descriptive overlays in most three.js examples.

You can add content to a

and use CSS markup to position absolutely at a position above all others with a z-index especially if you are running three.js full screen.

#info {
  position: absolute;
  top: 10px;
  width: 100%;
  text-align: center;
  z-index: 100;
  display:block;
}

2. Use `CSS2DRenderer` or `CSS3DRenderer`

Use these renderers to draw high-quality text contained in DOM elements to your three.js scene. This is similar to 1. except that with these renderers elements can be integrated more tightly and dynamically into the scene.

3. Draw text to canvas and use as a `Texture`

Use this method if you wish to draw text easily on a plane in your three.js scene.

4. Create a model in your favourite 3D application and export to three.js

Use this method if you prefer working with your 3d applications and importing the models to three.js.

5. Procedural Text Geometry

If you prefer to work purely in THREE.js or to create procedural and dynamic 3D text geometries, you can create a mesh whose geometry is an instance of THREE.TextGeometry:

`new THREE.TextGeometry( text, parameters );`

In order for this to work, however, your TextGeometry will need an instance of THREE.Font to be set on its "font" parameter.

See the `TextGeometry` page for more info on how this can be done, descriptions of each accepted parameter, and a list of the JSON fonts that come with the THREE.js distribution itself.

Examples

WebGL / geometry / text

WebGL / shadowmap

If Typeface is down, or you want to use a font that is not there, there's a tutorial with a python script for blender that allows you to export text to Three.js's JSON format: http://www.jaanga.com/2012/03/blender-to-threejs-create-3d-text-with.html

6. Bitmap Fonts

BMFonts (bitmap fonts) allow batching glyphs into a single BufferGeometry. BMFont rendering supports word-wrapping, letter spacing, kerning, signed distance fields with standard derivatives, multi-channel signed distance fields, multi-texture fonts, and more. See three-mesh-ui or three-bmfont-text.

Stock fonts are available in projects like A-Frame Fonts, or you can create your own from any .TTF font, optimizing to include only characters required for a project.

Some helpful tools:

- msdf-bmfont-web  *(web-based)*
- msdf-bmfont-xml  *(commandline)*
- hiero  *(desktop app)*

7. Troika Text

The troika-three-text package renders quality antialiased text using a similar technique as BMFonts, but works directly with any .TTF or .WOFF font file so you don't have to pregenerate a glyph texture offline. It also adds capabilities including:

- Effects like strokes, drop shadows, and curvature
- The ability to apply any three.js Material, even a custom ShaderMaterial
- Support for font ligatures, scripts with joined letters, and right-to-left/bidirectional layout
- Optimization for large amounts of dynamic text, performing most work off the main thread in a web worker


Drawing Lines

Summary: A tutorial on how to draw lines in Three.js using LineBasicMaterial, BufferGeometry with vertices, and the Line object, rather than wireframe Mesh geometry.

Drawing Lines

Let's say you want to draw a line or a circle, not a wireframe `Mesh`. First we need to set up the renderer, scene and camera (see the Creating a scene page).

Here is the code that we will use:

Next thing we will do is define a material. For lines we have to use `LineBasicMaterial` or `LineDashedMaterial`.

After material we will need a geometry with some vertices:

Note that lines are drawn between each consecutive pair of vertices, but not between the first and last (the line is not closed.)

Now that we have points for two lines and a material, we can put them together to form a line.

All that's left is to add it to the scene and call `renderer.render()`.

You should now be seeing an arrow pointing upwards, made from two blue lines.

const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 500 );
camera.position.set( 0, 0, 100 );
camera.lookAt( 0, 0, 0 );

const scene = new THREE.Scene();

//create a blue LineBasicMaterial
const material = new THREE.LineBasicMaterial( { color: 0x0000ff } );

const points = [];
points.push( new THREE.Vector3( - 10, 0, 0 ) );
points.push( new THREE.Vector3( 0, 10, 0 ) );
points.push( new THREE.Vector3( 10, 0, 0 ) );

const geometry = new THREE.BufferGeometry().setFromPoints( points );

const line = new THREE.Line( geometry, material );

scene.add( line );
renderer.render( scene, camera );


FAQ

Summary: A frequently asked questions page covering best-supported 3D model formats, viewport tags, scene scaling on resize, face culling, input validation, and Node.js usage in three.js.

Which 3D model format is best supported?

The recommended format for importing and exporting assets is glTF (GL Transmission Format). Because glTF is focused on runtime asset delivery, it is compact to transmit and fast to load.

three.js provides loaders for many other popular formats like FBX, Collada or OBJ as well. Nevertheless, you should always try to establish a glTF based workflow in your projects first.

Why are there meta viewport tags in examples?

These tags control viewport size and scale for mobile browsers (where page content may be rendered at different size than visible viewport).

<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">

How can scene scale be preserved on resize?

We want all objects, regardless of their distance from the camera, to appear the same size, even as the window is resized.

The key equation to solving this is this formula for the visible height at a given distance:

If we increase the window height by a certain percentage, then what we want is the visible height at all distances to increase by the same percentage.

This can not be done by changing the camera position. Instead you have to change the camera field-of-view.

visible_height = 2 * Math.tan( ( Math.PI / 180 ) * camera.fov / 2 ) * distance_from_camera;

Why is part of my object invisible?

This could be because of face culling. Faces have an orientation that decides which side is which. And the culling removes the backside in normal circumstances.

To see if this is your problem, change the material side to THREE.DoubleSide.

Why does three.js sometimes return strange results for invalid inputs?

For performance reasons, three.js doesn't validate inputs in most cases. It's your app's responsibility to make sure that all inputs are valid.

Can I use three.js in Node.js?

Because three.js is built for the web, it depends on browser and DOM APIs that don't always exist in Node.js. Some of these issues can be avoided by using shims like headless-gl and jsdom-global, or by replacing components like `TextureLoader` with custom alternatives. Other DOM APIs may be deeply intertwined with the code that uses them, and will be harder to work around. We welcome simple and maintainable pull requests to improve Node.js support, but recommend opening an issue to discuss your improvements first.


Libraries and Plugins

Summary: A community-maintained list of externally developed compatible libraries and plugins for three.js, organized by category including physics, postprocessing, file formats, geometry, 3D text, particle systems, IK, game AI, and wrappers/frameworks.

Libraries and Plugins

Listed here are externally developed compatible libraries and plugins for three.js. This list and the associated packages are maintained by the community and not guaranteed to be up to date. If you'd like to update this list make a PR!

Physics

Postprocessing

In addition to the official three.js postprocessing effects, support for some additional effects and frameworks are available through external libraries.

Intersection and Raycast Performance

Path Tracing

File Formats

In addition to the official three.js loaders, support for some additional formats is available through external libraries.

Geometry

3D Text and Layout

Particle Systems

Inverse Kinematics

Game AI

Wrappers and Frameworks


Loading 3D Models

Summary: A guide on loading 3D models in three.js, recommending the glTF format and providing workflow, loading instructions, troubleshooting tips, and guidance on asking for help.

Loading 3D Models

3D models are available in hundreds of file formats, each with different purposes, assorted features, and varying complexity. Although three.js provides many loaders, choosing the right format and workflow will save time and frustration later on. Some formats are difficult to work with, inefficient for realtime experiences, or simply not fully supported at this time.

This guide provides a workflow recommended for most users, and suggestions for what to try if things don't go as expected.

Before we start

If you're new to running a local server, begin with Installation first. Many common errors viewing 3D models can be avoided by hosting files correctly.

Recommended workflow

Where possible, we recommend using glTF (GL Transmission Format). Both .GLB and .GLTF versions of the format are well supported. Because glTF is focused on runtime asset delivery, it is compact to transmit and fast to load. Features include meshes, materials, textures, skins, skeletons, morph targets, animations, lights, and cameras.

Public-domain glTF files are available on sites like Sketchfab, or various tools include glTF export:

- Blender by the Blender Foundation
- Substance Painter by Allegorithmic
- Modo by Foundry
- Toolbag by Marmoset
- Houdini by SideFX
- Cinema 4D by MAXON
- COLLADA2GLTF by the Khronos Group
- FBX2GLTF by Facebook
- OBJ2GLTF by Analytical Graphics Inc
- …and many more

If your preferred tools do not support glTF, consider requesting glTF export from the authors, or posting on the glTF roadmap thread.

When glTF is not an option, popular formats such as FBX, OBJ, or COLLADA are also available and regularly maintained.

Loading

Only a few loaders (e.g. ObjectLoader) are included by default with three.js — others should be added to your app individually.

Once you've imported a loader, you're ready to add a model to your scene. Syntax varies among different loaders — when using another format, check the examples and documentation for that loader. For glTF, usage with global scripts would be:

import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

const loader = new GLTFLoader();

loader.load( 'path/to/model.glb', function ( gltf ) {

  scene.add( gltf.scene );

}, undefined, function ( error ) {

  console.error( error );

} );

Troubleshooting

You've spent hours modeling an artisanal masterpiece, you load it into the webpage, and — oh no! 😭 It's distorted, miscolored, or missing entirely. Start with these troubleshooting steps:

- Check the JavaScript console for errors, and make sure you've used an `onError` callback when calling `.load()` to log the result.
- View the model in another application. For glTF, drag-and-drop viewers are available for three.js and babylon.js. If the model appears correctly in one or more applications, file a bug against three.js. If the model cannot be shown in any application, we strongly encourage filing a bug with the application used to create the model.
- Try scaling the model up or down by a factor of 1000. Many models are scaled differently, and large models may not appear if the camera is inside the model.
- Try to add and position a light source. The model may be hidden in the dark.
- Look for failed texture requests in the network tab, like `"C:\\Path\To\Model\texture.jpg"`. Use paths relative to your model instead, such as `images/texture.jpg` — this may require editing the model file in a text editor.

Asking for help

If you've gone through the troubleshooting process above and your model still isn't working, the right approach to asking for help will get you to a solution faster. Post a question on the three.js forum and, whenever possible, include your model (or a simpler model with the same problem) in any formats you have available. Include enough information for someone else to reproduce the issue quickly — ideally, a live demo.


Uniform Types

Summary: Documents the mapping between GLSL uniform types and their corresponding JavaScript types in three.js, including support for uniform structures and arrays.

Uniform Types

Each uniform must have a `value` property. The type of the value must correspond to the type of the uniform variable in the GLSL code as specified for the primitive GLSL types in the table below. Uniform structures and arrays are also supported. GLSL arrays of primitive type must either be specified as an array of the corresponding THREE objects or as a flat array containing the data of all the objects. In other words; GLSL primitives in arrays must not be represented by arrays. This rule does not apply transitively. An array of `vec2` arrays, each with a length of five vectors, must be an array of arrays, of either five `Vector2` objects or ten `number`s.

| GLSL type | JavaScript type |
| --- | --- |
| int | Number |
| uint | Number |
| float | Number |
| bool | Boolean |
| bool | Number |
| vec2 | Vector2 |
| vec2 | Float32Array (*) |
| vec2 | Array (*) |
| vec3 | Vector3 |
| vec3 | Color |
| vec3 | Float32Array (*) |
| vec3 | Array (*) |
| vec4 | Vector4 |
| vec4 | Quaternion |
| vec4 | Float32Array (*) |
| vec4 | Array (*) |
| mat2 | Float32Array (*) |
| mat2 | Array (*) |
| mat3 | Matrix3 |
| mat3 | Float32Array (*) |
| mat3 | Array (*) |
| mat4 | Matrix4 |
| mat4 | Float32Array (*) |
| mat4 | Array (*) |
| ivec2, bvec2 | Float32Array (*) |
| ivec2, bvec2 | Array (*) |
| ivec3, bvec3 | Int32Array (*) |
| ivec3, bvec3 | Array (*) |
| ivec4, bvec4 | Int32Array (*) |
| ivec4, bvec4 | Array (*) |
| sampler2D | Texture |
| samplerCube | CubeTexture |

(*) Same for an (innermost) array (dimension) of the same GLSL type, containing the components of all vectors or matrices in the array.

Structured Uniforms

Sometimes you want to organize uniforms as `structs` in your shader code. The following style must be used so `three.js` is able to process structured uniform data.

This definition can be mapped on the following GLSL code:

uniforms = {
  data: {
    value: {
      position: new Vector3(),
      direction: new Vector3( 0, 0, 1 )
    }
  }
};

struct Data {
  vec3 position;
  vec3 direction;
};
uniform Data data;

Structured Uniforms with Arrays

It's also possible to manage `structs` in arrays. The syntax for this use case looks like so:

This definition can be mapped on the following GLSL code:

const entry1 = {
  position: new Vector3(),
  direction: new Vector3( 0, 0, 1 )
};
const entry2 = {
  position: new Vector3( 1, 1, 1 ),
  direction: new Vector3( 0, 1, 0 )
};

uniforms = {
  data: {
    value: [ entry1, entry2 ]
  }
};

struct Data {
  vec3 position;
  vec3 direction;
};
uniform Data data[ 2 ];


Useful Links

Summary: A curated collection of links to tutorials, courses, examples, tools, forums, and other resources useful when learning three.js.

Introduction

The following is a collection of links that you might find useful when learning three.js.

If you find something that you'd like to add here, or think that one of the links below is no longer relevant or working, feel free to click the 'edit' button in the bottom right and make some changes!

Note also that as three.js is under rapid development, a lot of these links will contain information that is out of date - if something isn't working as you'd expect or as one of these links says it should, check the browser console for warnings or errors. Also check the relevant docs pages.

Help forums

Three.js officially uses the forum (https://discourse.threejs.org/) and Stack Overflow (http://stackoverflow.com/tags/three.js/info) for help requests. If you need assistance with something, that's the place to go. Do NOT open an issue on Github for help requests.

Tutorials and courses

Getting started with three.js

- Three.js Fundamentals starting lesson (https://threejs.org/manual/#en/fundamentals)

- Beginning with 3D WebGL (https://codepen.io/rachsmith/post/beginning-with-3d-webgl-pt-1-the-scene) by Rachel Smith (https://codepen.io/rachsmith/).

- Animating scenes with WebGL and three.js (https://www.august.com.au/blog/animating-scenes-with-webgl-three-js/)

More extensive / advanced articles and courses

- Three Journey (https://threejs-journey.com/) Course by Bruno Simon (https://bruno-simon.com/) - Teaches beginners how to use Three.js step by step

- Discover three.js (https://discoverthreejs.com/)

- Collection of tutorials (http://blog.cjgammon.com/) by CJ Gammon (http://www.cjgammon.com/).

- Glossy spheres in three.js (https://medium.com/soffritti.pierfrancesco/glossy-spheres-in-three-js-bfd2785d4857).

- Interactive 3D Graphics (https://www.udacity.com/course/interactive-3d-graphics--cs291) - a free course on Udacity that teaches the fundamentals of 3D Graphics, and uses three.js as its coding tool.

- Aerotwist (https://aerotwist.com/tutorials/) tutorials by Paul Lewis (https://github.com/paullewis/).

- Three.js Bookshelf (https://discourse.threejs.org/t/three-js-bookshelf/2468) - Looking for more resources about three.js or computer graphics in general? Check out the selection of literature recommended by the community.

News and Updates

- Three.js on Twitter (https://twitter.com/hashtag/threejs)

- Three.js on reddit (http://www.reddit.com/r/threejs/)

- WebGL on reddit (http://www.reddit.com/r/webgl/)

Examples

- three-seed (https://github.com/edwinwebb/three-seed/) - three.js starter project with ES6 and Webpack

- Professor Stemkoskis Examples (http://stemkoski.github.io/Three.js/index.html) - a collection of beginner friendly examples built using three.js r60.

- Official three.js examples (https://threejs.org/examples/) - these examples are maintained as part of the three.js repository, and always use the latest version of three.js.

- Official three.js dev branch examples (https://raw.githack.com/mrdoob/three.js/dev/examples/) - Same as the above, except these use the dev branch of three.js, and are used to check that everything is working as three.js being is developed.

Tools

- physgl.org (https://github.com/tbensky/physgl) - JavaScript front-end with wrappers to three.js, to bring WebGL graphics to students learning physics and math.

- Whitestorm.js (https://whsjs.readme.io/) – Modular three.js framework with AmmoNext physics plugin.

- Three.js Inspector (http://zz85.github.io/zz85-bookmarklets/threelabs.html)

- ThreeNodes.js (http://idflood.github.io/ThreeNodes.js/).

- vscode shader (https://marketplace.visualstudio.com/items?itemName=slevesque.shader) - Syntax highlighter for shader language.

- vscode comment-tagged-templates (https://marketplace.visualstudio.com/items?itemName=bierner.comment-tagged-templates) - Syntax highlighting for tagged template strings using comments to shader language, like: glsl.js.

- WebXR-emulator-extension (https://github.com/MozillaReality/WebXR-emulator-extension)

WebGL References

- webgl-reference-card.pdf (https://www.khronos.org/files/webgl/webgl-reference-card-1_0.pdf) - Reference of all WebGL and GLSL keywords, terminology, syntax and definitions.

Old Links

These links are kept for historical purposes - you may still find them useful, but be warned that they may have information relating to very old versions of three.js.

- AlterQualia at WebGL Camp 3 (https://www.youtube.com/watch?v=Dir4KO9RdhM)

- Yomotsus Examples (http://yomotsu.github.io/threejs-examples/) - a collection of examples using three.js r45.

- Introduction to Three.js (http://fhtr.org/BasicsOfThreeJS/#1) by Ilmari Heikkinen (http://github.com/kig/) (slideshow).

- WebGL and Three.js (http://www.slideshare.net/yomotsu/webgl-and-threejs) by Akihiro Oyamada (http://github.com/yomotsu) (slideshow).

- Trigger Rally (https://www.youtube.com/watch?v=VdQnOaolrPA) by jareiko (https://github.com/jareiko) (video).

- ThreeFab (http://blackjk3.github.io/threefab/) - scene editor, maintained up until around three.js r50.

- Max to Three.js workflow tips and tricks (http://bkcore.com/blog/3d/webgl-three-js-workflow-tips.html) by BKcore (https://github.com/BKcore)

- A whirlwind look at Three.js (http://12devsofxmas.co.uk/2012/01/webgl-and-three-js/) by Paul King (http://github.com/nrocy)

- Animated selective glow in Three.js (http://bkcore.com/blog/3d/webgl-three-js-animated-selective-glow.html) by BKcore (https://github.com/BKcore)

- Building A Physics Simulation Environment (http://www.natural-science.or.jp/article/20120220155529.php) - three.js tutorial in Japanese


WebGL Compatibility Check

Summary: Explains how to check for WebGL 2 support in Three.js and display a fallback message to users when it is unavailable.

WebGL Compatibility Check

Even though this is becoming less and less of a problem, some devices or browsers may still not support WebGL 2. The following method allows you to check if it is supported and display a message to the user if it is not. Import the WebGL support detection module, and run the following before attempting to render anything.

import WebGL from 'three/addons/capabilities/WebGL.js';

if ( WebGL.isWebGL2Available() ) {

  // Initiate function or other initializations here
  animate();

} else {

  const warning = WebGL.getWebGL2ErrorMessage();
  document.getElementById( 'container' ).appendChild( warning );

}


Animation System

Summary: Extraction fallback content. [stop]

Animation System

##### Animation System

##### Overview

			Within the three.js animation system you can animate various properties of your models:
			the bones of a skinned and rigged model, morph targets, different material properties
			(colors, opacity, booleans), visibility and transforms. The animated properties can be faded in,
			faded out, crossfaded and warped. The weight and time scales of different simultaneous
			animations on the same object as well as on different objects can be changed
			independently. Various animations on the same and on different objects can be
			synchronized.

			To achieve all this in one homogeneous system, the three.js animation system
			[has completely changed in 2015](https://github.com/mrdoob/three.js/issues/6881)
			(beware of outdated information!), and it has now an architecture similar to
			Unity/Unreal Engine 4. This page gives a short overview of the main components of the
			system and how they work together.

###### Animation Clips

			If you have successfully imported an animated 3D object (it doesn't matter if it has
			bones or morph targets or both) — for example exporting it from Blender with the
			[glTF Blender exporter](https://github.com/KhronosGroup/glTF-Blender-IO) and
			loading it into a three.js scene using `GLTFLoader` — one of the response fields
			should be an array named "animations", containing the animation clips
			for this model (see a list of possible loaders below).

			Each `AnimationClip` usually holds the data for a certain activity of the object. If the
			mesh is a character, for example, there may be one AnimationClip for a walkcycle, a second
			for a jump, a third for sidestepping and so on.

###### Keyframe Tracks

			Inside of such an `AnimationClip` the data for each animated property are stored in a
			separate `KeyframeTrack`. Assuming a character object has a skeleton,
			one keyframe track could store the data for the position changes of the lower arm bone
			over time, a different track the data for the rotation changes of the same bone, a third
			the track position, rotation or scaling of another bone, and so on. It should be clear,
			that an AnimationClip can be composed of lots of such tracks.

			Assuming the model has morph targets (for example one morph
			target showing a friendly face and another showing an angry face), each track holds the
			information as to how the influence of a certain morph target changes during the performance
			of the clip.

###### Animation Mixer

			The stored data forms only the basis for the animations - actual playback is controlled by
			the `AnimationMixer`. You can imagine this not only as a player for animations, but
			as a simulation of a hardware like a real mixer console, which can control several animations
			simultaneously, blending and merging them.

###### Animation Actions

			The `AnimationMixer` itself has only very few (general) properties and methods, because it
			can be controlled by the animation actions. By configuring an
			`AnimationAction` you can determine when a certain `AnimationClip` shall be played, paused
			or stopped on one of the mixers, if and how often the clip has to be repeated, whether it
			shall be performed with a fade or a time scaling, and some additional things, such crossfading
			or synchronizing.

###### Animation Object Groups

			If you want a group of objects to receive a shared animation state, you can use an
			`AnimationObjectGroup`.

###### Supported Formats and Loaders

			Note that not all model formats include animation (OBJ notably does not), and that only some
			three.js loaders support `AnimationClip` sequences. Several that  *do*
			support this animation type:

- THREE.ObjectLoader

- THREE.BVHLoader

- THREE.ColladaLoader

- THREE.FBXLoader

- THREE.GLTFLoader

			Note that 3ds max and Maya currently can't export multiple animations (meaning animations which are not
			on the same timeline) directly to a single file.

##### Example

let mesh;

// Create an AnimationMixer, and get the list of AnimationClip instances
const mixer = new THREE.AnimationMixer( mesh );
const clips = mesh.animations;

// Update the mixer on each frame
function update () {
  mixer.update( deltaSeconds );
}

// Play a specific animation
const clip = THREE.AnimationClip.findByName( clips, 'dance' );
const action = mixer.clipAction( clip );
action.play();

// Play all animations
clips.forEach( function ( clip ) {
  mixer.clipAction( clip ).play();
} );


Color Management

Summary: An overview of color space concepts in three.js, covering color primaries, white points, transfer functions, and how input, working, and output color spaces are managed during rendering. Includes guidance on working with THREE.Color instances and common pitfalls.

What is a color space?

Every color space is a collection of several design decisions, chosen together to support a large range of colors while satisfying technical constraints related to precision and display technologies. When creating a 3D asset, or assembling 3D assets together into a scene, it is important to know what these properties are, and how the properties of one color space relate to other color spaces in the scene.

sRGB colors and white point (D65) displayed in the reference CIE 1931 chromaticity diagram. Colored region represents a 2D projection of the sRGB gamut, which is a 3D volume.

- Color primaries: Primary colors (e.g. red, green, blue) are not absolutes; they are selected from the visible spectrum based on constraints of limited precision and capabilities of available display devices. Colors are expressed as a ratio of the primary colors.

- White point: Most color spaces are engineered such that an equally weighted sum of primaries R = G = B will appear to be without color, or "achromatic". The appearance of achromatic values (like white or grey) depend on human perception, which in turn depends heavily on the context of the observer. A color space specifies its "white point" to balance these needs. The white point defined by the sRGB color space is D65.

- Transfer functions: After choosing the color gamut and a color model, we still need to define mappings ("transfer functions") of numerical values to/from the color space. Does r = 0.5 represent 50% less physical illumination than r = 1.0? Or 50% less bright, as perceived by an average human eye? These are different things, and that difference can be represented as a mathematical function. Transfer functions may be linear or nonlinear, depending on the objectives of the color space. sRGB defines nonlinear transfer functions. Those functions are sometimes approximated as gamma functions, but the term "gamma" is ambiguous and should be avoided in this context.

These three parameters — color primaries, white point, and transfer functions — define a color space, with each chosen for particular goals. Having defined the parameters, a few additional terms are helpful:

- Color model: Syntax for numerically identifying colors within chosen the color gamut — a coordinate system for colors. In three.js we're mainly concerned with the RGB color model, having three coordinates r, g, b ∈ [0,1] ("closed domain") or r, g, b ∈ [0,∞] ("open domain") each representing a fraction of a primary color. Other color models (HSL, Lab, LCH) are commonly used for artistic control.

- Color gamut: Once color primaries and a white point have been chosen, these represent a volume within the visible spectrum (a "gamut"). Colors not within this volume ("out of gamut") cannot be expressed by closed domain [0,1] RGB values. In the open domain [0,∞], the gamut is technically infinite.

Consider two very common color spaces: SRGBColorSpace ("sRGB") and LinearSRGBColorSpace ("Linear-sRGB"). Both use the same primaries and white point, and therefore have the same color gamut. Both use the RGB color model. They differ only in the transfer functions — Linear-sRGB is linear with respect to physical light intensity. sRGB uses the nonlinear sRGB transfer functions, and more closely resembles the way that the human eye perceives light and the responsiveness of common display devices.

That difference is important. Lighting calculations and other rendering operations must generally occur in a linear color space. However, a linear colors are less efficient to store in an image or framebuffer, and do not look correct when viewed by a human observer. As a result, input textures and the final rendered image will generally use the nonlinear sRGB color space.

NOTICE: While some modern displays support wider gamuts like Display-P3, the web platform's graphics APIs largely rely on sRGB. Applications using three.js today will typically use only the sRGB and Linear-sRGB color spaces.

Roles of color spaces

Linear workflows — required for modern rendering methods — generally involve more than one color space, each assigned to a particular role. Linear and nonlinear color spaces are appropriate for different roles, explained below.

Input color space

Colors supplied to three.js — from color pickers, textures, 3D models, and other sources — each have an associated color space. Those not already in the Linear-sRGB working color space must be converted, and textures be given the correct texture.colorSpace assignment. Certain conversions (for hexadecimal and CSS colors in sRGB) can be made automatically if the THREE.ColorManagement API is enabled before initializing colors:

THREE.ColorManagement is enabled by default.

- Materials, lights, and shaders: Colors in materials, lights, and shaders store RGB components in the Linear-sRGB working color space.

- Vertex colors: BufferAttribute store RGB components in the Linear-sRGB working color space.

- Color textures: PNG or JPEG Texture containing color information (like .map or .emissiveMap) use the closed domain sRGB color space, and must be annotated with texture.colorSpace = SRGBColorSpace. Formats like OpenEXR (sometimes used for .envMap or .lightMap) use the Linear-sRGB color space indicated with texture.colorSpace = LinearSRGBColorSpace, and may contain values in the open domain [0,∞].

- Non-color textures: Textures that do not store color information (like .normalMap or .roughnessMap) do not have an associated color space, and generally use the (default) texture annotation of texture.colorSpace = NoColorSpace. In rare cases, non-color data may be represented with other nonlinear encodings for technical reasons.

WARNING: Many formats for 3D models do not correctly or consistently define color space information. While three.js attempts to handle most cases, problems are common with older file formats. For best results, use glTF 2.0 (GLTFLoader) and test 3D models in online viewers early to confirm the asset itself is correct.

Working color space

Rendering, interpolation, and many other operations must be performed in an open domain linear working color space, in which RGB components are proportional to physical illumination. In three.js, the working color space is Linear-sRGB.

Output color space

Output to a display device, image, or video may involve conversion from the open domain Linear-sRGB working color space to another color space. The conversion is defined by (WebGLRenderer.outputColorSpace). When using post-processing, this requires OutputPass.

- Display: Colors written to a WebGL canvas for display should be in the sRGB color space.

- Image: Colors written to an image should use the color space appropriate for the format and usage. Fully-rendered images written to PNG or JPEG textures generally use the sRGB color space. Images containing emission, light maps, or other data not confined to the [0,1] range will generally use the open domain Linear-sRGB color space, and a compatible image format like OpenEXR.

WARNING: Render targets may use either sRGB or Linear-sRGB. sRGB makes better use of limited precision. In the closed domain, 8 bits often suffice for sRGB whereas ≥12 bits (half float) may be required for Linear-sRGB. If later pipeline stages require Linear-sRGB input, the additional conversions may have a small performance cost.

Custom materials based on ShaderMaterial and RawShaderMaterial have to implement their own output color space conversion. For instances of ShaderMaterial, adding the colorspace_fragment shader chunk to the fragment shader's main() function should be sufficient.

Working with THREE.Color instances

Methods reading or modifying Color instances assume data is already in the three.js working color space, Linear-sRGB. RGB and HSL components are direct representations of data stored by the Color instance, and are never converted implicitly. Color data may be explicitly converted with .convertLinearToSRGB() or .convertSRGBToLinear().

With ColorManagement.enabled = true set (recommended), certain conversions are made automatically. Because hexadecimal and CSS colors are generally sRGB, Color methods will automatically convert these inputs from sRGB to Linear-sRGB in setters, or convert from Linear-sRGB to sRGB when returning hexadecimal or CSS output from getters.

// RGB components (no change).
color.r = color.g = color.b = 0.5;
console.log( color.r ); // → 0.5

// Manual conversion.
color.r = 0.5;
color.convertSRGBToLinear();
console.log( color.r ); // → 0.214041140

// Hexadecimal conversion.
color.setHex( 0x808080 );
console.log( color.r ); // → 0.214041140
console.log( color.getHex() ); // → 0x808080

// CSS conversion.
color.setStyle( 'rgb( 0.5, 0.5, 0.5 )' );
console.log( color.r ); // → 0.214041140

// Override conversion with 'colorSpace' argument.
color.setHex( 0x808080, LinearSRGBColorSpace );
console.log( color.r ); // → 0.5
console.log( color.getHex( LinearSRGBColorSpace ) ); // → 0x808080
console.log( color.getHex( SRGBColorSpace ) ); // → 0xBCBCBC

Common mistakes

When an individual color or texture is misconfigured, it will appear darker or lighter than expected. When the renderer's output color space is misconfigured, the entire scene may appear darker (e.g. missing conversion to sRGB) or lighter (e.g. a double conversion to sRGB with post-processing). In each case the problem may not be uniform, and simply increasing/decreasing lighting does not solve it.

A more subtle issue appears when both the input color spaces and the output color spaces are incorrect — the overall brightness levels may be fine, but colors may change unexpectedly under different lighting, or shading may appear more blown-out and less soft than intended. These two wrongs do not make a right, and it's important that the working color space be linear ("scene referred") and the output color space be nonlinear ("display referred").

Further reading

- GPU Gems 3: The Importance of Being Linear, by Larry Gritz and Eugene d'Eon
- What every coder should know about gamma, by John Novak
- The Hitchhiker's Guide to Digital Color, by Troy Sobotka
- Color Management, Blender


How to create VR content

Summary: This guide provides a brief overview of the basic components of a web-based VR application made with three.js, covering VRButton setup, XR rendering enablement, and the animation loop.

Overview

This guide provides a brief overview of the basic components of a web-based VR application made with three.js.

Workflow

First, you have to include VRButton.js into your project.

VRButton.createButton() does two important things: It creates a button which indicates VR compatibility. Besides, it initiates a VR session if the user activates the button. The only thing you have to do is to add the following line of code to your app.

Next, you have to tell your instance of WebGLRenderer to enable XR rendering.

Finally, you have to adjust your animation loop since we can't use our well known window.requestAnimationFrame() function. For VR projects we use renderer.setAnimationLoop(). The minimal code looks like this:

import { VRButton } from 'three/addons/webxr/VRButton.js';

document.body.appendChild( VRButton.createButton( renderer ) );

renderer.setAnimationLoop( function () {

  renderer.render( scene, camera );

} );

Next Steps

Have a look at one of the official WebVR examples to see this workflow in action.

WebXR / XR / ballshooter
WebXR / XR / cubes
WebXR / XR / dragging
WebXR / XR / marching cubes
WebXR / XR / paint
WebXR / VR / panorama_depth
WebXR / VR / panorama
WebXR / VR / rollercoaster
WebXR / VR / sandbox
WebXR / VR / video


How to dispose of Objects

Summary: A guide covering how to properly dispose of three.js objects such as geometries, materials, textures, render targets, and skinned meshes to free WebGL-related resources and avoid memory leaks.

How to dispose of Objects

One important aspect in order to improve performance and avoid memory leaks in your application is the disposal of unused library entities. Whenever you create an instance of a *three.js* type, you allocate a certain amount of memory. However, *three.js* creates for specific objects like geometries or materials WebGL related entities like buffers or shader programs which are necessary for rendering. It's important to highlight that these objects are not released automatically. Instead, the application has to use a special API in order to free such resources. This guide provides a brief overview about how this API is used and what objects are relevant in this context.

Geometries

A geometry usually represents vertex information defined as a collection of attributes. *three.js* internally creates an object of type [WebGLBuffer](https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer) for each attribute. These entities are only deleted if you call `BufferGeometry.dispose()`. If a geometry becomes obsolete in your application, execute the method to free all related resources.

Materials

A material defines how objects are rendered. *three.js* uses the information of a material definition in order to construct a shader program for rendering. Shader programs can only be deleted if the respective material is disposed. For performance reasons, *three.js* tries to reuse existing shader programs if possible. So a shader program is only deleted if all related materials are disposed. You can indicate the disposal of a material by executing `Material.dispose()`.

Textures

The disposal of a material has no effect on textures. They are handled separately since a single texture can be used by multiple materials at the same time. Whenever you create an instance of `Texture`, three.js internally creates an instance of [WebGLTexture](https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture). Similar to buffers, this object can only be deleted by calling `Texture.dispose()`.

If you use an `ImageBitmap` as the texture's data source, you have to call [ImageBitmap.close](https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap/close)() at the application level to dispose of all CPU-side resources. An automated call of `ImageBitmap.close()` in `Texture.dispose()` is not possible, since the image bitmap becomes unusable, and the engine has no way of knowing if the image bitmap is used elsewhere.

Render Targets

Objects of type `WebGLRenderTarget` not only allocate an instance of [WebGLTexture](https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture) but also [WebGLFramebuffer](https://developer.mozilla.org/en-US/docs/Web/API/WebGLFramebuffer)s and [WebGLRenderbuffer](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderbuffer)s for realizing custom rendering destinations. These objects are only deallocated by executing `WebGLRenderTarget.dispose()`.

Skinned Mesh

Skinned meshes represent their bone hierarchy as skeletons. If you don't need a skinned mesh anymore, consider to call `Skeleton.dispose()` on the skeleton to free internal resources. Keep in mind that skeletons can be shared across multiple skinned meshes, so only call `dispose()` if the skeleton is not used by other active skinned meshes.

Miscellaneous

There are other classes from the examples directory like controls or post processing passes which provide `dispose()` methods in order to remove internal event listeners or render targets. In general, it's recommended to check the API or documentation of a class and watch for `dispose()`. If present, you should use it when cleaning things up.

Why can't *three.js* dispose objects automatically?

This question was asked many times by the community so it's important to clarify this matter. Fact is that *three.js* does not know the lifetime or scope of user-created entities like geometries or materials. This is the responsibility of the application. For example even if a material is currently not used for rendering, it might be necessary for the next frame. So if the application decides that a certain object can be deleted, it has to	notify the engine via calling the respective `dispose()` method.

Does removing a mesh from the scene also dispose its geometry and material?

No, you have to explicitly dispose the geometry and material via *dispose()*. Keep in mind that geometries and materials can be shared among 3D objects like meshes.

Does *three.js* provide information about the amount of cached objects?

Yes. It's possible to evaluate `renderer.info`, a special property of the renderer with a series of statistical information about the graphics board memory and the rendering process. Among other things, it tells you how many textures, geometries and shader programs are internally stored. If you notice performance problems in your application, it's a good idea to debug this property in order to easily identify a memory leak.

What happens when you call `dispose()` on a texture but the image is not loaded yet?

Internal resources for a texture are only allocated if the image has fully loaded. If you dispose a texture before the image was loaded, nothing happens. No resources were allocated so there is also no need for clean up.

What happens when I call `dispose()` and then use the respective object at a later point?

That depends. For geometries, materials, textures, render targets and post processing passes the deleted internal resources can be created again by the engine. So no runtime error will occur but you might notice a negative performance impact for the current frame, especially when shader programs have to be compiled.

Controls and renderers are an exception. Instances of these classes can not be used after `dispose()` has been called. You have to create new instances in this case.

How should I manage *three.js* objects in my app? When do I know how to dispose things?

In general, there is no definite recommendation for this. It highly depends on the specific use case when calling `dispose()` is appropriate. It's important to highlight that it's not always necessary to dispose objects all the time. A good example for this is a game which consists of multiple levels. A good place for object disposal is when switching the level. The app could traverse through the old scene and dispose all obsolete materials, geometries and textures. As mentioned in the previous section, it does not produce a runtime error if you dispose an object that is actually still in use. The worst thing that can happen is performance drop for a single frame.

Why `renderer.info.memory` is still reporting geometries and textures after traversing the scene and disposing all reachable textures and geometries?

In certain cases, there are some textures and geometries used internally by Three.js that are not reachable when traversing the scene graph in order to be disposed. It is expected that `renderer.info.memory` will still report them even after a full scene cleanup. However, they do not leak, but they are reused on consecutive scene cleanup/repopulating cycles.

These cases could be related to using `material.envMap`, `scene.background`, `scene.environment`, or other contexts that would require the engine to create textures or geometries for internal use.

Examples that demonstrate the usage of dispose()

[WebGL / test / memory](../../examples/#webgl_test_memory)

[WebGL / test / memory2](../../examples/#webgl_test_memory2)


How to update Things

Summary: A guide explaining how to update various Three.js objects including matrix transforms, BufferGeometries, Materials, Textures, Cameras, InstancedMesh, and SkinnedMesh.

How to update Things

All objects by default automatically update their matrices if they have been added to the scene with

```
const object = new THREE.Object3D();
scene.add( object );
```

or if they are the child of another object that has been added to the scene:

```
const object1 = new THREE.Object3D();
const object2 = new THREE.Object3D();

object1.add( object2 );
scene.add( object1 ); //object1 and object2 will automatically update their matrices
```

However, if you know the object will be static, you can disable this and update the transform matrix manually just when needed.

```
object.matrixAutoUpdate = false;
object.updateMatrix();
```

BufferGeometry

BufferGeometries store information (such as vertex positions, face indices, normals, colors, UVs, and any custom attributes) in attribute buffers - that is, typed arrays. This makes them generally faster than standard Geometries, at the cost of being somewhat harder to work with.

With regards to updating BufferGeometries, the most important thing to understand is that you cannot resize buffers (this is very costly,	basically the equivalent to creating a new geometry). You can however update the content of buffers.

This means that if you know an attribute of your BufferGeometry will grow, say the number of vertices, you must pre-allocate a buffer large enough to hold any new vertices that may be created. Of course, this also means that there will be a maximum size for your BufferGeometry - there is no way to create a BufferGeometry that can efficiently be extended indefinitely.

We'll use the example of a line that gets extended at render time. We'll allocate space in the buffer for 500 vertices but draw only two at first, using `BufferGeometry.drawRange`.

Next we'll randomly add points to the line using a pattern like:

If you want to change the number of points rendered after the first render, do this:

If you want to change the position data values after the first render, you need to set the needsUpdate flag like so:

If you change the position data values after the initial render, you may need to recompute bounding volumes so other features of the engine like view frustum culling or helpers properly work.

Here is a fiddle showing an animated line which you can adapt to your use case.

const MAX_POINTS = 500;

// geometry
const geometry = new THREE.BufferGeometry();

// attributes
const positions = new Float32Array( MAX_POINTS * 3 ); // 3 floats (x, y and z) per point
geometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );

// draw range
const drawCount = 2; // draw the first 2 points, only
geometry.setDrawRange( 0, drawCount );

// material
const material = new THREE.LineBasicMaterial( { color: 0xff0000 } );

// line
const line = new THREE.Line( geometry, material );
scene.add( line );

const positionAttribute = line.geometry.getAttribute( 'position' );

let x = 0, y = 0, z = 0;

for ( let i = 0; i < positionAttribute.count; i ++ ) {

    positionAttribute.setXYZ( i, x, y, z );

    x += ( Math.random() - 0.5 ) * 30;
    y += ( Math.random() - 0.5 ) * 30;
    z += ( Math.random() - 0.5 ) * 30;

}

line.geometry.setDrawRange( 0, newValue );

positionAttribute.needsUpdate = true; // required after the first render

Examples

[WebGL / custom / attributes](../../examples/#webgl_custom_attributes)

[WebGL / buffergeometry / custom / attributes / particles](../../examples/#webgl_buffergeometry_custom_attributes_particles)

Materials

All uniforms values can be changed freely (e.g. colors, textures, opacity, etc), values are sent to the shader every frame.

Also GLstate related parameters can change any time (depthTest, blending, polygonOffset, etc).

The following properties can't be easily changed at runtime (once the material is rendered at least once):

- numbers and types of uniforms
- presence or not of

- texture
- fog
- vertex colors
- morphing
- shadow map
- alpha test
- transparent

Changes in these require building of new shader program. You'll need to set

`material.needsUpdate = true`

Bear in mind this might be quite slow and induce jerkiness in framerate (especially on Windows, as shader compilation is slower in DirectX than OpenGL).

For smoother experience you can emulate changes in these features to some degree by having "dummy" values like zero intensity lights, white textures, or zero density fog.

You can freely change the material used for geometry chunks, however you cannot change how an object is divided into chunks (according to face materials).

If you need to have different configurations of materials during runtime:

If the number of materials / chunks is small, you could pre-divide the object beforehand (e.g. hair / face / body / upper clothes / trousers for a human, front / sides / top / glass / tire / interior for a car).

If the number is large (e.g. each face could be potentially different), consider a different solution, such as using attributes / textures to drive different per-face look.

Examples

[WebGL / materials / car](../../examples/#webgl_materials_car)

[WebGL / webgl_postprocessing / dof](../../examples/#webgl_postprocessing_dof)

Textures

Image, canvas, video and data textures need to have the following flag set if they are changed:

`
              texture.needsUpdate = true;
            `

Render targets update automatically.

Examples

[WebGL / materials / video](../../examples/#webgl_materials_video)

[WebGL / rtt](../../examples/#webgl_rtt)

Cameras

A camera's position and target is updated automatically. If you need to change

- fov
- aspect
- near
- far

then you'll need to recompute the projection matrix:

camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();

InstancedMesh

`InstancedMesh` is a class for conveniently access instanced rendering in `three.js`. Certain library features like view frustum culling or ray casting rely on up-to-date bounding volumes (bounding sphere and bounding box). Because of the way how `InstancedMesh` works, the class has its own `boundingBox` and `boundingSphere` properties that supersede the bounding volumes on geometry level.

Similar to geometries you have to recompute the bounding box and sphere whenever you change the underlying data. In context of `InstancedMesh`, that happens when you transform instances via `setMatrixAt()`. You can use the same pattern like with geometries.

SkinnedMesh

`SkinnedMesh` follows the same principles like `InstancedMesh` in context of bounding volumes. Meaning the class has its own version of `boundingBox` and `boundingSphere` to correctly enclose animated meshes. When calling `computeBoundingBox()` and `computeBoundingSphere()`, the class computes the respective bounding volumes based on the current bone transformation (or in other words the current animation state).


How to use Post Processing

Summary: A guide explaining how to use three.js's post-processing pipeline via EffectComposer to apply graphical effects such as Depth-Of-Field, Bloom, Film Grain, and Anti-aliasing to rendered scenes.

How to use Post Processing

Many three.js applications render their 3D objects directly to the screen. Sometimes, however, you want to apply one or more graphical effects like Depth-Of-Field, Bloom, Film Grain or various types of Anti-aliasing. Post-processing is a widely used approach to implement such effects. First, the scene is rendered to a render target which represents a buffer in the video card's memory. In the next step one or more post-processing passes apply filters and effects to the image buffer before it is eventually rendered to the screen.

three.js provides a complete post-processing solution via `EffectComposer` to implement such a workflow.

Workflow

The first step in the process is to import all necessary files from the examples directory. The guide assumes you are using the official npm package of three.js. For our basic demo in this guide we need the following files.

After all files are successfully imported, we can create our composer by passing in an instance of `WebGLRenderer`.

When using a composer, it's necessary to change the application's animation loop. Instead of calling the render method of `WebGLRenderer`, we now use the respective counterpart of `EffectComposer`.

Our composer is now ready so it's possible to configure the chain of post-processing passes. These passes are responsible for creating the final visual output of the application. They are processed in order of their addition/insertion. In our example, the instance of `RenderPass` is executed first, then the instance of `GlitchPass` and finally `OutputPass`. The last enabled pass in the chain is automatically rendered to the screen. The setup of the passes looks like so:

`RenderPass` is normally placed at the beginning of the chain in order to provide the rendered scene as an input for the next post-processing step. In our case, `GlitchPass` is going to use these image data to apply a wild glitch effect. `OutputPass` is usually the last pass in the chain which performs sRGB color space conversion and tone mapping. Check out this live example to see it in action.

import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
import { GlitchPass } from 'three/addons/postprocessing/GlitchPass.js';
import { OutputPass } from 'three/addons/postprocessing/OutputPass.js';

const composer = new EffectComposer( renderer );

function animate() {

  requestAnimationFrame( animate );

  composer.render();

}

const renderPass = new RenderPass( scene, camera );
composer.addPass( renderPass );

const glitchPass = new GlitchPass();
composer.addPass( glitchPass );

const outputPass = new OutputPass();
composer.addPass( outputPass );

Built-in Passes

You can use a wide range of pre-defined post-processing passes provided by the engine. They are located in the postprocessing directory.

Custom Passes

Sometimes you want to write a custom post-processing shader and include it into the chain of post-processing passes. For this scenario, you can utilize `ShaderPass`. After importing the file and your custom shader, you can use the following code to setup the pass.

The repository provides a file called CopyShader which is a good starting code for your own custom shader. `CopyShader` just copies the image contents of the `EffectComposer`'s read buffer to its write buffer without applying any effects.

import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js';
import { LuminosityShader } from 'three/addons/shaders/LuminosityShader.js';

// later in your init routine

const luminosityPass = new ShaderPass( LuminosityShader );
composer.addPass( luminosityPass );


Matrix Transformations

Summary: Explains how Three.js uses matrices to encode 3D transformations (translations, rotations, and scaling) for Object3D instances, including how to update an object's transformation manually or automatically.

Matrix Transformations

Three.js uses `matrices` to encode 3D transformations---translations (position), rotations, and scaling. Every instance of `Object3D` has a `matrix` which stores that object's position, rotation, and scale. This page describes how to update an object's transformation.

Convenience properties and `matrixAutoUpdate`

There are two ways to update an object's transformation:

- Modify the object's `position`, `quaternion`, and `scale` properties, and let three.js recompute the object's matrix from these properties:

By default, the `matrixAutoUpdate` property is set true, and the matrix will be automatically recalculated. If the object is static, or you wish to manually control when recalculation occurs, better performance can be obtained by setting the property false:

And after changing any properties, manually update the matrix:

- Modify the object's matrix directly. The `Matrix4` class has various methods for modifying the matrix:

Note that `matrixAutoUpdate` *must* be set to `false` in this case, and you should make sure *not* to call `updateMatrix`. Calling `updateMatrix` will clobber the manual changes made to the matrix, recalculating the matrix from `position`, `scale`, and so on.

object.position.copy( start_position );
object.quaternion.copy( quaternion );

object.matrix.makeRotationFromQuaternion( quaternion );
object.matrix.setPosition( start_position );
object.matrixAutoUpdate = false;

Object and world matrices

An object's matrix stores the object's transformation *relative* to the object's parent; to get the object's transformation in *world* coordinates, you must access the object's world matrix.

When either the parent or the child object's transformation changes, you can request that the child object's world matrix be updated by calling `object.updateMatrixWorld()`.

An object can be transformed via `applyMatrix4()`. Note: Under-the-hood, this method relies on `Matrix4.decompose()`, and not all matrices are decomposable in this way. For example, if an object has a non-uniformly scaled parent, then the object's world matrix may not be decomposable, and this method may not be appropriate.

Rotation and Quaternion

Three.js provides two ways of representing 3D rotations: Euler angles and Quaternions, as well as methods for converting between the two. Euler angles are subject to a problem called "gimbal lock," where certain configurations can lose a degree of freedom (preventing the object from being rotated about one axis). For this reason, object rotations are *always* stored in the object's quaternion.

Previous versions of the library included a `useQuaternion` property which, when set to false, would cause the object's matrix to be calculated from an Euler angle. This practice is deprecated---instead, you should use the `object.setRotationFromEuler()` method, which will update the quaternion.