ホームページ > 記事 > ウェブフロントエンド > 3D レンダリングはthree.js を使用して作成されますか?
three.js を使用すると、Web ページ上にさまざまな 3D 効果を簡単に作成できます。 2D でコンテンツを描画する場合は、キャンバスを使用することをお勧めします。しかし、多くの友人は、私たちが描いてインポートしたグラフィックスにシャドウ効果を追加する方法を知りません。また、すでに作成した 3dmax リソースをインポートする方法さえ知りません。そこで、このチュートリアルでは、3dmax で作成したリソースをインポートする方法と、自分で描いたすべてのグラフィックを含むインポートしたリソースに影を追加する方法を簡単に紹介します。この8部構成のエッセイのような暗号がまったく覚えられないという友人もたくさんいます。実際、コードを書く必要があるときは、コードを暗記する代わりに、公式のケースを参照するだけで済みます。たくさんメイクすれば自然と覚えられます。コンパイルの量が減れば、めったに使用しないコードを覚えるのに多くの時間を費やす必要がなくなります。
まず、3dmax リソースをインポートする方法を紹介します。ここで、私自身のテストの結果、作成した Web ページをローカル ファイルから直接開くと、Google や IE などのブラウザはロードしたリソースを表示できないことに注意してください。その理由は、ファイルを開いた後にファイル プロトコルが使用されるためです。ファイルはローカルにあるため、サーバーを参照すると、セキュリティの問題により、ローカル リソースを読み込むことができなくなります。 Firefox ブラウザは通常どおり開くことができます。したがって、デバッグする場合は Firefox を使用するか、Tomcat や Apache などを使用して最初にローカル サーバーをセットアップし、ドメイン名を介して作成した Web ページにアクセスすることをお勧めします。ブラウザのセキュリティ設定を変更することはお勧めできません。
まず 3dmax を使用してグラフィックを作成し、ここでは独自のティーポットを選択します。インターネット上には 3dmax を使用してティーポットを作成するチュートリアルが多すぎるため、ここでは詳しく説明しません。作り方がわからない人は、チュートリアルを検索するだけで、数ステップで作成できます。 もちろん、作成後はエクスポートすることを忘れないでください。これを mtl ファイルと obj ファイルにエクスポートする必要があります。このステップは、ティーポットを作成するためのほとんどのチュートリアルでも利用でき、マウスを数回クリックするだけで実行できます。教材などについては、ここではあまり考えません。結局のところ、学習は簡単なことから始めるべきです。
上記のように 2 つのファイルをエクスポートした後、公式コードを参照して独自のマテリアルをインポートできます。
まず、three.js ファイルに加えて、three ソース ファイルも導入する必要があります。 1 つは OBJLoader.js、1 つは MTLLoader.js、もう 1 つは DDSLoader.js です。これらは、ローカル リソースをロードするために公式に提供されているライブラリ ファイルであり、公式 Web サイトからダウンロードできます。 このウェブサイトは公式のケースです。必要なファイルもここからダウンロードできます。
以下のコードは、公式と同様に素材をインポートするコードに加えて、影効果も追加しました。
1 var onError = function ( xhr ) { }; 2 THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() ); 3 var mtlLoader = new THREE.MTLLoader(); 4 mtlLoader.setPath( './' ); //设置我们需要加载的mtl文件路径 5 mtlLoader.load( 'lyn.mtl', function( material ) { //这里加载我们需要的文件名 6 material.preload(); 7 var objLoader = new THREE.OBJLoader(); 8 objLoader.setMaterials( material ); //材质,也可自定义 9 objLoader.setPath( './' ); //设置要加载的obj文件的路径 10 objLoader.load( 'lyn.obj', function ( object ) { //加载obj文件 11 object.position.z = 1; //这里设置我们的素材相对于原来的大小以及旋转缩放等 12 object.position.y = -0.5; 13 object.scale.x = 0.2; 14 object.scale.y = 0.2; 15 object.scale.z = 0.2; 16 object1 = object; //这里是对素材设置阴影的操作 17 for(var k in object.children){ //由于我们的素材并不是看上去的一个整体,所以需要进行迭代 18 //对其中的所有孩子都设置接收阴影以及投射阴影 19 //才能看到阴影效果 20 object.children[k].castShadow = true; //设置该对象可以产生阴影 21 object.children[k].receiveShadow = true; //设置该对象可以接收阴影 22 } 23 scene.add( object1 ); 24 25 }, onProgress, onError ); 26 });的 上記のコードは、影の設定とサイズ調整を除いて、必要に応じてコピー&ペーストして、この開発に携わる場合は、ソースコードの実現を確認することをお勧めします。インポートしても素材が表示されない場合があります。以下の点を考慮する必要があります。最初の側面は、3dmax マテリアルを大きすぎるか小さすぎるかどうかです。大きすぎると、マテリアルの一部しか見えなくなり、見えないような錯覚が生じます。小さすぎると鮮明に見えなかったり、表示できなかったりします。この種の問題では、カメラの視聴距離に応じて調整する必要があります。もう1つの問題は、マテリアルにマテリアルを設定しておらず、コードに光源を追加していないため、暗いパッチのみが表示されていることです。したがって、このマテリアルを表示したい場合は、照明も追加する必要があります。
以下はスポットライト光源を追加するためのコードです。スポットライト光源は焦点を合わせることができるため、デモンストレーションがより便利になります。友達は自分で他の光源を試すこともできます。必要なのは点光源や指向性光源などの光源であることを思い出してください。環境光は影を生成できません。ただし、周囲をより鮮明に表示したい場合は、点光源と周囲光を同時に追加することもできますが、過度の周囲光が影の通常の表示に影響を与えるのを避けるために、周囲光の強度を弱くする必要があります。
function SpotLight(){ light = new THREE.SpotLight( '#ffffff' ,1); light.castShadow = true; light.distance = 50; light.angle = 0.6; light.decay = 2; light.penumbra = 0.2; light.position.set( 3, 2, 1 ); light.shadow.camera.near = 1; light.shadow.camera.far = 3; light.shadow.camera.visible = true; light.shadow.mapSize.width = 1024; light.shadow.mapSize.height = 1024; light.target = sp; scene.add(light); }
影が見えるように、床に影を落とす床も必要です。前に、receiveShadow 属性について説明しました。マテリアルを追加したシェイプ SP を作成するとします。シャドウを受信できるようにするには、sp.receiveShadow=true を使用する必要があります。 false に設定するとどうなりますか?
は影を生成しません。では、これを true に設定するとどうなるでしょうか?可以看到,已经生成了阴影。所以,如果我们要让一个物体可以产生阴影,需要设置castShadow这个属性为true,而生成了阴影,总需要投射到某个物体上,才能被观察到。所以,接收投影需要将receiveShadow这个属性设置为true。
完整的效果如下
以下是完整代码。其中库文件以及3dmax的素材文件这里不提供,需要自己生成或者自己下载。也可以只学习阴影的生成方法。代码编写略仓促,不过除了各种事件的控制等,其他方面应该还是比较清晰的。欢迎批评之争。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <style> 5 html, 6 body { 7 width: 100%; 8 height: 100%; 9 } 10 11 body { 12 margin: 0; 13 } 14 15 canvas { 16 width: 100%; 17 height: 100% 18 } 19 </style> 20 </head> 21 <body> 22 23 <script src="js/three.min.js?1.1.11"></script> 24 <script src="js/jquery-1.12.4.js?1.1.11"></script> 25 <script src="js/OBJLoader.js?1.1.11"></script> 26 <script src="js/MTLLoader.js?1.1.11"></script> 27 <script src="js/DDSLoader.js?1.1.11"></script> 28 <script> 29 var scene = new THREE.Scene(); 30 var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 2000); 31 camera.position.z = 6; 32 camera.position.y = 1; 33 camera.position.x = 2; 34 camera.lookAt(new THREE.Vector3(0, 0, 0)); 35 36 var other = new THREE.Object3D(); 37 other.add(camera); 38 scene.add(other); 39 40 var renderer = new THREE.WebGLRenderer(); 41 renderer.setSize(window.innerWidth, window.innerHeight); 42 document.body.appendChild(renderer.domElement); 43 44 var geometry = new THREE.BoxGeometry(1,1,1); 45 var material = new THREE.MeshPhongMaterial({ 46 color : '#2194ce', 47 specular : '#111111', 48 specular : 10 49 }); 50 var sp = new THREE.Mesh(geometry,material); 51 sp.position.z = -0.5; 52 53 var geometry = new THREE.ConeGeometry( 0.5, 1, 6 ); 54 var material2 = new THREE.MeshPhongMaterial({ 55 color : '#2194ce', 56 specular : '#ffffff', 57 shininess : 100 58 }); 59 var sp2 = new THREE.Mesh(geometry,material2); 60 sp2.position.x = -2.5; 61 sp2.position.z = -1; 62 63 var ball = new THREE.SphereGeometry( 0.5, 32, 32 ); 64 var material3 = new THREE.MeshPhongMaterial({ 65 color : '#2194ce', 66 specular : '#111111', 67 shininess : 100 68 }); 69 var myBall = new THREE.Mesh(ball,material3); 70 myBall.position.z = 1; 71 myBall.position.x = -1; 72 myBall.position.y = -1; 73 myBall.castShadow = true; 74 myBall.receiveShadow = true; 75 76 var light2 = new THREE.SpotLight( '#ffffff' ,1); 77 light2.castShadow = true; 78 light2.distance = 50; 79 light2.angle = 0.3; 80 light2.decay = 2; 81 light2.penumbra = 0.2; 82 light2.position.set( -2, 5, -2 ); 83 light2.shadow.camera.near = 1; 84 light2.shadow.camera.far = 3; 85 light2.shadow.camera.visible = true; 86 light2.shadow.mapSize.width = 1024; 87 light2.shadow.mapSize.height = 1024; 88 light2.target = sp; 89 scene.add(light2); 90 lightHelper2 = new THREE.SpotLightHelper(light2); 91 scene.add(lightHelper2); 92 93 renderer.shadowMap.enabled = true; 94 95 var matFloor = new THREE.MeshPhongMaterial( { color:0x808080 } ); 96 var geoFloor = new THREE.BoxGeometry( 200, 0.1, 200 ); 97 var mshFloor = new THREE.Mesh( geoFloor, matFloor ); 98 var ambient = new THREE.AmbientLight( 0x111111); 99 var lightHelper; 100 101 var light; 102 SpotLight(); 103 lightHelper = new THREE.SpotLightHelper( light ); 104 105 sp.castShadow = true; 106 sp.receiveShadow = true; 107 sp2.castShadow = true; 108 sp2.receiveShadow = true; 109 mshFloor.castShadow = true; 110 mshFloor.receiveShadow = true; 111 mshFloor.position.set( 0, -2, 0 ); 112 113 114 scene.add( mshFloor ); 115 scene.add(sp); 116 scene.add(sp2); 117 scene.add(myBall); 118 scene.add( light ); 119 scene.add(ambient); 120 scene.add(lightHelper); 121 // 0.9854 122 123 //聚光灯光源 124 function SpotLight(){ 125 light = new THREE.SpotLight( '#ffffff' ,1); 126 light.castShadow = true; 127 light.distance = 50; 128 light.angle = 0.6; 129 light.decay = 2; 130 light.penumbra = 0.2; 131 light.position.set( 3, 2, 1 ); 132 light.shadow.camera.near = 1; 133 light.shadow.camera.far = 3; 134 light.shadow.camera.visible = true; 135 light.shadow.mapSize.width = 1024; 136 light.shadow.mapSize.height = 1024; 137 light.target = sp; 138 scene.add(light); 139 } 140 141 //点光源 142 function PointLight(){ 143 light = new THREE.PointLight('#ffffff',1,50,2); 144 light.castShadow = true; 145 light.position.set( 3, 2, 1 ); 146 light.shadow.mapSize.width = 1024; 147 light.shadow.mapSize.height = 1024; 148 scene.add(light); 149 } 150 151 //平行光 152 function DirectLight(){ 153 light = new THREE.DirectionalLight('#ffffff',1); 154 light.castShadow = true; 155 light.position.set( 3, 2, 1 ); 156 light.decay = 2; 157 light.penumbra = 0.2; 158 light.shadow.mapSize.width = 1024; 159 light.shadow.mapSize.height = 1024; 160 scene.add(light); 161 } 162 163 var onProgress = function ( xhr ) { 164 if ( xhr.lengthComputable ) { 165 var percentComplete = xhr.loaded / xhr.total * 100; 166 console.log( Math.round(percentComplete, 2) + '% downloaded' ); 167 } 168 }; 169 170 var onError = function ( xhr ) { }; 171 THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() ); 172 var mtlLoader = new THREE.MTLLoader(); 173 mtlLoader.setPath( './' ); //设置我们需要加载的mtl文件路径 174 mtlLoader.load( 'lyn.mtl', function( material ) { //这里加载我们需要的文件名 175 material.preload();176 var objLoader = new THREE.OBJLoader(); 177 objLoader.setMaterials( material ); //材质,也可自定义 178 objLoader.setPath( './' ); //设置要加载的obj文件的路径 179 objLoader.load( 'lyn.obj', function ( object ) { //加载obj文件 180 object.position.z = 1; //这里设置我们的素材相对于原来的大小以及旋转缩放等 181 object.position.y = -0.5; 182 object.scale.x = 0.2; 183 object.scale.y = 0.2; 184 object.scale.z = 0.2; 185 object1 = object; //这里是对素材设置阴影的操作 186 for(var k in object.children){ //由于我们的素材并不是看上去的一个整体,所以需要进行迭代 187 //对其中的所有孩子都设置接收阴影以及投射阴影 188 //才能看到阴影效果 189 object.children[k].castShadow = true; //设置该对象可以产生阴影 190 object.children[k].receiveShadow = true; //设置该对象可以接收阴影 191 } 192 scene.add( object1 ); 193 194 }, onProgress, onError ); 195 }); 196 197 198 var render = function() { 199 requestAnimationFrame(render); 200 lightHelper.update(); 201 202 other.rotation.y += 0.01; 203 sp2.rotation.x += 0.01; 204 205 renderer.render(scene, camera); 206 } 207 208 render(); 209 210 //设置场景不停旋转 211 var tmp = 0; 212 var timer = setInterval(function(){ 213 if(tmp == 0){ 214 var route = (5 - light.position.y) / 50; 215 light.position.y += route; 216 if(route <= 0.001){ 217 tmp = 1; 218 } 219 }else{ 220 var route = (light.position.y - 1) / 50; 221 light.position.y -= route; 222 if(route <= 0.001){ 223 tmp = 0; 224 } 225 } 226 },15); 227 228 //设置图中的立方体可以旋转 229 var left = false; 230 var right = false; 231 var boxLeft = false; 232 var boxRight = false; 233 var boxUp = false; 234 var boxDown = false; 235 var object1 = ''; 236 setInterval(function(){ 237 if(left){ 238 object1.rotation.y -= 0.02; 239 }else if(right){ 240 object1.rotation.y += 0.02; 241 }else if(boxLeft){ 242 sp.rotation.y -= 0.02; 243 }else if(boxRight){ 244 sp.rotation.y += 0.02; 245 }else if(boxUp){246 sp.rotation.x -= 0.02; 247 }else if(boxDown){248 sp.rotation.x += 0.02; 249 } 250 },25); 251 252 document.onkeydown = function(ev){ 253 var ev = ev || event; 254 if(ev.keyCode == 65) 255 left = true; 256 else if(ev.keyCode == 68) 257 right = true; 258 else if(ev.keyCode == 37) 259 boxLeft = true; 260 else if(ev.keyCode == 38) 261 boxUp = true; 262 else if(ev.keyCode == 39) 263 boxRight = true; 264 else if(ev.keyCode == 40) 265 boxDown = true; 266 else if(ev.keyCode == 80){ 267 scene.remove(light); 268 PointLight(); 269 }else if(ev.keyCode == 83){ 270 scene.remove(light); 271 SpotLight(); 272 }else if(ev.keyCode == 17){ 273 scene.remove(light); 274 DirectLight(); 275 }else if(ev.keyCode == 90){ 276 if(light.intensity < 10) 277 light.intensity += 1; 278 }else if(ev.keyCode == 88){ 279 if(light.intensity > 0) 280 light.intensity -= 1; 281 }else if(ev.keyCode == 67){ 282 scene.remove(sp); 283 geometry = new THREE.BoxGeometry(1,1,1); 284 material = new THREE.MeshPhongMaterial({ 285 color : '#A44A32', 286 specular : '#ffffff', 287 specular : 100 288 }); 289 var sp = new THREE.Mesh(geometry,material); 290 sp.position.z = -0.5; 291 scene.add(sp); 292 }else if(ev.keyCode == 86){ 293 scene.remove(sp); 294 geometry = new THREE.BoxGeometry(1,1,1); 295 material = new THREE.MeshPhongMaterial({ 296 color : '#2194ce', 297 specular : '#111111', 298 specular : 100 299 }); 300 var sp = new THREE.Mesh(geometry,material); 301 sp.position.z = -0.5; 302 scene.add(sp); 303 } 304 } 305 306 document.onkeyup = function(ev){ 307 var ev = ev || event; 308 if(ev.keyCode == 65) 309 left = false; 310 else if(ev.keyCode == 68) 311 right = false; 312 else if(ev.keyCode == 37) 313 boxLeft = false; 314 else if(ev.keyCode == 38) 315 boxUp = false; 316 else if(ev.keyCode == 39) 317 boxRight = false; 318 else if(ev.keyCode == 40) 319 boxDown = false; 320 } 321 322 323 </script> 324 </body> 325 </html>
以上が3D レンダリングはthree.js を使用して作成されますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。