Ich beginne mit THREE.js und versuche, ein Rechteck mit einer Textur darauf zu zeichnen, das von einer einzelnen Lichtquelle beleuchtet wird. Ich denke, das ist so einfach wie es nur geht (HTML der Kürze halber weggelassen):
function loadScene() {
var world = document.getElementById('world'),
WIDTH = 1200,
HEIGHT = 500,
VIEW_ANGLE = 45,
ASPECT = WIDTH / HEIGHT,
NEAR = 0.1,
FAR = 10000,
renderer = new THREE.WebGLRenderer(),
camera = new THREE.Camera(VIEW_ANGLE, ASPECT, NEAR, FAR),
scene = new THREE.Scene(),
texture = THREE.ImageUtils.loadTexture('crate.gif'),
material = new THREE.MeshBasicMaterial({map: texture}),
// material = new THREE.MeshPhongMaterial({color: 0xCC0000});
geometry = new THREE.PlaneGeometry(100, 100),
mesh = new THREE.Mesh(geometry, material),
pointLight = new THREE.PointLight(0xFFFFFF);
camera.position.z = 200;
renderer.setSize(WIDTH, HEIGHT);
scene.addChild(mesh);
world.appendChild(renderer.domElement);
pointLight.position.x = 50;
pointLight.position.y = 50;
pointLight.position.z = 130;
scene.addLight(pointLight);
renderer.render(scene, camera);
}
Das Problem ist, ich kann nichts sehen. Wenn ich das Material ändere und das kommentierte verwende, erscheint ein Quadrat, wie ich es erwarten würde. Beachten Sie, dass
- Die Textur ist 256x256, also sind seine Seiten Zweierpotenz
- Die Funktion wird tatsächlich aufgerufen, wenn der Körper geladen wird. in der Tat funktioniert es mit einem anderen Material.
- Es funktioniert nicht, selbst wenn ich die Datei von einem Webserver aus bereitstelle. Es handelt sich also nicht um eine domänenübergreifende Richtlinie, die das Laden des Images nicht zulässt.
Was mache ich falsch?
javascript
three.js
Andrea
quelle
quelle
THREE.ImageUtils.loadTexture
(was veraltet ist) undTHREE.TextureLoader.load
stattdessen verwenden.ImageUtils
hat bei mir überhaupt nicht funktioniert, aberTextureLoader
beim ersten Versuch perfekt funktioniert. Docs: threejs.org/docs/index.html#api/loaders/TextureLoaderAndrea Lösung ist absolut richtig, ich werde nur eine weitere Implementierung schreiben, die auf der gleichen Idee basiert. Wenn Sie sich die Quelle THREE.ImageUtils.loadTexture () angesehen haben, werden Sie feststellen, dass sie das Javascript-Image-Objekt verwendet. Das Ereignis $ (window) .load wird ausgelöst, nachdem alle Bilder geladen wurden! In diesem Fall können wir unsere Szene mit den bereits geladenen Texturen rendern ...
CoffeeScript
$(document).ready -> material = new THREE.MeshLambertMaterial(map: THREE.ImageUtils.loadTexture("crate.gif")) sphere = new THREE.Mesh(new THREE.SphereGeometry(radius, segments, rings), material) $(window).load -> renderer.render scene, camera
JavaScript
$(document).ready(function() { material = new THREE.MeshLambertMaterial({ map: THREE.ImageUtils.loadTexture("crate.gif") }); sphere = new THREE.Mesh(new THREE.SphereGeometry(radius, segments, rings), material); $(window).load(function() { renderer.render(scene, camera); }); });
Vielen Dank...
quelle
In Version r75 von three.js sollten Sie Folgendes verwenden:
var loader = new THREE.TextureLoader(); loader.load('texture.png', function ( texture ) { var geometry = new THREE.SphereGeometry(1000, 20, 20); var material = new THREE.MeshBasicMaterial({map: texture, overdraw: 0.5}); var mesh = new THREE.Mesh(geometry, material); scene.add(mesh); });
quelle
In Version r82 von Three.js ist TextureLoader das Objekt, das zum Laden einer Textur verwendet werden soll.
Laden einer Textur ( Quellcode , Demo )
Auszug ( test.js ):
var scene = new THREE.Scene(); var ratio = window.innerWidth / window.innerHeight; var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 50); var renderer = ... [...] /** * Will be called when load completes. * The argument will be the loaded texture. */ var onLoad = function (texture) { var objGeometry = new THREE.BoxGeometry(20, 20, 20); var objMaterial = new THREE.MeshPhongMaterial({ map: texture, shading: THREE.FlatShading }); var mesh = new THREE.Mesh(objGeometry, objMaterial); scene.add(mesh); var render = function () { requestAnimationFrame(render); mesh.rotation.x += 0.010; mesh.rotation.y += 0.010; renderer.render(scene, camera); }; render(); } // Function called when download progresses var onProgress = function (xhr) { console.log((xhr.loaded / xhr.total * 100) + '% loaded'); }; // Function called when download errors var onError = function (xhr) { console.log('An error happened'); }; var loader = new THREE.TextureLoader(); loader.load('texture.jpg', onLoad, onProgress, onError);
Laden mehrerer Texturen ( Quellcode , Demo )
In diesem Beispiel werden die Texturen in den Konstruktor des Netzes geladen, mehrere Texturen werden mit Promises geladen .
Auszug ( Globe.js ):
Erstellen Sie einen neuen Container,
Object3D
indem Sie zwei Maschen im selben Container haben:var Globe = function (radius, segments) { THREE.Object3D.call(this); this.name = "Globe"; var that = this; // instantiate a loader var loader = new THREE.TextureLoader();
Eine Karte genannt ,
textures
wo jedes Objekt das enthälturl
eine Textur - Datei undval
für den Wert eines Three.js Speicherung Textur - Objekts.// earth textures var textures = { 'map': { url: 'relief.jpg', val: undefined }, 'bumpMap': { url: 'elev_bump_4k.jpg', val: undefined }, 'specularMap': { url: 'wateretopo.png', val: undefined } };
Das Array von Versprechungen, für jedes Objekt in der Karte, das als
textures
Push ein neues Versprechen im Array bezeichnet wirdtexturePromises
, wird von jedem Versprechen aufgerufenloader.load
. Wenn der Wert vonentry.val
ein gültigesTHREE.Texture
Objekt ist, lösen Sie das Versprechen auf.var texturePromises = [], path = './'; for (var key in textures) { texturePromises.push(new Promise((resolve, reject) => { var entry = textures[key] var url = path + entry.url loader.load(url, texture => { entry.val = texture; if (entry.val instanceof THREE.Texture) resolve(entry); }, xhr => { console.log(url + ' ' + (xhr.loaded / xhr.total * 100) + '% loaded'); }, xhr => { reject(new Error(xhr + 'An error occurred loading while loading: ' + entry.url)); } ); })); }
Promise.all
Nimmt das Versprechen-ArraytexturePromises
als Argument. Dadurch wartet der Browser auf die Lösung aller Versprechen. Wenn dies der Fall ist, können wir die Geometrie und das Material laden.// load the geometry and the textures Promise.all(texturePromises).then(loadedTextures => { var geometry = new THREE.SphereGeometry(radius, segments, segments); var material = new THREE.MeshPhongMaterial({ map: textures.map.val, bumpMap: textures.bumpMap.val, bumpScale: 0.005, specularMap: textures.specularMap.val, specular: new THREE.Color('grey') }); var earth = that.earth = new THREE.Mesh(geometry, material); that.add(earth); });
Für die Wolkenkugel ist nur eine Textur erforderlich:
// clouds loader.load('n_amer_clouds.png', map => { var geometry = new THREE.SphereGeometry(radius + .05, segments, segments); var material = new THREE.MeshPhongMaterial({ map: map, transparent: true }); var clouds = that.clouds = new THREE.Mesh(geometry, material); that.add(clouds); }); } Globe.prototype = Object.create(THREE.Object3D.prototype); Globe.prototype.constructor = Globe;
quelle
Ohne Fehler Handeling
//Load background texture new THREE.TextureLoader(); loader.load('https://images.pexels.com/photos/1205301/pexels-photo-1205301.jpeg' , function(texture) { scene.background = texture; });
Mit Fehlerbehandlung
// Function called when download progresses var onProgress = function (xhr) { console.log((xhr.loaded / xhr.total * 100) + '% loaded'); }; // Function called when download errors var onError = function (error) { console.log('An error happened'+error); }; //Function called when load completes. var onLoad = function (texture) { var objGeometry = new THREE.BoxGeometry(30, 30, 30); var objMaterial = new THREE.MeshPhongMaterial({ map: texture, shading: THREE.FlatShading }); var boxMesh = new THREE.Mesh(objGeometry, objMaterial); scene.add(boxMesh); var render = function () { requestAnimationFrame(render); boxMesh.rotation.x += 0.010; boxMesh.rotation.y += 0.010; sphereMesh.rotation.y += 0.1; renderer.render(scene, camera); }; render(); } //LOAD TEXTURE and on completion apply it on box var loader = new THREE.TextureLoader(); loader.load('https://upload.wikimedia.org/wikipedia/commons/thumb/9/97/The_Earth_seen_from_Apollo_17.jpg/1920px-The_Earth_seen_from_Apollo_17.jpg', onLoad, onProgress, onError);
Ergebnis:
https://codepen.io/hiteshsahu/pen/jpGLpq/
quelle
Verwenden Sie TextureLoader, um ein Bild als Textur zu laden, und wenden Sie diese Textur dann einfach auf den Szenenhintergrund an.
new THREE.TextureLoader(); loader.load('https://images.pexels.com/photos/1205301/pexels-photo-1205301.jpeg' , function(texture) { scene.background = texture; });
Ergebnis:
https://codepen.io/hiteshsahu/pen/jpGLpq?editors=0011
Siehe den Pen Flat Earth Three.JS von Hitesh Sahu ( @hiteshsahu ) auf CodePen .quelle