Zum Wochenausklang habe ich noch ein paar fantastische 3D Animationen für Euch. Die animierten 3D-Car Darstellungen stammen aus der Bespielsammlung von three.js. Mit der JavaScript-Bibliothek three.js lassen sich im Browser animierte Darstellungen in 3D erstellen. three.js erzeugt mit Hilfe der Anaglyphenbildtechnik einen räumlichen Eindruck.
Sie haben es eilig? Dann speichern Sie diesen Blogartikel von R23 als PDF
Brauchen Sie den Inhalt dieses Artikels “3D im Internet: three.js webgl – materials – cube reflection” schnell und bequem? Dann speichern Sie ihn doch einfach als PDF!
Meine Stammleser können sich sicherlich noch an die 3D Teekanne auf einer Brücke erinnern?
Wir visualisieren Ideen!
R23 ist Ihre Digitalagentur für Virtual & Augmented Reality. Wir investieren in immersive Technologien wie Augmented Reality und künstliche Intelligenz, die die Grundlage für die Art und Weise sein werden, wie wir in Zukunft online einkaufen. Mit neuen visuellen Entdeckungstools helfen wir Käufer:innen, neue Produkte zu finden, und mit AR-Erlebnissen helfen wir Menschen, Artikel zu visualisieren, bevor sie sie kaufen.
Fotorealistische Visualisierungen und 3D-Animationen lassen sich schnell und kostengünstig erzeugen und in Ihrem Online-Shop veröffentlichen.
Navigationshilfe
3D-Modell drehen: Drücken der linken Maustaste und bewegen der Maus
Vergrößern/Verkleinern: Mausrad drehen
Verschieben: die mittleren Maustaste gedrückt halten und die Maus bewegen
Die Beispiele kannst du dir in einem neuen Browser-Fenster anzeigen lassen.
https://blog.r23.de/3d/loader/cubemap.html
Auf der Brücke drehen wir heute in der Luft die Autos: Bugatti Veyron, Lamborghini Gallardo, Ferrari F50 und Chevrolet Camaro. In den 3D Animationen können wir die Lackierung per Klick ändern. Bugatti Veyron wurde von Troyano, Lamborghini Gallardo wurde von machman_3d, Ferrari F50 wurde von daniel sathya und Chevrolet Camaro wurde von dskfnwn erstellt.
Bevor wir uns die 3D Animation ansehen noch etwas Physik.
Das Einkörperproblem
Stellen Sie sich ein Universum vor, das abgesehen von einem einzigen Himmelskörper (Masse) wie einem Stern oder Planeten gänzlich leer ist. Bei einem solchen Universum stellt sich folgendes Einkörperproblem:
Wie können Sie anhand einer anfänglichen Position und Geschwindigkeit für die Masse die Bewegung der Masse als Funktion der Zeit vorhersagen?
Die Antwort ist, wie Sie vielleicht wissen, einfach:
- Wenn die Geschwindigkeit v der Masse 0 ist, bewegt sich die Masse nie (keine Bewegung).
- Wenn die Geschwindigkeit v der Masse nicht 0 ist, bewegt sich die Masse mit einer konstanten Geschwindigkeit und Richtung entsprechend v.
Obwohl es beim Einkörperproblem keine interessante Dynamik gibt, bietet es doch die Möglichkeit, ein Three.js-“Universum” einzurichten.
Das Beispiel kannst du dir in einem neuen Browser-Fenster anzeigen lassen.
https://blog.r23.de/r23webvr/three.js-r86/examples/webgl_materials_cars.html
Code
Der Quellcode für die 3D-Oberflächenmodelle ist verfügbar.
<!DOCTYPE html> <html lang="en"> <head> <title>three.js webgl - materials - cube reflection [cars]</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> <style> body { background:#000; color:#fff; padding:0; margin:0; overflow:hidden; font-family:georgia; text-align:center; } h1 { } a { color:skyblue; text-decoration:none } canvas { pointer-events:none; z-index:10; position:relative; } #d { position:absolute; width: 100%; text-align:center; margin:1em 0 -4.5em 0; z-index:1000; } .bwrap { margin:0.5em 0 0 0 } button { font-family:georgia; border:0; background:#000; color:#fff; padding:0.2em 0.5em; cursor:pointer; border-radius:3px; } button:hover { background:#333 } #buttons_cars button { color:#fa0 } #car_info { text-align:center; } #car_name { font-size:1em } #car_author { font-size:1em } #oldie { background:rgb(50,0,0) !important; color:#fff !important; margin-top:7em!important } </style> </head> <body> <div id="d"> <div id="info"> <a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> webgl demo : texture by <a href="http://www.humus.name/index.php?page=Textures" target="_blank" rel="noopener">Humus</a> : <span id="car_info"> <span id="car_name">Bugatti Veyron model</span> by <span id="car_author"><a href="http://artist-3d.com/free_3d_models/dnm/model_disp.php?uid=1129" target="_blank" rel="noopener">Troyano</a></span> </span> </div> <div id="buttons_cars" class="bwrap"> <button id="veyron">Bugatti Veyron</button> <button id="gallardo">Lamborghini Gallardo</button> <button id="f50">Ferrari F50</button> <button id="camaro">Chevrolet Camaro</button> </div> <div id="buttons_materials" class="bwrap"></div> </div> <script src="../build/three.js"></script> <script src="js/loaders/BinaryLoader.js"></script> <script src="js/Detector.js"></script> <script src="js/libs/stats.min.js"></script> <script> if ( ! Detector.webgl ) Detector.addGetWebGLMessage(); var STATS_ENABLED = false; var CARS = { "veyron": { name: "Bugatti Veyron", url: "obj/veyron/VeyronNoUv_bin.js", author: '<a href="http://artist-3d.com/free_3d_models/dnm/model_disp.php?uid=1129" target="_blank" rel="noopener">Troyano</a>', init_rotation: [ 0, 0, 0 ], scale: 5.5, init_material: 4, body_materials: [ 2 ], object: null, buttons: null, materials: null }, "gallardo": { name: "Lamborghini Gallardo", url: "obj/gallardo/GallardoNoUv_bin.js", author: '<a href="http://artist-3d.com/free_3d_models/dnm/model_disp.php?uid=1711" target="_blank" rel="noopener">machman_3d</a>', init_rotation: [ 0, 0, 0 ], scale: 3.7, init_material: 9, body_materials: [ 3 ], object: null, buttons: null, materials: null }, "f50": { name: "Ferrari F50", url: "obj/f50/F50NoUv_bin.js", author: '<a href="http://artist-3d.com/free_3d_models/dnm/model_disp.php?uid=1687" target="_blank" rel="noopener">daniel sathya</a>', init_rotation: [ 0, 0, 0 ], scale: 0.175, init_material: 2, body_materials: [ 3, 6, 7, 8, 9, 10, 23, 24 ], object: null, buttons: null, materials: null }, "camaro": { name: "Chevrolet Camaro", url: "obj/camaro/CamaroNoUv_bin.js", author: '<a href="http://www.turbosquid.com/3d-models/blender-camaro/411348" target="_blank" rel="noopener">dskfnwn</a>', init_rotation: [ 0.0, 0.0, 0.0 /*0, 1, 0*/ ], scale: 75, init_material: 0, body_materials: [ 0 ], object: null, buttons: null, materials: null } }; var container, stats; var camera, scene, renderer; var m, mi; var directionalLight, pointLight; var mouseX = 0, mouseY = 0; var windowHalfX = window.innerWidth / 2; var windowHalfY = window.innerHeight / 2; var loader = new THREE.BinaryLoader(); init(); animate(); function init() { container = document.createElement( 'div' ); document.body.appendChild( container ); // CAMERAS camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 100000 ); // SCENE var textureCube = new THREE.CubeTextureLoader() .setPath( 'textures/cube/Bridge2/') .load( [ 'posx.jpg', 'negx.jpg', 'posy.jpg', 'negy.jpg', 'posz.jpg', 'negz.jpg' ] ); scene = new THREE.Scene(); scene.background = textureCube; // LIGHTS var ambient = new THREE.AmbientLight( 0x050505 ); scene.add( ambient ); directionalLight = new THREE.DirectionalLight( 0xffffff, 2 ); directionalLight.position.set( 2, 1.2, 10 ).normalize(); scene.add( directionalLight ); directionalLight = new THREE.DirectionalLight( 0xffffff, 1 ); directionalLight.position.set( -2, 1.2, -10 ).normalize(); scene.add( directionalLight ); pointLight = new THREE.PointLight( 0xffaa00, 2 ); pointLight.position.set( 2000, 1200, 10000 ); scene.add( pointLight ); // renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); renderer.setFaceCulling( THREE.CullFaceNone ); container.appendChild( renderer.domElement ); if ( STATS_ENABLED ) { stats = new Stats(); container.appendChild( stats.dom ); } document.addEventListener( 'mousemove', onDocumentMouseMove, false ); // common materials var mlib = { "Orange": new THREE.MeshLambertMaterial( { color: 0xff6600, envMap: textureCube, combine: THREE.MixOperation, reflectivity: 0.3 } ), "Blue": new THREE.MeshLambertMaterial( { color: 0x001133, envMap: textureCube, combine: THREE.MixOperation, reflectivity: 0.3 } ), "Red": new THREE.MeshLambertMaterial( { color: 0x660000, envMap: textureCube, combine: THREE.MixOperation, reflectivity: 0.25 } ), "Black": new THREE.MeshLambertMaterial( { color: 0x000000, envMap: textureCube, combine: THREE.MixOperation, reflectivity: 0.15 } ), "White": new THREE.MeshLambertMaterial( { color: 0xffffff, envMap: textureCube, combine: THREE.MixOperation, reflectivity: 0.25 } ), "Carmine": new THREE.MeshPhongMaterial( { color: 0x770000, specular:0xffaaaa, envMap: textureCube, combine: THREE.MultiplyOperation } ), "Gold": new THREE.MeshPhongMaterial( { color: 0xaa9944, specular:0xbbaa99, shininess:50, envMap: textureCube, combine: THREE.MultiplyOperation } ), "Bronze": new THREE.MeshPhongMaterial( { color: 0x150505, specular:0xee6600, shininess:10, envMap: textureCube, combine: THREE.MixOperation, reflectivity: 0.25 } ), "Chrome": new THREE.MeshPhongMaterial( { color: 0xffffff, specular:0xffffff, envMap: textureCube, combine: THREE.MultiplyOperation } ), "Orange metal": new THREE.MeshLambertMaterial( { color: 0xff6600, envMap: textureCube, combine: THREE.MultiplyOperation } ), "Blue metal": new THREE.MeshLambertMaterial( { color: 0x001133, envMap: textureCube, combine: THREE.MultiplyOperation } ), "Red metal": new THREE.MeshLambertMaterial( { color: 0x770000, envMap: textureCube, combine: THREE.MultiplyOperation } ), "Green metal": new THREE.MeshLambertMaterial( { color: 0x007711, envMap: textureCube, combine: THREE.MultiplyOperation } ), "Black metal": new THREE.MeshLambertMaterial( { color: 0x222222, envMap: textureCube, combine: THREE.MultiplyOperation } ), "Pure chrome": new THREE.MeshLambertMaterial( { color: 0xffffff, envMap: textureCube } ), "Dark chrome": new THREE.MeshLambertMaterial( { color: 0x444444, envMap: textureCube } ), "Darker chrome":new THREE.MeshLambertMaterial( { color: 0x222222, envMap: textureCube } ), "Black glass": new THREE.MeshLambertMaterial( { color: 0x101016, envMap: textureCube, opacity: 0.975, transparent: true } ), "Dark glass": new THREE.MeshLambertMaterial( { color: 0x101046, envMap: textureCube, opacity: 0.25, transparent: true } ), "Blue glass": new THREE.MeshLambertMaterial( { color: 0x668899, envMap: textureCube, opacity: 0.75, transparent: true } ), "Light glass": new THREE.MeshBasicMaterial( { color: 0x223344, envMap: textureCube, opacity: 0.25, transparent: true, combine: THREE.MixOperation, reflectivity: 0.25 } ), "Red glass": new THREE.MeshLambertMaterial( { color: 0xff0000, opacity: 0.75, transparent: true } ), "Yellow glass": new THREE.MeshLambertMaterial( { color: 0xffffaa, opacity: 0.75, transparent: true } ), "Orange glass": new THREE.MeshLambertMaterial( { color: 0x995500, opacity: 0.75, transparent: true } ), "Orange glass 50": new THREE.MeshLambertMaterial( { color: 0xffbb00, opacity: 0.5, transparent: true } ), "Red glass 50": new THREE.MeshLambertMaterial( { color: 0xff0000, opacity: 0.5, transparent: true } ), "Fullblack rough": new THREE.MeshLambertMaterial( { color: 0x000000 } ), "Black rough": new THREE.MeshLambertMaterial( { color: 0x050505 } ), "Darkgray rough": new THREE.MeshLambertMaterial( { color: 0x090909 } ), "Red rough": new THREE.MeshLambertMaterial( { color: 0x330500 } ), "Darkgray shiny": new THREE.MeshPhongMaterial( { color: 0x000000, specular: 0x050505 } ), "Gray shiny": new THREE.MeshPhongMaterial( { color: 0x050505, shininess: 20 } ) }; // Gallardo materials CARS[ "gallardo" ].materials = { body: [ [ "Orange", mlib[ "Orange" ] ], [ "Blue", mlib[ "Blue" ] ], [ "Red", mlib[ "Red" ] ], [ "Black", mlib[ "Black" ] ], [ "White", mlib[ "White" ] ], [ "Orange metal", mlib[ "Orange metal" ] ], [ "Blue metal", mlib[ "Blue metal" ] ], [ "Green metal", mlib[ "Green metal" ] ], [ "Black metal", mlib[ "Black metal" ] ], [ "Carmine", mlib[ "Carmine" ] ], [ "Gold", mlib[ "Gold" ] ], [ "Bronze", mlib[ "Bronze" ] ], [ "Chrome", mlib[ "Chrome" ] ] ] }; m = CARS[ "gallardo" ].materials; mi = CARS[ "gallardo" ].init_material; CARS[ "gallardo" ].mmap = { 0: mlib[ "Pure chrome" ], // wheels chrome 1: mlib[ "Black rough" ], // tire 2: mlib[ "Black glass" ], // windshield 3: m.body[ mi ][ 1 ], // body 4: mlib[ "Red glass" ], // back lights 5: mlib[ "Yellow glass" ], // front lights 6: mlib[ "Dark chrome" ] // windshield rim }; // Veyron materials CARS[ "veyron" ].materials = { body: [ [ "Orange metal", mlib[ "Orange metal" ] ], [ "Blue metal", mlib[ "Blue metal" ] ], [ "Red metal", mlib[ "Red metal" ] ], [ "Green metal", mlib[ "Green metal" ] ], [ "Black metal", mlib[ "Black metal" ] ], [ "Gold", mlib[ "Gold" ] ], [ "Bronze", mlib[ "Bronze" ] ], [ "Chrome", mlib[ "Chrome" ] ] ] }; m = CARS[ "veyron" ].materials; mi = CARS[ "veyron" ].init_material; CARS[ "veyron" ].mmap = { 0: mlib[ "Black rough" ], // tires + inside 1: mlib[ "Pure chrome" ], // wheels + extras chrome 2: m.body[ mi ][ 1 ], // back / top / front torso 3: mlib[ "Dark glass" ], // glass 4: mlib[ "Pure chrome" ], // sides torso 5: mlib[ "Pure chrome" ], // engine 6: mlib[ "Red glass 50" ], // backlights 7: mlib[ "Orange glass 50" ] // backsignals }; // F50 materials CARS[ "f50" ].materials = { body: [ [ "Orange", mlib[ "Orange" ] ], [ "Blue", mlib[ "Blue" ] ], [ "Red", mlib[ "Red" ] ], [ "Black", mlib[ "Black" ] ], [ "White", mlib[ "White" ] ], [ "Orange metal", mlib[ "Orange metal" ] ], [ "Blue metal", mlib[ "Blue metal" ] ], [ "Black metal", mlib[ "Black metal" ] ], [ "Carmine", mlib[ "Carmine" ] ], [ "Gold", mlib[ "Gold" ] ], [ "Bronze", mlib[ "Bronze" ] ], [ "Chrome", mlib[ "Chrome" ] ] ] }; m = CARS[ "f50" ].materials; mi = CARS[ "f50" ].init_material; CARS[ "f50" ].mmap = { 0: mlib[ "Dark chrome" ], // interior + rim 1: mlib[ "Pure chrome" ], // wheels + gears chrome 2: mlib[ "Blue glass" ], // glass 3: m.body[ mi ][ 1 ], // torso mid + front spoiler 4: mlib[ "Darkgray shiny" ], // interior + behind seats 5: mlib[ "Darkgray shiny" ], // tiny dots in interior 6: m.body[ mi ][ 1 ], // back torso 7: m.body[ mi ][ 1 ], // right mirror decal 8: m.body[ mi ][ 1 ], // front decal 9: m.body[ mi ][ 1 ], // front torso 10: m.body[ mi ][ 1 ], // left mirror decal 11: mlib[ "Pure chrome" ], // engine 12: mlib[ "Darkgray rough" ], // tires side 13: mlib[ "Darkgray rough" ], // tires bottom 14: mlib[ "Darkgray shiny" ], // bottom 15: mlib[ "Black rough" ], // ??? 16: mlib[ "Orange glass" ], // front signals 17: mlib[ "Dark chrome" ], // wheels center 18: mlib[ "Red glass" ], // back lights 19: mlib[ "Black rough" ], // ??? 20: mlib[ "Red rough" ], // seats 21: mlib[ "Black rough" ], // back plate 22: mlib[ "Black rough" ], // front light dots 23: m.body[ mi ][ 1 ], // back torso 24: m.body[ mi ][ 1 ] // back torso center }; // Camero materials CARS[ "camaro" ].materials = { body: [ [ "Orange", mlib[ "Orange" ] ], [ "Blue", mlib[ "Blue" ] ], [ "Red", mlib[ "Red" ] ], [ "Black", mlib[ "Black" ] ], [ "White", mlib[ "White" ] ], [ "Orange metal", mlib[ "Orange metal" ] ], [ "Blue metal", mlib[ "Blue metal" ] ], [ "Red metal", mlib[ "Red metal" ] ], [ "Green metal", mlib[ "Green metal" ] ], [ "Black metal", mlib[ "Black metal" ] ], [ "Gold", mlib[ "Gold" ] ], [ "Bronze", mlib[ "Bronze" ] ], [ "Chrome", mlib[ "Chrome" ] ] ] }; m = CARS[ "camaro" ].materials; mi = CARS[ "camaro" ].init_material; CARS[ "camaro" ].mmap = { 0: m.body[ mi ][ 1 ], // car body 1: mlib[ "Pure chrome" ], // wheels chrome 2: mlib[ "Pure chrome" ], // grille chrome 3: mlib[ "Dark chrome" ], // door lines 4: mlib[ "Light glass" ], // windshield 5: mlib[ "Gray shiny" ], // interior 6: mlib[ "Black rough" ], // tire 7: mlib[ "Fullblack rough" ], // tireling 8: mlib[ "Fullblack rough" ] // behind grille }; loader.load( CARS[ "veyron" ].url, function( geometry ) { createScene( geometry, "veyron" ) } ); for( var c in CARS ) initCarButton( c ); // window.addEventListener( 'resize', onWindowResize, false ); } function onWindowResize() { windowHalfX = window.innerWidth / 2; windowHalfY = window.innerHeight / 2; camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); } function initCarButton( car ) { $( car ).addEventListener( 'click', function() { if ( ! CARS[ car ].object ) { loader.load( CARS[ car ].url, function( geometry ) { createScene( geometry, car ) } ); } else { switchCar( car ); } }, false ); } function $( id ) { return document.getElementById( id ) } function button_name( car, index ) { return "m_" + car + "_" + index } function switchCar( car ) { for ( var c in CARS ) { if ( c != car && CARS[ c ].object ) { CARS[ c ].object.visible = false; CARS[ c ].buttons.style.display = "none"; } } CARS[ car ].object.visible = true; CARS[ car ].buttons.style.display = "block"; $( "car_name" ).innerHTML = CARS[ car ].name + " model"; $( "car_author" ).innerHTML = CARS[ car ].author; } function createButtons( materials, car ) { var buttons, i, src = ""; for( i = 0; i < materials.length; i ++ ) { src += '<button id="' + button_name( car, i ) + '">' + materials[ i ][ 0 ] + '</button> '; } buttons = document.createElement( "div" ); buttons.innerHTML = src; $( "buttons_materials" ).appendChild( buttons ); return buttons; } function attachButtonMaterials( materials, faceMaterials, material_indices, car ) { for( var i = 0; i < materials.length; i ++ ) { $( button_name( car, i ) ).counter = i; $( button_name( car, i ) ).addEventListener( 'click', function() { for ( var j = 0; j < material_indices.length; j ++ ) { faceMaterials[ material_indices [ j ] ] = materials[ this.counter ][ 1 ]; } }, false ); } } function createScene( geometry, car ) { geometry.sortFacesByMaterialIndex(); var m = [], s = CARS[ car ].scale * 1, r = CARS[ car ].init_rotation, materials = CARS[ car ].materials, mi = CARS[ car ].init_material, bm = CARS[ car ].body_materials; for ( var i in CARS[ car ].mmap ) { m[ i ] = CARS[ car ].mmap[ i ]; } var mesh = new THREE.Mesh( geometry, m ); mesh.rotation.x = r[ 0 ]; mesh.rotation.y = r[ 1 ]; mesh.rotation.z = r[ 2 ]; mesh.scale.x = mesh.scale.y = mesh.scale.z = s; scene.add( mesh ); CARS[ car ].object = mesh; CARS[ car ].buttons = createButtons( materials.body, car ); attachButtonMaterials( materials.body, m, bm, car ); switchCar( car ); } function onDocumentMouseMove(event) { mouseY = ( event.clientY - window.innerHeight ); } // function animate() { requestAnimationFrame( animate ); render(); } function render() { var timer = -0.0002 * Date.now(); camera.position.x = 1000 * Math.cos( timer ); camera.position.y += ( - mouseY - camera.position.y ) * .05; camera.position.z = 1000 * Math.sin( timer ); camera.lookAt( scene.position ); renderer.render( scene, camera ); if ( STATS_ENABLED ) stats.update(); } </script> </body> </html>
Nützliche Links
Jetzt bist du gefragt!
Hast du Anregungen, Ergänzungen, einen Fehler gefunden oder ist dieser Beitrag nicht mehr aktuell? Dann freue ich mich auf deinen Kommentar.
Du kannst diesen Beitrag natürlich auch weiterempfehlen. Ich bin dir für jede Unterstützung dankbar!
Schreiben Sie einen Kommentar