|
@@ -9,127 +9,244 @@
|
|
|
</head>
|
|
|
<body>
|
|
|
<h1>[name]</h1>
|
|
|
- <p>All objects by default automatically update their matrices.</p>
|
|
|
-
|
|
|
- <p>However, if you know object will be static, you can disable this and update transform matrix manually just when needed.</p>
|
|
|
-
|
|
|
- <div class="highlight highlight-source-js"><pre><span class="pl-smi">object</span>.<span class="pl-smi">matrixAutoUpdate</span> <span class="pl-k">=</span> <span class="pl-c1">false</span>;
|
|
|
- <span class="pl-smi">object</span>.<span class="pl-en">updateMatrix</span>();</pre></div>
|
|
|
+ <div>
|
|
|
+ <p>All objects by default automatically update their matrices if the have been added to the scene with</p>
|
|
|
+ <code>
|
|
|
+var object = new THREE.Object3D;
|
|
|
+scene.add( object );
|
|
|
+ </code>
|
|
|
+ or if they are the child of another object that has been added to the scene:
|
|
|
+ <code>
|
|
|
+var object1 = new THREE.Object3D;
|
|
|
+var object2 = new THREE.Object3D;
|
|
|
+
|
|
|
+object1.add( object2 );
|
|
|
+scene.add( object1 ); //object1 and object2 will automatically update their matrices
|
|
|
+ </code>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <p>However, if you know object will be static, you can disable this and update the transform matrix manually just when needed.</p>
|
|
|
+
|
|
|
+ <code>
|
|
|
+object.matrixAutoUpdate = false;
|
|
|
+object.updateMatrix();
|
|
|
+ </code>
|
|
|
|
|
|
<h2>Geometries</h2>
|
|
|
+ <div>
|
|
|
+ <h3>[page:BufferGeometry]</h3>
|
|
|
+ <div>
|
|
|
+ <p>
|
|
|
+ BufferGeometries store information (such as vertex positions, face indices, normals, colors,
|
|
|
+ UVs, and any custom attributes) in [page:BufferAttribute buffers] - that is,
|
|
|
+ [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays typed arrays].
|
|
|
+ This makes them generally faster than standard Geometries, at the cost of being somewhat harder to
|
|
|
+ work with.
|
|
|
+ </p>
|
|
|
+ <p>
|
|
|
+ With regards to updating BufferGeometries, the most important thing to understand is that you
|
|
|
+ you cannot resize buffers (this is very costly, basically the equivalent to creating new a geometry).
|
|
|
+ You can however update the content of buffers.
|
|
|
+ </p>
|
|
|
+ <p>
|
|
|
+ This means that if you know an attribute of you 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.
|
|
|
+ </p>
|
|
|
+ <p>
|
|
|
+ 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 [page:BufferGeometry.drawRange].
|
|
|
+ </p>
|
|
|
+ <code>
|
|
|
+var MAX_POINTS = 500;
|
|
|
+
|
|
|
+// geometry
|
|
|
+var geometry = new THREE.BufferGeometry();
|
|
|
+
|
|
|
+// attributes
|
|
|
+var positions = new Float32Array( MAX_POINTS * 3 ); // 3 vertices per point
|
|
|
+geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
|
|
|
+
|
|
|
+// draw range
|
|
|
+drawCount = 2; // draw the first 2 points, only
|
|
|
+geometry.setDrawRange( 0, drawCount );
|
|
|
+
|
|
|
+// material
|
|
|
+var material = new THREE.LineBasicMaterial( { color: 0xff0000, linewidth: 2 } );
|
|
|
+
|
|
|
+// line
|
|
|
+line = new THREE.Line( geometry, material );
|
|
|
+scene.add( line );
|
|
|
+ </code>
|
|
|
+ <p>
|
|
|
+ Next we'll randomly add points to the line using a pattern like:
|
|
|
+ </p>
|
|
|
+ <code>
|
|
|
+var positions = line.geometry.attributes.position.array;
|
|
|
+
|
|
|
+var x = y = z = index = 0;
|
|
|
+
|
|
|
+for ( var i = 0, l = MAX_POINTS; i < l; i ++ ) {
|
|
|
+
|
|
|
+ positions[ index ++ ] = x;
|
|
|
+ positions[ index ++ ] = y;
|
|
|
+ positions[ index ++ ] = z;
|
|
|
+
|
|
|
+ x += ( Math.random() - 0.5 ) * 30;
|
|
|
+ y += ( Math.random() - 0.5 ) * 30;
|
|
|
+ z += ( Math.random() - 0.5 ) * 30;
|
|
|
+
|
|
|
+}
|
|
|
+ </code>
|
|
|
+ <p>
|
|
|
+ If you want to change the <em>number of points</em> rendered after the first render, do this:
|
|
|
+ </p>
|
|
|
+ <code>
|
|
|
+line.geometry.setDrawRange( 0, newValue );
|
|
|
+ </code>
|
|
|
+ <p>
|
|
|
+ If you want to change the position data values after the first render, you need to
|
|
|
+ set the needsUpdate flag like so:
|
|
|
+ </p>
|
|
|
+ <code>
|
|
|
+line.geometry.attributes.position.needsUpdate = true; // required after the first render
|
|
|
+ </code>
|
|
|
+
|
|
|
+ <p>
|
|
|
+ [link:http://jsfiddle.net/w67tzfhx/ Here is a fiddle] showing an animated line which you can adapt to your use case.
|
|
|
+ </p>
|
|
|
+
|
|
|
+ <h4>Examples:</h4>
|
|
|
+ [example:webgl_custom_attributes WebGL / custom / attributes]<br />
|
|
|
+ [example:webgl_buffergeometry_custom_attributes_particles WebGL / buffergeometry / custom / attributes / particles]
|
|
|
+
|
|
|
+
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <h3>[page:Geometry]</h3>
|
|
|
+ <div>
|
|
|
+ <p>
|
|
|
+ The following flag control updating of various geometry attributes. 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. Note that this applies only to [page:Geometry]
|
|
|
+ and not to [page:BufferGeometry].
|
|
|
+ </p>
|
|
|
+ <code>
|
|
|
+var geometry = new THREE.Geometry();
|
|
|
+geometry.verticesNeedUpdate = true;
|
|
|
+geometry.elementsNeedUpdate = true;
|
|
|
+geometry.morphTargetsNeedUpdate = true;
|
|
|
+geometry.uvsNeedUpdate = true;
|
|
|
+geometry.normalsNeedUpdate = true;
|
|
|
+geometry.colorsNeedUpdate = true;
|
|
|
+geometry.tangentsNeedUpdate = true;
|
|
|
+ </code>
|
|
|
+
|
|
|
+ <p>
|
|
|
+ In versions prior to [link:https://github.com/mrdoob/three.js/releases/tag/r66 r66] meshes
|
|
|
+ additionally need the <em>dynamic</em> flag enabled (to keep internal typed arrays):
|
|
|
+ </p>
|
|
|
+
|
|
|
+ <code>
|
|
|
+ //removed after r66
|
|
|
+ geometry.dynamic = true;
|
|
|
+ </code>
|
|
|
+
|
|
|
+ <h4>Example:</h4>
|
|
|
+ [example:webgl_geometry_dynamic WebGL / geometry / dynamic]<br />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
|
|
|
- <p>You can only update content of buffers, you cannot resize buffers (this is very costly, basically equivalent to creating new geometry). </p>
|
|
|
-
|
|
|
- <p>You can emulate resizing by pre-allocating larger buffer and then keeping unneeded vertices collapsed / hidden.</p>
|
|
|
-
|
|
|
- <p>Set flags only for attributes that you need to update, updates are costly. Once buffers change, these flags reset automatically back to <code>false</code>. You need to keep setting them to <code>true</code> if you wanna keep updating buffers.</p>
|
|
|
-
|
|
|
- <p>r49</p>
|
|
|
-
|
|
|
- <div class="highlight highlight-source-js"><pre><span class="pl-smi">geometry</span>.<span class="pl-smi">verticesNeedUpdate</span> <span class="pl-k">=</span> <span class="pl-c1">true</span>;
|
|
|
- <span class="pl-smi">geometry</span>.<span class="pl-smi">elementsNeedUpdate</span> <span class="pl-k">=</span> <span class="pl-c1">true</span>;
|
|
|
- <span class="pl-smi">geometry</span>.<span class="pl-smi">morphTargetsNeedUpdate</span> <span class="pl-k">=</span> <span class="pl-c1">true</span>;
|
|
|
- <span class="pl-smi">geometry</span>.<span class="pl-smi">uvsNeedUpdate</span> <span class="pl-k">=</span> <span class="pl-c1">true</span>;
|
|
|
- <span class="pl-smi">geometry</span>.<span class="pl-smi">normalsNeedUpdate</span> <span class="pl-k">=</span> <span class="pl-c1">true</span>;
|
|
|
- <span class="pl-smi">geometry</span>.<span class="pl-smi">colorsNeedUpdate</span> <span class="pl-k">=</span> <span class="pl-c1">true</span>;
|
|
|
- <span class="pl-smi">geometry</span>.<span class="pl-smi">tangentsNeedUpdate</span> <span class="pl-k">=</span> <span class="pl-c1">true</span>;</pre></div>
|
|
|
-
|
|
|
- <p>pre-r49</p>
|
|
|
-
|
|
|
- <div class="highlight highlight-source-js"><pre><span class="pl-smi">geometry</span>.<span class="pl-smi">__dirtyVertices</span> <span class="pl-k">=</span> <span class="pl-c1">true</span>;
|
|
|
- <span class="pl-smi">geometry</span>.<span class="pl-smi">__dirtyMorphTargets</span> <span class="pl-k">=</span> <span class="pl-c1">true</span>;
|
|
|
- <span class="pl-smi">geometry</span>.<span class="pl-smi">__dirtyElements</span> <span class="pl-k">=</span> <span class="pl-c1">true</span>;
|
|
|
- <span class="pl-smi">geometry</span>.<span class="pl-smi">__dirtyUvs</span> <span class="pl-k">=</span> <span class="pl-c1">true</span>;
|
|
|
- <span class="pl-smi">geometry</span>.<span class="pl-smi">__dirtyNormals</span> <span class="pl-k">=</span> <span class="pl-c1">true</span>;
|
|
|
- <span class="pl-smi">geometry</span>.<span class="pl-smi">__dirtyTangents</span> <span class="pl-k">=</span> <span class="pl-c1">true</span>;
|
|
|
- <span class="pl-smi">geometry</span>.<span class="pl-smi">__dirtyColors</span> <span class="pl-k">=</span> <span class="pl-c1">true</span>;</pre></div>
|
|
|
-
|
|
|
- <p>In versions prior to <a href="https://github.com/mrdoob/three.js/releases/tag/r66">r66</a> meshes additionally need the <code>dynamic</code> flag enabled (to keep internal typed arrays).</p>
|
|
|
-
|
|
|
- <div class="highlight highlight-source-js"><pre><span class="pl-smi">geometry</span>.<span class="pl-smi">dynamic</span> <span class="pl-k">=</span> <span class="pl-c1">true</span>;</pre></div>
|
|
|
-
|
|
|
- <p>Custom attributes (in <code>MeshShaderMaterial</code>):</p>
|
|
|
-
|
|
|
- <div class="highlight highlight-source-js"><pre>attributes[ <span class="pl-s"><span class="pl-pds">"</span>attributeName<span class="pl-pds">"</span></span> ].<span class="pl-smi">needsUpdate</span> <span class="pl-k">=</span> <span class="pl-c1">true</span>;</pre></div>
|
|
|
-
|
|
|
- <p>Other objects like <code>ParticleSystem</code>, <code>Ribbon</code>, <code>Line</code> just need "dirty" flags.</p>
|
|
|
-
|
|
|
- <p>Examples:</p>
|
|
|
-
|
|
|
- <p><a href="https://github.com/mrdoob/three.js/blob/master/examples/webgl_geometry_dynamic.html">https://github.com/mrdoob/three.js/blob/master/examples/webgl_geometry_dynamic.html</a></p>
|
|
|
|
|
|
- <p><a href="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.html</a></p>
|
|
|
|
|
|
- <p><a href="https://github.com/mrdoob/three.js/blob/master/examples/webgl_custom_attributes_particles.html">https://github.com/mrdoob/three.js/blob/master/examples/webgl_custom_attributes_particles.html</a></p>
|
|
|
|
|
|
<h2>Materials</h2>
|
|
|
+ <div>
|
|
|
+ <p>All uniforms values can be changed freely (e.g. colors, textures, opacity, etc), values are sent to the shader every frame.</p>
|
|
|
|
|
|
- <p>All uniforms values can be changed freely (e.g. colors, textures, opacity, etc), values are sent to shader every frame.</p>
|
|
|
+ <p>Also GLstate related parameters can change any time (depthTest, blending, polygonOffset, etc).</p>
|
|
|
|
|
|
- <p>Also GL state related parameters can change any time (depthTest, blending, polygonOffset, etc).</p>
|
|
|
+ <p>Flat / smooth shading is baked into normals. You need to reset normals buffer (see above).</p>
|
|
|
|
|
|
- <p>Flat / smooth shading is baked into normals. You need to reset normals buffer (see above).</p>
|
|
|
+ <p>The following properties can't be easily changed at runtime (once the material is rendered at least once):</p>
|
|
|
+ <ul>
|
|
|
+ <li>numbers and types of uniforms</li>
|
|
|
+ <li>numbers and types of lights</li>
|
|
|
+ <li>presence or not of
|
|
|
+ <ul>
|
|
|
+ <li>texture</li>
|
|
|
+ <li>fog</li>
|
|
|
+ <li>vertex colors</li>
|
|
|
+ <li>skinning</li>
|
|
|
+ <li>morphing</li>
|
|
|
+ <li>shadow map</li>
|
|
|
+ <li>alpha test</li>
|
|
|
+ </ul>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
|
|
|
- <p>Properties that can't be easily changed in runtime (once material is rendered at least once):</p>
|
|
|
+ <p>Changes in these require building of new shader program. You'll need to set</p>
|
|
|
+ <code>material.needsUpdate = true</code>
|
|
|
|
|
|
- <ul>
|
|
|
- <li>numbers and types of uniforms</li>
|
|
|
- <li>numbers and types of lights</li>
|
|
|
- <li>presence or not of
|
|
|
+ <p>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).</p>
|
|
|
|
|
|
- <ul>
|
|
|
- <li>texture</li>
|
|
|
- <li>fog</li>
|
|
|
- <li>vertex colors</li>
|
|
|
- <li>skinning</li>
|
|
|
- <li>morphing</li>
|
|
|
- <li>shadow map</li>
|
|
|
- <li>alpha test</li>
|
|
|
- </ul>
|
|
|
- </li>
|
|
|
- </ul>
|
|
|
+ <p>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.</p>
|
|
|
|
|
|
- <p>Changes in these require building of new shader program. You'll need to set <code>material.needsUpdate</code> flag to <code>true</code>. </p>
|
|
|
+ <p>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). </p>
|
|
|
|
|
|
- <p>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).</p>
|
|
|
+ <h3>If you need to have different configurations of materials during runtime:</h3>
|
|
|
+ <p>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). </p>
|
|
|
|
|
|
- <p>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.</p>
|
|
|
+ <p>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.</p>
|
|
|
|
|
|
- <p>You can change freely material used for geometry chunk, you cannot change how object is divided into chunks (according to face materials). </p>
|
|
|
+ <h3>Examples:</h3>
|
|
|
+ [example:webgl_materials_cars WebGL / materials / cars]<br />
|
|
|
+ [example:webgl_postprocessing_dof WebGL / webgl_postprocessing / dof]
|
|
|
+ </div>
|
|
|
|
|
|
- <p>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). </p>
|
|
|
-
|
|
|
- <p>If number is large (e.g. each face could be potentially different), consider different solution, using attributes / textures to drive different per-face look.</p>
|
|
|
-
|
|
|
- <p>Examples:</p>
|
|
|
-
|
|
|
- <p><a href="https://github.com/mrdoob/three.js/blob/master/examples/webgl_materials_cars.html">https://github.com/mrdoob/three.js/blob/master/examples/webgl_materials_cars.html</a></p>
|
|
|
-
|
|
|
- <p><a href="https://github.com/mrdoob/three.js/blob/master/examples/webgl_postprocessing_dof.html">https://github.com/mrdoob/three.js/blob/master/examples/webgl_postprocessing_dof.html</a></p>
|
|
|
|
|
|
<h2>Textures</h2>
|
|
|
-
|
|
|
- <p>Image, canvas, video and data textures need to have flag set:</p>
|
|
|
-
|
|
|
- <div class="highlight highlight-source-js"><pre><span class="pl-smi">texture</span>.<span class="pl-smi">needsUpdate</span> <span class="pl-k">=</span> <span class="pl-c1">true</span>;</pre></div>
|
|
|
-
|
|
|
- <p>Render targets update automatically.</p>
|
|
|
-
|
|
|
- <p>Examples:</p>
|
|
|
-
|
|
|
- <p><a href="https://github.com/mrdoob/three.js/blob/master/examples/webgl_materials_video.html">https://github.com/mrdoob/three.js/blob/master/examples/webgl_materials_video.html</a></p>
|
|
|
-
|
|
|
- <p><a href="https://github.com/mrdoob/three.js/blob/master/examples/webgl_rtt.html">https://github.com/mrdoob/three.js/blob/master/examples/webgl_rtt.html</a></p>
|
|
|
-
|
|
|
- <h2>
|
|
|
- <a id="user-content-cameras" class="anchor" href="#cameras" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Cameras</h2>
|
|
|
-
|
|
|
- <p>Camera position and target is updated automatically.</p>
|
|
|
-
|
|
|
- <p>If you need to change <code>fov</code>, <code>aspect</code>, <code>near</code>, <code>far</code> you need to recompute projection matrix:</p>
|
|
|
-
|
|
|
- <div class="highlight highlight-source-js"><pre><span class="pl-smi">camera</span>.<span class="pl-smi">aspect</span> <span class="pl-k">=</span> <span class="pl-c1">window</span>.<span class="pl-c1">innerWidth</span> <span class="pl-k">/</span> <span class="pl-c1">window</span>.<span class="pl-c1">innerHeight</span>;
|
|
|
- <span class="pl-smi">camera</span>.<span class="pl-en">updateProjectionMatrix</span>();</pre></div>
|
|
|
-
|
|
|
+ <div>
|
|
|
+ <p>Image, canvas, video and data textures need to have the following flag set if they are changed:</p>
|
|
|
+ <code>
|
|
|
+ texture.needsUpdate = true;
|
|
|
+ </code>
|
|
|
+ <p>Render targets update automatically.</p>
|
|
|
+
|
|
|
+ <h3>Examples:</h3>
|
|
|
+ [example:webgl_materials_video WebGL / materials / video]<br />
|
|
|
+ [example:webgl_rtt WebGL / rtt]
|
|
|
+
|
|
|
+ </div>
|
|
|
+
|
|
|
+
|
|
|
+ <h2>Cameras</h2>
|
|
|
+ <div>
|
|
|
+ <p>A camera's position and target is updated automatically. If you need to change</p>
|
|
|
+ <ul>
|
|
|
+ <li>
|
|
|
+ fov
|
|
|
+ </li>
|
|
|
+ <li>
|
|
|
+ aspect
|
|
|
+ </li>
|
|
|
+ <li>
|
|
|
+ near
|
|
|
+ </li>
|
|
|
+ <li>
|
|
|
+ far
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ <p>
|
|
|
+ then you'll need to recompute the projection matrix:
|
|
|
+ </p>
|
|
|
+ <code>
|
|
|
+camera.aspect = window.innerWidth / window.innerHeight;
|
|
|
+camera.updateProjectionMatrix();
|
|
|
+ </code>
|
|
|
+ </div>
|
|
|
</body>
|
|
|
</html>
|