Skip to content
alteredq edited this page Mar 17, 2012 · 3 revisions

How to update things

Transforms

All objects by default automatically update their matrices.

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

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

Geometries

You can only update content of buffers, you cannot resize buffers (this is very costly, basically equivalent to creating new geometry).

You can emulate resizing by pre-allocating larger buffer and then keeping unneeded vertices collapsed / hidden.

Set flags only for attributes that you need to update, updates are costly. Once buffers change, these flags reset automatically back to false. You need to keep setting them to true if you wanna keep updating buffers.

geometry.__dirtyVertices = true;
geometry.__dirtyMorphTargets = true;
geometry.__dirtyElements = true;
geometry.__dirtyUvs = true;
geometry.__dirtyNormals = true;
geometry.__dirtyTangents = true;
geometry.__dirtyColors = true;

Meshes additionally need also dynamic flag enabled (to keep internal typed arrays).

geometry.dynamic = true;

Custom attributes (in MeshShaderMaterial):

attributes[ "attributeName" ].needsUpdate = true;

Other objects like ParticleSystem, Ribbon, Line just need "dirty" flags.

Examples:

https://github.com/mrdoob/three.js/blob/master/examples/webgl_geometry_dynamic.html

https://github.com/mrdoob/three.js/blob/master/examples/webgl_custom_attributes.html

https://github.com/mrdoob/three.js/blob/master/examples/webgl_custom_attributes_particles.html

https://github.com/mrdoob/three.js/blob/master/examples/webgl_ribbons.html

Materials

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

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

Flat / smooth shading is baked into normals. You need to reset normals buffer (see above).

Properties that can't be easily changed in runtime (once material is rendered at least once):

  • numbers and types of uniforms
  • numbers and types of lights
  • presence or not of
    • texture
    • fog
    • vertex colors
    • skinning
    • morphing
    • shadow map
    • alpha test

Changes in these require building of new shader program. You'll need to set material.needsUpdate flag to 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 change freely material used for geometry chunk, you cannot change how object is divided into chunks (according to face materials).

If you need to have different configurations of materials during runtime, if number of materials / chunks is small, you could pre-divide object beforehand (e.g. hair / face / body / upper clothes / trousers for human, front / sides / top / glass / tire / interior for car).

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

Examples:

https://github.com/mrdoob/three.js/blob/master/examples/webgl_ribbons.html

https://github.com/mrdoob/three.js/blob/master/examples/webgl_materials_cars.html

https://github.com/mrdoob/three.js/blob/master/examples/webgl_postprocessing_dof.html

Textures

Image, canvas, video and data textures need to have flag set:

texture.needsUpdate = true;

Render targets update automatically.

Examples:

https://github.com/mrdoob/three.js/blob/master/examples/webgl_materials_video.html

https://github.com/mrdoob/three.js/blob/master/examples/webgl_rtt.html

Cameras

Camera position and target is updated automatically.

If you need to change fov, aspect, near, far you need to recompute projection matrix:

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