I'd like to modify the material in a gltf loaded model to set its opacity/transparency.
I can't seem to get any meshes. I have created this fiddle that says 'no mesh found'. I have found quite a few examples of getting material and they all seem to do it this way (making sure it's mesh then getting the material).
<style>
canvas {
display: block;
width: 98%;
height: 98%;
}
</style>
<canvas id="canvasid"></canvas>
<script src="https://cdn.jsdelivr.net/npm/three#0.143/examples/js/controls/OrbitControls.js"></script>-->
<script async src="https://unpkg.com/es-module-shims#1.3.6/dist/es-module-shims.js"></script>
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three#0.143/build/three.module.js"
}
}
</script>
<script type="module">
import * as THREE from 'three';
import { GLTFLoader } from 'https://cdn.jsdelivr.net/npm/three#0.143/examples/jsm/loaders/GLTFLoader.js';
import { OrbitControls } from 'https://cdn.jsdelivr.net/npm/three#0.143/examples/jsm/controls/OrbitControls.js';
var scene = new THREE.Scene();
scene.background = new THREE.Color(0x6699cc);
const lights = [];
lights[0] = new THREE.PointLight(0xffffff, 1, 0);
lights[1] = new THREE.PointLight(0xffffff, 1, 0);
lights[2] = new THREE.PointLight(0xffffff, 1, 0);
lights[0].position.set(0, 100, 0);
lights[1].position.set(100, 100, 100);
lights[2].position.set(- 100, - 100, - 100);
scene.add(lights[0]);
scene.add(lights[1]);
scene.add(lights[2]);
const loader = new GLTFLoader();
loader.load("https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf", function (gltf) {
const mesh = gltf.scene.children[0];
scene.add(mesh);
//my main question is about this code - looks like everyone can test if isMesh, then can get the material. I have tried multiple models and can never find any mesh. If I just assumme a material that doesn't work either
gltf.scene.traverse((o) => {
if (o.isMesh) {
console.log("found mesh");
console.log(o && o.material);
} else {
console.log("no mesh found");
}
});
}, undefined, function (error) {
console.error(error);
});
var canvas = document.getElementById("canvasid");
var renderer = new THREE.WebGLRenderer({
canvas: canvas,
antialias: true
});
renderer.setSize(canvas.parentElement.clientWidth, canvas.parentElement.clientHeight);
var camera = new THREE.PerspectiveCamera(1, canvas.parentElement.clientWidth / canvas.parentElement.clientHeight, 1, 1000);
camera.position.z = 100;
const controls = new OrbitControls(camera, renderer.domElement);
controls.update();
controls.autoRotate = true;
controls.enableDamping = true;
var animate = function () {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
};
window.addEventListener('resize', function () {
renderer.setSize(canvas.parentElement.clientWidth, canvas.parentElement.clientHeight);
camera.aspect = canvas.parentElement.clientWidth / canvas.parentElement.clientHeight;
camera.updateProjectionMatrix();
}, false);
animate();
How can I access the mesh/material?
The traverse does not work since you add the first child of gltf.scene to scene. That means you change the object hierarchy and thus break the traversal.
To fix this, simply move the below two lines of code after the call of Object3D.traverse().
const mesh = gltf.scene.children[0];
scene.add(mesh);
Also, consider to just do this since a glTF asset does not necessarily only have a single child mesh:
scene.add(gltf.scene);
Updated fiddle: https://jsfiddle.net/ftcnby9e/
Related
I downloaded the following model from sketchfab and imported to my scene but model does not seem looking correctly especially the glass blur.
here is my code
import "./sass/main.scss";
import { Scene, PerspectiveCamera, WebGLRenderer, DirectionalLight, ACESFilmicToneMapping, sRGBEncoding, Object3D, Mesh, MeshStandardMaterial, ReinhardToneMapping, AmbientLight, EquirectangularReflectionMapping,
} from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
const scene = new Scene();
const camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new WebGLRenderer({
canvas: document.querySelector("canvas#webgl"),
antialias: true
});
renderer.toneMapping = ACESFilmicToneMapping;
renderer.outputEncoding = sRGBEncoding;
renderer.physicallyCorrectLights = true;
renderer.toneMappingExposure = 1
renderer.shadowMap.enabled = true;
const controls = new OrbitControls(camera, renderer.domElement);
camera.rotation.reorder("YXZ")
camera.position.set(2, 1.5, 3.5);
camera.rotation.set(-0.25, Math.PI * 0.25, 0);
renderer.setSize(window.innerWidth, window.innerHeight)
const gltfLoader = new GLTFLoader();
const rgbeLoader = new RGBELoader();
const environmentMap = await rgbeLoader.loadAsync("./assets/environment/puresky.hdr")
environmentMap.mapping = EquirectangularReflectionMapping;
scene.environment = environmentMap;
await gltfLoader.loadAsync("./assets/models/scene.gltf").then(gltf => {
scene.add(gltf.scene);
});
mapAllElements();
function render() {
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
function mapAllElements() {
scene.traverse((child) => {
if (child instanceof Mesh && child.material instanceof MeshStandardMaterial) {
child.material.envMap = environmentMap;
child.material.envMapIntensity = 1;
child.material.needsUpdate = true;
}
})
}
I searched my problem on the internet but couldn't find anything useful and I also tried other gltf models from sketchfab but other models also does not looking properly.
My code is using top-level-await feature and I enabled from webpack.config.js
The way the model looks is tied to the Viewer in which it is loaded. If you want to recreate the effects you can create a new material using the THREE.MeshPhysicalMaterial class, which is a physically-based material that can simulate realistic lighting and materials.
A barebones example is as follows:
scene.traverse((child) => {
if (child instanceof Mesh && child.material instanceof MeshStandardMaterial) {
if (child.name.includes("glass")) {
// Create a new MeshPhysicalMaterial for the glass object
const glassMaterial = new THREE.MeshPhysicalMaterial({
color: 0xffffff,
metalness: 0,
roughness: 0.1,
transparent: true,
transmission: 0.9,
opacity: 0.7,
envMap: environmentMap,
envMapIntensity: 1,
side: THREE.DoubleSide,
});
// Replace the existing material with the new glass material
child.material = glassMaterial;
} else {
// For non-glass objects, just add the environment map
child.material.envMap = environmentMap;
child.material.envMapIntensity = 1;
}
child.material.needsUpdate = true;
}
});
}
If you don't want to re-invent the wheel, you can also take a look at WebGi, where you have much finer grained control through an accessible plugin system.
I have looked through stack overflow and google and I have found how to CENTER a text geometry but that is not what I want to do.
I have a scene that just has a block of text that says "Buy Here!". Using the documentation in the three.js website and examples here I was able to do that after some struggling. I had some trouble finding out how to refer to that mesh since I had created the geometry inside a function, and it took hours for me to know about setting a name for it as a string so it can be accessible from different parent/child levels.
What I am NOT able to do now is to offset the text by some arbitrary number of units. I tried shifting it down by 5 units. No matter how I try to do it it isn't working. I either manage to make the text geometry disappear OR my whole scene is black.
Here is my code...
I have the basic scene setup working properly and I'll include it here but feel free to skip since I'm pretty sure this has nothing to do with the issue...
import './style.css'
import * as THREE from 'three';
import { OrbitControls } from 'https://cdn.jsdelivr.net/npm/three#0.117.0/examples/jsm/controls/OrbitControls.js';
import TWEEN from 'https://cdn.jsdelivr.net/npm/#tweenjs/tween.js#18.5.0/dist/tween.esm.js';
//BASIC SCENE SETUP
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
//LIGHTS (POINT AND AMBIENT)
const pointLight = new THREE.PointLight(0xFFFFFF);
pointLight.position.set(5, 5, 5);
const ambientLight = new THREE.AmbientLight(0xFFFFFF);
scene.add(pointLight, ambientLight);
//RESIZE WINDOW
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
render();
}, false);
//ORBIT CONTROLS
const controls = new OrbitControls(camera, renderer.domElement);
controls.minDistance = 5;
controls.maxDistance = 70;
controls.enablePan = false;
controls.enableRotate = false;
controls.enableZoom = false;
controls.target.set(0,0,-1);
camera.position.setZ(25);
window.addEventListener("click", (event) => {
onClick(event);
})
window.addEventListener("mousemove", onMouseMove);
var animate = function() {
requestAnimationFrame(animate);
controls.update();
render();
TWEEN.update();
};
function render() {
renderer.render(scene, camera);
}
animate();
and here is my code for the text object....
var loaderF = new THREE.FontLoader();
loaderF.load( 'https://threejs.org/examples/fonts/optimer_regular.typeface.json', function ( font ) {
var geometry = new THREE.TextGeometry( 'Buy Here!', {
font: font,
size: 2.3,
height: 0.1,
curveSegments: 15,
bevelEnabled: true,
bevelThickness: 0.5,
bevelSize: 0.31,
bevelSegments: 7
} );
geometry.center();
var material = new THREE.MeshLambertMaterial({color: 0x686868});
var mesh = new THREE.Mesh( geometry, material );
mesh.name = "bhText"
scene.add( mesh );
mesh.userData = { URL: "http://google.com"};
} );
Here's what I have tried.....
under "var geometry ({...});" I typed....
geometry.position.setX(-5);
but the text object disappears completely so I tried
geometry.position.setX = -5;
but there was no difference so i tried taking out
geometry.center();
but it had the same results.
So then I tried using
mesh.position.x = -5;
with AND without
geometry.center();
but again, they all just make my text object disappear.
So now I tried to set the position from outside the function by typing the following code OUTSIDE of everything that is contained in
loaderF.load ('https.....', function (font){var geometry = .....})
using the reference I learned....
scene.getObjectByName("bhText").position.x(-5);
but this makes my entire scene go blank (black). So I tried variations of like
scene.getObjectByName("bhText").position.x = -5;
scene.getObjectByName("bhText").position.setX(-5);
scene.getObjectByName("bhText").position.setX = -5;
mesh.position.setX = -5;// I was pretty sure this wasn't going to work since I wasn't
//using the mesh name specifically for when it's inside something
//I can't reach because of parent-child relations
and again trying each of those with AND without
geometry.center();
but they all made my scene go black.
I just wanna move it down a couple of units. Sheesh.
Could anyone be kind enough to tell me WHERE in my code I can set the position of the text geometry? Thank you please.
I just wanna move it down a couple of units.
In this case use mesh.position.y = - 5;. Changing the x coordinate will move the mesh to the left or right. Here is a complete live example based on your code:
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set( 0, 0, 10 );
const renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
const pointLight = new THREE.PointLight(0xFFFFFF);
pointLight.position.set(5, 5, 5);
const ambientLight = new THREE.AmbientLight(0xFFFFFF);
scene.add(pointLight, ambientLight);
const loader = new THREE.FontLoader();
loader.load('https://threejs.org/examples/fonts/optimer_regular.typeface.json', function(font) {
const geometry = new THREE.TextGeometry('Buy Here!', {
font: font,
size: 2,
height: 0.5
});
geometry.center();
const material = new THREE.MeshLambertMaterial({
color: 0x686868
});
const mesh = new THREE.Mesh(geometry, material);
mesh.position.y = - 1; // FIX
mesh.name = "bhText"
scene.add(mesh);
renderer.render(scene, camera);
});
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.130.1/build/three.min.js"></script>
I want to render a scene using a WebGL renderer or a canvas renderer in three.js (version 69).
This is my code:
<!DOCTYPE html>
<html>
<head>
<script src="./libs/three.js"></script>
<script src="./libs/CanvasRenderer.js"></script>
<script src="./libs/Projector.js"></script>
<script src="./libs/dat.gui.js"></script>
</head>
<body>
<div id="renderer-output"></div>
<script type="text/javascript">
// global variables
var scene, camera, renderer;
var gui;
var config = {
rendererType: 'WebGL',
perspectiveCameraFOV: 45,
perspectiveCameraNear: 0.1,
perspectiveCameraFar: 1000,
cameraPosition_x: -30,
cameraPosition_y: 40,
cameraPosition_z: 30,
};
function init() {
// create the scene
scene = new THREE.Scene();
// create the camera
camera = new THREE.PerspectiveCamera(
config.perspectiveCameraFOV,
window.innerWidth / window.innerHeight,
config.perspectiveCameraNear,
config.perspectiveCameraFar
);
// set the position
camera.position.set(
config.cameraPosition_x,
config.cameraPosition_y,
config.cameraPosition_z
);
// set the look at
camera.lookAt(scene.position);
// create the renderer
if (config.rendererType == 'WebGL') {
renderer = new THREE.WebGLRenderer();
} else if (config.rendererType == 'canvas') {
renderer = new THREE.CanvasRenderer();
}
// set the size
renderer.setSize(window.innerWidth, window.innerHeight);
// add the output to the html element
document.getElementById("renderer-output").appendChild(renderer.domElement);
var boxGeometry = new THREE.BoxGeometry(4, 4, 4);
var boxMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
var box = new THREE.Mesh(boxGeometry, boxMaterial);
scene.add(box);
// create the dat gui
gui = new dat.GUI({
preset: config // preset default config
});
// remember config
gui.remember(config);
// add a renderer folder
let rendererFolder = gui.addFolder("Renderer");
rendererFolder.open();
// set control rendererType
let rendererTypeController = rendererFolder.add(
config,
"rendererType",
['WebGL', 'canvas']
);
rendererTypeController.onFinishChange(function (rendererType) {
// remove the renderer output from the html element
document.getElementById('renderer-output').removeChild(renderer.domElement);
// create the renderer
if (rendererType == 'WebGL') {
renderer = new THREE.WebGLRenderer();
} else {
renderer = new THREE.CanvasRenderer();
}
// set the size
renderer.setSize(window.innerWidth, innerHeight);
// add the output to the html element
document.getElementById('renderer-output').appendChild(renderer.domElement);
});
render();
}
function render() {
// update the scene
requestAnimationFrame(render);
renderer.render(scene, camera);
}
window.onload = init;
</script>
</body>
</html>
When I want to change the renderer type, the following lines are executed:
// remove the renderer output from the html element
document.getElementById('renderer-output').removeChild(renderer.domElement);
// create the renderer
if (rendererType == 'WebGL') {
renderer = new THREE.WebGLRenderer();
} else {
renderer = new THREE.CanvasRenderer();
}
// set the size
renderer.setSize(window.innerWidth, innerHeight);
// add the output to the html element
document.getElementById('renderer-output').appendChild(renderer.domElement);
But when I change the renderer from canvas to WebGL I can't see the objects in the scene. When I go from WebGL to canvas I can see it.
I don't get any error in console.
Do you have any advice ?
I can find a solution creating two variables to store the two different renderer types and calling them when I change the value of config.rendererTypes.
<!DOCTYPE html>
<html>
<head>
<script src="./libs/three.js"></script>
<script src="./libs/CanvasRenderer.js"></script>
<script src="./libs/Projector.js"></script>
<script src="./libs/dat.gui.js"></script>
</head>
<body>
<div id="renderer-output"></div>
<script type="text/javascript">
// global variables
var camera, scene;
var rendererWebGL, rendererCanvas;
var gui;
var config = {
rendererType: 'WebGL'
};
function init() {
// create the scene
scene = new THREE.Scene();
// create the camera
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
// set the position
camera.position.set(-30, 40, 30);
// set the look at
camera.lookAt(new THREE.Vector3(0, 0, 0));
// create the renderer
rendererWebGL = new THREE.WebGLRenderer();
rendererCanvas = new THREE.WebGLRenderer();
// set the sizeWebGLRenderer
rendererWebGL.setSize(window.innerWidth, window.innerHeight);
rendererCanvas.setSize(window.innerWidth, window.innerHeight);
// set the color
// rendererWebGL.setClearColor(0xEEEEEE);
// rendererCanvas.setClearColor(0xEEEEEE);
// add the output to the html element
if (config.rendererType == 'WebGL') {
document.getElementById("renderer-output").appendChild(rendererWebGL.domElement);
} else if (config.rendererType == 'canvas') {
document.getElementById("renderer-output").appendChild(rendererCanvas.domElement);
}
// add a box to the scene
var boxGeometry = new THREE.BoxGeometry(4, 4, 4);
var boxMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
scene.add(new THREE.Mesh(boxGeometry, boxMaterial));
// create the dat gui
gui = new dat.GUI({
preset: config
});
// remember config
gui.remember(config);
// add a renderer folder
let rendererFolder = gui.addFolder("Renderer");
// set folder open
rendererFolder.open();
// add a control rendererType
let rendererTypeController = rendererFolder.add(config, "rendererType", ['WebGL', 'canvas']);
// set the onFinishCange
rendererTypeController.onFinishChange(function (rendererType) {
// remove the renderer's domElement
var renderer_output = document.getElementById("renderer-output");
renderer_output.removeChild(renderer_output.children[0]);
// add the renderer-output
if (rendererType == 'WebGL') {
renderer_output.appendChild(rendererWebGL.domElement);
} else {
renderer_output.appendChild(rendererWebGL.domElement);
}
});
render();
}
function render() {
// update the scene
if (config.rendererType == 'WebGL') {
rendererWebGL.render(scene, camera);
} else if (config.rendererType == 'canvas') {
rendererCanvas.render(scene, camera);
}
requestAnimationFrame(render);
}
window.onload = init;
</script>
</body>
</html>
I have a pretty easy question for you with three.js about x position translation of an imported .obj mesh.
I'm fairly new to three.js and was wandering if someone could give me some lead on what to do or solve this problem.
So... I have this mesh on (0,-200,0) and i just wanted to move it to (50,-200,0) with a smooth translation through a button back and forth to the two positions.
objLoader = new THREE.OBJLoader();
objLoader.load('models/map_real.obj', function (obj) {
var blackMat = new THREE.MeshStandardMaterial({color:0xfaf9c9});
obj.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material = blackMat;
}
});
obj.castShadow = true;
obj.receiveShadow = true;
obj.position.set(0,-200,0)
obj.rotation.y = getDeg(-20);
scene.add(obj);
objWrap = obj;
});
I have in my main.js an init() which contains all the functions such as camera(), animate(), render() etc... and from the variable objWrap.position.x it logs the correct position.
I've tried to capture the click (as the snippet below shows) on my #test button and only increment the position by 0.5 - - i get this, is not in the animate loop so it cant keep add 0.5.
$('#test').click(function(){
if (objWrap.position.x <= 50) {
objWrap.position += 0.5}
});
So the final result that i want is a button that toggle back and forth a smooth animation that goes from objWrap.position.x = 0 to objWrap.position.x = 50
I hope to have been clear, feel free to ask if you need to know more, i'll respond in seconds... All the help is truly appreciate!
Just an example of how you can do it with Tween.js:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.setScalar(50);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
scene.add(new THREE.GridHelper(200, 100));
var box = new THREE.Mesh(new THREE.BoxGeometry(2, 2, 2), new THREE.MeshBasicMaterial({
color: "aqua"
}));
scene.add(box);
btnMove.addEventListener("click", onClick, false);
var forth = true;
function onClick() {
new TWEEN.Tween(box.position)
.to(box.position.clone().setX(forth ? 50 : 0), 1000)
.onStart(function() {
btnMove.disabled = true;
})
.onComplete(function() {
btnMove.disabled = false;
forth = !forth;
})
.start();
}
render();
function render() {
requestAnimationFrame(render);
TWEEN.update();
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/94/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.2.0/Tween.min.js"></script>
<button id="btnMove" style="position:absolute;">Move</button>
This works with ReactJS,
import TWEEN.
import {TWEEN} from "three/examples/jsm/libs/tween.module.min";
Enable drag controller and tween animation.
const { gl, camera } = useThree();
const objects = []; // objects.push(ref.current)
useEffect(() => {
const controls = new DragControls( objects, camera, gl.domElement );
controls.addEventListener( 'dragend', (e) => {
new TWEEN.Tween(e.object.position)
.to(new Vector3(x, y, z), 1000)
.easing(TWEEN.Easing.Back.InOut)
.start();
});
})
UseFrame to show the animation.
useFrame(() => {
TWEEN.update();
});
Hope to help someone.
I'm trying to load a model into my scene.
I've included these files at the top of my project:
<script src="js/build/three.min.js"></script>
<script src="js/loaders/OBJLoader.js"></script>
This is my code
var loader = new THREE.OBJLoader();
loader.load( "res/rose/ModelsAndTextures/rose.obj", function ( object ) {
scene.add( object );
} );
But I get error: OBJLoader.js:46 Uncaught TypeError: THREE.FileLoader is not a constructor(…)
I looked in the OBJLoader.js file and to find THREE.FileLoader - this is the line the error is on:
var loader = new THREE.FileLoader( scope.manager );
Other peoples examples of this work fine
Check out if you're using the right OBJLoader.js.
Take a look at an example that shows how to use this object properly:
var scene = new THREE.Scene();
var renderer, camera, banana;
var ww = window.innerWidth,
wh = window.innerHeight;
renderer = new THREE.WebGLRenderer({
canvas: document.getElementById('scene')
});
renderer.setSize(ww, wh);
camera = new THREE.PerspectiveCamera(50, ww / wh, 0.1, 10000);
camera.position.set(0, 0, 500);
scene.add(camera);
//Add a light in the scene
directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(0, 0, 350);
directionalLight.lookAt(new THREE.Vector3(0, 0, 0));
scene.add(directionalLight);
var render = function() {
requestAnimationFrame(render);
banana.rotation.z += .01;
renderer.render(scene, camera);
};
var loadOBJ = function() {
//Manager from ThreeJs to track a loader and its status
var manager = new THREE.LoadingManager();
//Loader for Obj from Three.js
var loader = new THREE.OBJLoader(manager);
//Launch loading of the obj file, addBananaInScene is the callback when it's ready
loader.load('http://mamboleoo.be/learnThree/demos/banana.obj', function(object) {
banana = object;
//Move the banana in the scene
banana.rotation.x = Math.PI / 2;
banana.position.y = -200;
banana.position.z = 50;
//Go through all children of the loaded object and search for a Mesh
object.traverse(function(child) {
//This allow us to check if the children is an instance of the Mesh constructor
if (child instanceof THREE.Mesh) {
child.material.color = new THREE.Color(0X00FF00);
//Sometimes there are some vertex normals missing in the .obj files, ThreeJs will compute them
child.geometry.computeVertexNormals();
}
});
scene.add(banana);
render();
});
};
loadOBJ();
<script src="http://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.min.js"></script>
<script src="http://mamboleoo.be/learnThree/demos/OBJLoader.js"></script>
<canvas id="scene"></canvas>
I had this issue and realized I used an old version of the three.js file. I replaced it with the three.js in the build folder of the three.js download where I took the OBJLoader from.