custom-geometry.html 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. <!DOCTYPE html><html lang="ja"><head>
  2. <meta charset="utf-8">
  3. <title>のカスタムジオメトリ</title>
  4. <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
  5. <meta name="twitter:card" content="summary_large_image">
  6. <meta name="twitter:site" content="@threejs">
  7. <meta name="twitter:title" content="Three.js – のカスタムジオメトリ">
  8. <meta property="og:image" content="https://threejs.org/files/share.png">
  9. <link rel="shortcut icon" href="/files/favicon_white.ico" media="(prefers-color-scheme: dark)">
  10. <link rel="shortcut icon" href="/files/favicon.ico" media="(prefers-color-scheme: light)">
  11. <link rel="stylesheet" href="/manual/resources/lesson.css">
  12. <link rel="stylesheet" href="/manual/resources/lang.css">
  13. <!-- Import maps polyfill -->
  14. <!-- Remove this when import maps will be widely supported -->
  15. <script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js"></script>
  16. <script type="importmap">
  17. {
  18. "imports": {
  19. "three": "../../build/three.module.js"
  20. }
  21. }
  22. </script>
  23. </head>
  24. <body>
  25. <div class="container">
  26. <div class="lesson-title">
  27. <h1>のカスタムジオメトリ</h1>
  28. </div>
  29. <div class="lesson">
  30. <div class="lesson-main">
  31. <div class="warning">
  32. <strong>NOTE!</strong> This article is deprecated. Three.js r125
  33. removed support for <code class="notranslate" translate="no">Geometry</code>. Please refer to
  34. the article on <a href="custom-buffergeometry.html">custom BufferGeometry</a>.
  35. </div>
  36. <p>前回の<a href="primitives.html">記事</a>ではTHREE.jsにある基本ジオメトリであるプリミティブジオメトリを紹介しました。この記事ではカスタムジオメトリを紹介します。</p>
  37. <p>まず最初に断っておきますが、本格的な3Dコンテンツを作りたい場合は
  38. 3Dモデリングツールを使うべきです。3Dモデリングツールには
  39. <a href="https://blender.org">Blender</a>,
  40. <a href="https://www.autodesk.com/products/maya/overview">Maya</a>,
  41. <a href="https://www.autodesk.com/products/3ds-max/overview">3D Studio Max</a>,
  42. <a href="https://www.maxon.net/en-us/">Cinema4D</a>などがあります。</p>
  43. <p>これらのモデリングツールでモデルを作ってから<a href="load-gltf.html">gLTF</a>や<a href="load-obj.html">.obj</a>
  44. にエクスポートしたものをTHREE.jsにインポートすることもできます。
  45. どのモデリングツールも習得にそれなりの時間がかかります。</p>
  46. <p>ここまで簡単なカスタムジオメトリであれば大袈裟なモデリングツールを使わずにTHREE.jsのコードで作れます。</p>
  47. <p>まずは立方体を作ってみましょう。THREE.jsの<a href="/docs/#api/ja/geometries/BoxGeometry"><code class="notranslate" translate="no">BoxGeometry</code></a>や<a href="/docs/#api/ja/geometries/BoxGeometry"><code class="notranslate" translate="no">BoxGeometry</code></a>を使えば一発で
  48. 立方体を作れますが、簡単な例としてカスタムジオメトリで作ってみましょう。</p>
  49. <p>THREE.jsにはカスタムジオメトリを作る方法が2つあります。1つ目は<code class="notranslate" translate="no">Geometry</code>クラスで2つ目が<a href="/docs/#api/ja/core/BufferGeometry"><code class="notranslate" translate="no">BufferGeometry</code></a>です。
  50. それぞれに利点があります。<code class="notranslate" translate="no">Geometry</code>は簡単に使えますが遅く、メモリをより消費します。1000個以下の三角形を作る際は
  51. よいですが、10,000個の三角形を作る時には<a href="/docs/#api/ja/core/BufferGeometry"><code class="notranslate" translate="no">BufferGeometry</code></a>が良いでしょう。</p>
  52. <p><a href="/docs/#api/ja/core/BufferGeometry"><code class="notranslate" translate="no">BufferGeometry</code></a>は使うのが難しいですがメモリの消費が小さく速いです。1万個の三角形を作る時にはこれを使いましょう。</p>
  53. <p>ただし変形などがない場合はそれほど変わりません。<code class="notranslate" translate="no">Geometry</code>が遅いというのはジオメトリが編集された
  54. 場合に遅いと言う意味で、もし編集が必要なくそれほど大きくなければこの両者はあまり変わりません。
  55. この記事では両方紹介します。最初は簡単な<code class="notranslate" translate="no">Geometry</code>を紹介します。</p>
  56. <p>まずは<code class="notranslate" translate="no">Geometry</code>で立方体を作ってみましょう。<a href="responsive.html">レスポンシブの記事</a>の例を使います。</p>
  57. <p><a href="/docs/#api/ja/geometries/BoxGeometry"><code class="notranslate" translate="no">BoxGeometry</code></a>を使っている部分を消して<code class="notranslate" translate="no">Geometry</code>で置き換えてみます。</p>
  58. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">-const boxWidth = 1;
  59. -const boxHeight = 1;
  60. -const boxDepth = 1;
  61. -const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);
  62. +const geometry = new THREE.Geometry();
  63. </pre>
  64. <p>まずは8つの角を追加してみます。</p>
  65. <div class="threejs_center"><img src="../resources/cube-vertex-positions.svg" style="width: 500px"></div>
  66. <p>中心の周囲にこのようにvertexを追加します。(訳註:vertexとはジオメトリを構成する頂点です。3つの頂点を結ぶことでface=面ができます)。</p>
  67. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const geometry = new THREE.Geometry();
  68. +geometry.vertices.push(
  69. + new THREE.Vector3(-1, -1, 1), // 0
  70. + new THREE.Vector3( 1, -1, 1), // 1
  71. + new THREE.Vector3(-1, 1, 1), // 2
  72. + new THREE.Vector3( 1, 1, 1), // 3
  73. + new THREE.Vector3(-1, -1, -1), // 4
  74. + new THREE.Vector3( 1, -1, -1), // 5
  75. + new THREE.Vector3(-1, 1, -1), // 6
  76. + new THREE.Vector3( 1, 1, -1), // 7
  77. +);
  78. </pre>
  79. <p>vertexを結んで三角形を作ります。1面につき2つの三角形を使います。
  80. (訳註:立方体は6つの正方形で構成されます。1つの正方形は2つの三角形で構成されます。)</p>
  81. <div class="threejs_center"><img src="../resources/cube-triangles.svg" style="width: 500px"></div>
  82. <p>vertexを結んで三角形を作るには<a href="/docs/#api/ja/core/Face3"><code class="notranslate" translate="no">Face3</code></a>を使います。<a href="/docs/#api/ja/core/Face3"><code class="notranslate" translate="no">Face3</code></a>の3は3つのvertexでfaceを作ると言う意味です。</p>
  83. <p>vertexを指定する順序は重要です。faceには表面と裏面があります。立方体を構成するfaceの
  84. 面が外に向くためには反時計回りの順序でvertexを指定します。</p>
  85. <div class="threejs_center"><img src="../resources/cube-vertex-winding-order.svg" style="width: 500px"></div>
  86. <p>同じように12個の三角形を作って立方体を作ります。</p>
  87. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">geometry.faces.push(
  88. // front
  89. new THREE.Face3(0, 3, 2),
  90. new THREE.Face3(0, 1, 3),
  91. // right
  92. new THREE.Face3(1, 7, 3),
  93. new THREE.Face3(1, 5, 7),
  94. // back
  95. new THREE.Face3(5, 6, 7),
  96. new THREE.Face3(5, 4, 6),
  97. // left
  98. new THREE.Face3(4, 2, 6),
  99. new THREE.Face3(4, 0, 2),
  100. // top
  101. new THREE.Face3(2, 7, 6),
  102. new THREE.Face3(2, 3, 7),
  103. // bottom
  104. new THREE.Face3(4, 1, 0),
  105. new THREE.Face3(4, 5, 1),
  106. );
  107. </pre>
  108. <p>ちょっとコードを変えるだけで動きます。</p>
  109. <p>これらの立方体は前に使った<a href="/docs/#api/ja/geometries/BoxGeometry"><code class="notranslate" translate="no">BoxGeometry</code></a>の立方体より2倍のサイズがあります。
  110. 全体が映るようにカメラを引きます。</p>
  111. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const fov = 75;
  112. const aspect = 2; // the canvas default
  113. const near = 0.1;
  114. -const far = 5;
  115. +const far = 100;
  116. const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  117. -camera.position.z = 2;
  118. +camera.position.z = 5;
  119. </pre>
  120. <p>わかりやすいようにそれぞれを離して色を変えます。</p>
  121. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const cubes = [
  122. - makeInstance(geometry, 0x44aa88, 0),
  123. - makeInstance(geometry, 0x8844aa, -2),
  124. - makeInstance(geometry, 0xaa8844, 2),
  125. + makeInstance(geometry, 0x44FF44, 0),
  126. + makeInstance(geometry, 0x4444FF, -4),
  127. + makeInstance(geometry, 0xFF4444, 4),
  128. ];
  129. </pre>
  130. <p>この状態ではnormal(法線)がないのでライトが当たりません。
  131. そこでライトが必要ないマテリアルに変えます。</p>
  132. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">function makeInstance(geometry, color, x) {
  133. - const material = new THREE.MeshPhongMaterial({color});
  134. + const material = new THREE.MeshBasicMaterial({color});
  135. const cube = new THREE.Mesh(geometry, material);
  136. scene.add(cube);
  137. ...
  138. </pre>
  139. <p>これで自分で作った立方体ができました。</p>
  140. <p></p><div translate="no" class="threejs_example_container notranslate">
  141. <div><iframe class="threejs_example notranslate" translate="no" style=" " src="/manual/examples/resources/editor.html?url=/manual/examples/custom-geometry-cube.html"></iframe></div>
  142. <a class="threejs_center" href="/manual/examples/custom-geometry-cube.html" target="_blank">ここをクリックして別のウィンドウで開きます</a>
  143. </div>
  144. <p></p>
  145. <p>それぞれのfaceに対して<code class="notranslate" translate="no">color</code>を設定することで色を変えられます。</p>
  146. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">geometry.faces[ 0].color = geometry.faces[ 1].color = new THREE.Color('red');
  147. geometry.faces[ 2].color = geometry.faces[ 3].color = new THREE.Color('yellow');
  148. geometry.faces[ 4].color = geometry.faces[ 5].color = new THREE.Color('green');
  149. geometry.faces[ 6].color = geometry.faces[ 7].color = new THREE.Color('cyan');
  150. geometry.faces[ 8].color = geometry.faces[ 9].color = new THREE.Color('blue');
  151. geometry.faces[10].color = geometry.faces[11].color = new THREE.Color('magenta');
  152. </pre>
  153. <p>マテリアルには<code class="notranslate" translate="no">vertexColors</code>を使うように設定します。</p>
  154. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">-const material = new THREE.MeshBasicMaterial({color});
  155. +const material = new THREE.MeshBasicMaterial({vertexColors: true});
  156. </pre>
  157. <p></p><div translate="no" class="threejs_example_container notranslate">
  158. <div><iframe class="threejs_example notranslate" translate="no" style=" " src="/manual/examples/resources/editor.html?url=/manual/examples/custom-geometry-cube-face-colors.html"></iframe></div>
  159. <a class="threejs_center" href="/manual/examples/custom-geometry-cube-face-colors.html" target="_blank">ここをクリックして別のウィンドウで開きます</a>
  160. </div>
  161. <p></p>
  162. <p><code class="notranslate" translate="no">vertexcolors</code>を設定すればvertexそれぞれに色を設定できます。
  163. 3つのvertexに対して3つの色を設定してみます。</p>
  164. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">geometry.faces.forEach((face, ndx) =&gt; {
  165. face.vertexColors = [
  166. (new THREE.Color()).setHSL(ndx / 12 , 1, 0.5),
  167. (new THREE.Color()).setHSL(ndx / 12 + 0.1, 1, 0.5),
  168. (new THREE.Color()).setHSL(ndx / 12 + 0.2, 1, 0.5),
  169. ];
  170. });
  171. </pre>
  172. <p></p><div translate="no" class="threejs_example_container notranslate">
  173. <div><iframe class="threejs_example notranslate" translate="no" style=" " src="/manual/examples/resources/editor.html?url=/manual/examples/custom-geometry-cube-vertex-colors.html"></iframe></div>
  174. <a class="threejs_center" href="/manual/examples/custom-geometry-cube-vertex-colors.html" target="_blank">ここをクリックして別のウィンドウで開きます</a>
  175. </div>
  176. <p></p>
  177. <p>ライトを適用する時はnormalが必要です。normalはfaceの向きを示すベクトルです。
  178. 色を設定したのと同じようにそれぞれのfaceにのnormalを設定します。</p>
  179. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">face.normal = new THREE.Vector3(...)
  180. </pre>
  181. <p><code class="notranslate" translate="no">vertexNormals</code>でvertexに対してnormalを設定することもできます。</p>
  182. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">face.vertexNormals = [
  183. new THREE.Vector3(...),
  184. new THREE.Vector3(...),
  185. new THREE.Vector3(...),
  186. ]
  187. </pre>
  188. <p>しかしTHREE.jsに自動的にnormalを設定してもらうこともできます。
  189. faceのnormalに対しては<code class="notranslate" translate="no">Geometry.computeFaceNormals</code>を使います。</p>
  190. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">geometry.computeFaceNormals();
  191. </pre>
  192. <p>vertex colorを消してマテリアルを<a href="/docs/#api/ja/materials/MeshPhongMaterial"><code class="notranslate" translate="no">MeshPhongMaterial</code></a>に戻します。</p>
  193. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">-const material = new THREE.MeshBasicMaterial({vertexColors: true});
  194. +const material = new THREE.MeshPhongMaterial({color});
  195. </pre>
  196. <p>ライトが適用できました。</p>
  197. <p></p><div translate="no" class="threejs_example_container notranslate">
  198. <div><iframe class="threejs_example notranslate" translate="no" style=" " src="/manual/examples/resources/editor.html?url=/manual/examples/custom-geometry-cube-face-normals.html"></iframe></div>
  199. <a class="threejs_center" href="/manual/examples/custom-geometry-cube-face-normals.html" target="_blank">ここをクリックして別のウィンドウで開きます</a>
  200. </div>
  201. <p></p>
  202. <p>vertex normalsを使うことで滑らかな表面を表現できます。
  203. <code class="notranslate" translate="no">Geometry.computeVertexNormals</code>を設定してください。</p>
  204. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">-geometry.computeFaceNormals();
  205. +geometry.computeVertexNormals();
  206. </pre>
  207. <p>ここまで説明しておいてなんですが立方体はvertex normalの例としてはあまり適切ではありません。
  208. なぜなら1つのvertex normalがそのvertexが接する全ての面に依存しているからです。</p>
  209. <p></p><div translate="no" class="threejs_example_container notranslate">
  210. <div><iframe class="threejs_example notranslate" translate="no" style=" " src="/manual/examples/resources/editor.html?url=/manual/examples/custom-geometry-cube-vertex-normals.html"></iframe></div>
  211. <a class="threejs_center" href="/manual/examples/custom-geometry-cube-vertex-normals.html" target="_blank">ここをクリックして別のウィンドウで開きます</a>
  212. </div>
  213. <p></p>
  214. <p>テクスチャの座標(UVと呼ばれる)を設定するには<code class="notranslate" translate="no">faces</code>に対応した配列を用意します。
  215. <code class="notranslate" translate="no">Geometry.faceVertexUvs</code>で設定します。
  216. これらのテクニックを使うと以下のような立方体ができます。</p>
  217. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">geometry.faceVertexUvs[0].push(
  218. // front
  219. [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
  220. [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
  221. // right
  222. [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
  223. [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
  224. // back
  225. [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
  226. [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
  227. // left
  228. [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
  229. [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
  230. // top
  231. [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
  232. [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
  233. // bottom
  234. [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1) ],
  235. [ new THREE.Vector2(0, 0), new THREE.Vector2(1, 0), new THREE.Vector2(1, 1) ],
  236. );
  237. </pre>
  238. <p><code class="notranslate" translate="no">faceVertexUvs</code>は配列の配列によってUV座標がレイヤー状に格納されています。それぞれの配列にはUV座標が入っています。デフォルトではレイヤー数は1です。もう1つレイヤーを追加してみます。</p>
  239. <p>マテリアルに<a href="textures.html">テクスチャを追加</a> してください。</p>
  240. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">-geometry.computeVertexNormals();
  241. +geometry.computeFaceNormals();
  242. +const loader = new THREE.TextureLoader();
  243. +const texture = loader.load('resources/images/star.png');
  244. function makeInstance(geometry, color, x) {
  245. - const material = new THREE.MeshPhongMaterial({color});
  246. + const material = new THREE.MeshPhongMaterial({color, map: texture});
  247. const cube = new THREE.Mesh(geometry, material);
  248. scene.add(cube);
  249. ...
  250. </pre>
  251. <p></p><div translate="no" class="threejs_example_container notranslate">
  252. <div><iframe class="threejs_example notranslate" translate="no" style=" " src="/manual/examples/resources/editor.html?url=/manual/examples/custom-geometry-cube-texcoords.html"></iframe></div>
  253. <a class="threejs_center" href="/manual/examples/custom-geometry-cube-texcoords.html" target="_blank">ここをクリックして別のウィンドウで開きます</a>
  254. </div>
  255. <p></p>
  256. <p>OKです。単純なハイトマップをterrain meshから作りましょう。</p>
  257. <p>terrain meshからつくるハイトマップとは詰まるところ二次元配列です。配列の数値は高さの表現に使います。二次元配列を取得するには画像編集ソフトで適当な画像を作ってしまうのが楽です。96x96の画像を作ってみました。</p>
  258. <div class="threejs_center"><img src="../examples/resources/images/heightmap-96x64.png" style="width: 512px; image-rendering: pixelated;"></div>
  259. <p>このPNG画像をロードして二次元配列にしてハイトマップとして使います。
  260. 画像をロードするには<a href="/docs/#api/ja/loaders/ImageLoader"><code class="notranslate" translate="no">ImageLoader</code></a>を使います。</p>
  261. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const imgLoader = new THREE.ImageLoader();
  262. imgLoader.load('resources/images/heightmap-96x64.png', createHeightmap);
  263. function createHeightmap(image) {
  264. // extract the data from the image by drawing it to a canvas
  265. // and calling getImageData
  266. const ctx = document.createElement('canvas').getContext('2d');
  267. const {width, height} = image;
  268. ctx.canvas.width = width;
  269. ctx.canvas.height = height;
  270. ctx.drawImage(image, 0, 0);
  271. const {data} = ctx.getImageData(0, 0, width, height);
  272. const geometry = new THREE.Geometry();
  273. </pre>
  274. <p>画像から二次元配列を取り出しました。次に粗い正方形で区切られたグリッドを作ります。このグリッドはそれぞれのピクセルの中心点を四隅とした正方形で構成されています。</p>
  275. <div class="threejs_center"><img src="../resources/heightmap-points.svg" style="width: 500px"></div>
  276. <p>それぞれの正方形に対して5つのvertexを作ります。4つは正方形の四隅のピクセル値で、のこり1つはその四隅の平均です。</p>
  277. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const cellsAcross = width - 1;
  278. const cellsDeep = height - 1;
  279. for (let z = 0; z &lt; cellsDeep; ++z) {
  280. for (let x = 0; x &lt; cellsAcross; ++x) {
  281. // compute row offsets into the height data
  282. // we multiply by 4 because the data is R,G,B,A but we
  283. // only care about R
  284. const base0 = (z * width + x) * 4;
  285. const base1 = base0 + (width * 4);
  286. // look up the height for the for points
  287. // around this cell
  288. const h00 = data[base0] / 32;
  289. const h01 = data[base0 + 4] / 32;
  290. const h10 = data[base1] / 32;
  291. const h11 = data[base1 + 4] / 32;
  292. // compute the average height
  293. const hm = (h00 + h01 + h10 + h11) / 4;
  294. // the corner positions
  295. const x0 = x;
  296. const x1 = x + 1;
  297. const z0 = z;
  298. const z1 = z + 1;
  299. // remember the first index of these 5 vertices
  300. const ndx = geometry.vertices.length;
  301. // add the 4 corners for this cell and the midpoint
  302. geometry.vertices.push(
  303. new THREE.Vector3(x0, h00, z0),
  304. new THREE.Vector3(x1, h01, z0),
  305. new THREE.Vector3(x0, h10, z1),
  306. new THREE.Vector3(x1, h11, z1),
  307. new THREE.Vector3((x0 + x1) / 2, hm, (z0 + z1) / 2),
  308. );
  309. </pre>
  310. <p>この5つのvertexを元に4つの三角形を作ります。</p>
  311. <div class="threejs_center"><img src="../resources/heightmap-triangles.svg" style="width: 500px"></div>
  312. <pre class="prettyprint showlinemods notranslate lang-js" translate="no"> // create 4 triangles
  313. geometry.faces.push(
  314. new THREE.Face3(ndx + 0, ndx + 4, ndx + 1),
  315. new THREE.Face3(ndx + 1, ndx + 4, ndx + 3),
  316. new THREE.Face3(ndx + 3, ndx + 4, ndx + 2),
  317. new THREE.Face3(ndx + 2, ndx + 4, ndx + 0),
  318. );
  319. // add the texture coordinates for each vertex of each face
  320. const u0 = x / cellsAcross;
  321. const v0 = z / cellsDeep;
  322. const u1 = (x + 1) / cellsAcross;
  323. const v1 = (z + 1) / cellsDeep;
  324. const um = (u0 + u1) / 2;
  325. const vm = (v0 + v1) / 2;
  326. geometry.faceVertexUvs[0].push(
  327. [ new THREE.Vector2(u0, v0), new THREE.Vector2(um, vm), new THREE.Vector2(u1, v0) ],
  328. [ new THREE.Vector2(u1, v0), new THREE.Vector2(um, vm), new THREE.Vector2(u1, v1) ],
  329. [ new THREE.Vector2(u1, v1), new THREE.Vector2(um, vm), new THREE.Vector2(u0, v1) ],
  330. [ new THREE.Vector2(u0, v1), new THREE.Vector2(um, vm), new THREE.Vector2(u0, v0) ],
  331. );
  332. }
  333. }
  334. </pre>
  335. <p>仕上げです。</p>
  336. <pre class="prettyprint showlinemods notranslate lang-js" translate="no"> geometry.computeFaceNormals();
  337. // center the geometry
  338. geometry.translate(width / -2, 0, height / -2);
  339. const loader = new THREE.TextureLoader();
  340. const texture = loader.load('resources/images/star.png');
  341. const material = new THREE.MeshPhongMaterial({color: 'green', map: texture});
  342. const cube = new THREE.Mesh(geometry, material);
  343. scene.add(cube);
  344. }
  345. </pre>
  346. <p>すこし視点を変えるとみやすくなります。</p>
  347. <ul>
  348. <li><a href="/docs/#examples/controls/OrbitControls"><code class="notranslate" translate="no">OrbitControls</code></a>を追加してください。</li>
  349. </ul>
  350. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">import * as THREE from '/build/three.module.js';
  351. +import {OrbitControls} from '/examples/jsm/controls/OrbitControls.js';
  352. </pre>
  353. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">const fov = 75;
  354. const aspect = 2; // the canvas default
  355. const near = 0.1;
  356. -const far = 100;
  357. +const far = 200;
  358. const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  359. -camera.position.z = 5;
  360. +camera.position.set(20, 20, 20);
  361. +const controls = new OrbitControls(camera, canvas);
  362. +controls.target.set(0, 0, 0);
  363. +controls.update();
  364. </pre>
  365. <p>ライトも2つ入れましょう。</p>
  366. <pre class="prettyprint showlinemods notranslate lang-js" translate="no">-{
  367. +function addLight(...pos) {
  368. const color = 0xFFFFFF;
  369. const intensity = 1;
  370. const light = new THREE.DirectionalLight(color, intensity);
  371. - light.position.set(-1, 2, 4\);
  372. + light.position.set(...pos);
  373. scene.add(light);
  374. }
  375. +addLight(-1, 2, 4);
  376. +addLight(1, 2, -2);
  377. </pre>
  378. <p>立方体を回転を止めました。</p>
  379. <p></p><div translate="no" class="threejs_example_container notranslate">
  380. <div><iframe class="threejs_example notranslate" translate="no" style=" " src="/manual/examples/resources/editor.html?url=/manual/examples/custom-geometry-heightmap.html"></iframe></div>
  381. <a class="threejs_center" href="/manual/examples/custom-geometry-heightmap.html" target="_blank">ここをクリックして別のウィンドウで開きます</a>
  382. </div>
  383. <p></p>
  384. <p><code class="notranslate" translate="no">Geometry</code>の使用方法をおわかりいただけたでしょうか?</p>
  385. <p><a href="custom-buffergeometry.html">この記事</a>では<a href="/docs/#api/ja/core/BufferGeometry"><code class="notranslate" translate="no">BufferGeometry</code></a>について説明します。</p>
  386. </div>
  387. </div>
  388. </div>
  389. <script src="/manual/resources/prettify.js"></script>
  390. <script src="/manual/resources/lesson.js"></script>
  391. </body></html>