So, I have been using rollup to bundle my js files, created for usage with three js. What I thought of is to minimize and bundle the three js files using rollup js.
I used npm and installed three and rollup using the command npm install rollup three.
The index.js file as created is:
import { Scene, PerspectiveCamera, WebGLRenderer } from 'three'
const scene = new Scene()
const camera = new PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10)
camera.position.z = 1
geometry = new BoxGeometry( 0.2, 0.2, 0.2 )
material = new MeshNormalMaterial()
mesh = new THREE.Mesh( geometry, material )
const basic = basicScene()
scene.add( mesh )
const renderer = new WebGLRenderer({antialias: true})
renderer.setSize( window.innerWidth, window.innerHeight )
document.body.appendChild( renderer.domElement )
function animate() {
requestAnimationFrame(animate)
mesh.rotation.x += 0.01
mesh.rotation.y += 0.01
renderer.render( scene, camera )
}
animate()
The rollup config as used is rollup.config.js:
export default [{
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'cjs'
}
}]
The final bundle.js file as generated after running rollup --config is:
'use strict';var three=require('three');const scene = new three.Scene();
const camera = new three.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10);
camera.position.z = 1;
geometry = new BoxGeometry( 0.2, 0.2, 0.2 );
material = new MeshNormalMaterial();
mesh = new THREE.Mesh( geometry, material );
const basic = basicScene();
scene.add( mesh );
const renderer = new three.WebGLRenderer({antialias: true});
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.01;
renderer.render( scene, camera );
}
animate();
I have the following doubts with the given bundle.js file that is generated:
1. The bundle js as created uses require, which results in ReferenceError: require is not defined for rollup
2. Secondly, not sure why the bundled version is not really the complete minified version of the produced js file?
Great, if some could suggest the probable issue?
There is actually a minimal sample project if you use the npm version of three.js and build your project via rollup. It demonstrates all the bits which are necessary for a proper setup:
https://github.com/Mugen87/three-jsm
A few comments to your question:
It seems you are not importing all classes from the three package. For example BoxGeometry or MeshNormalMaterial are missing.
Besides, you are referring to the Mesh class over the THREE namespace which is obviously wrong.
When importing npm packages, rollup requires the usage of #rollup/plugin-node-resolve.
Minifying does not happen automatically. You need to use a separate plugin for this e.g. rollup-plugin-terser.
Except for the last point, the mentioned sample project implements all above steps which are necessary for a proper build.
Related
I've got a gltf file. When I import it inside the Three.js editor (https://threejs.org/editor/) I get a correct result when I add an environment map.
On the other hand, when I import my gltf in my project scene I've a different result. Even when I use the very same HDRI image. The metalness is way too shinny in this case.
Does anyone know what I'm missing? Thank you.
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1;
renderer.outputEncoding = THREE.sRGBEncoding;
new RGBELoader()
.load( 'royal_esplanade_1k.hdr', function ( texture ) {
texture.mapping = THREE.EquirectangularReflectionMapping;
scene.environment = texture;
} );
loader.load(
'./gltf/canette.glb',
// called when the resource is loaded
function ( gltf ) {
obj = gltf.scene;
mixer = new THREE.AnimationMixer( gltf.scene );
action = mixer.clipAction( gltf.animations[ 0 ] );
//obj
scene.add( obj );
}
);
EDIT :
Here's a live demo.
Here's the gltf model.
Unfortunately, you are using a code snippet which does not match your actual three.js version. You have to use at least r131 (or better the latest one r141). Right now, you are using r129.
If you use three.js versions below r131, you have to use PMREMGenerator to prepare the environment map that you apply to PBR materials. Starting from r131, the engine is doing this for you so you don't have to worry about PMREMGenerator at all.
I'm trying to get a basic GlitchPass to work in a Three js demo, but I can't get past Uncaught TypeError: Cannot read property 'prototype' of undefined at ShaderPass.js.
For this demo I'm not using files from the jsm directory...just the ones from js. These are the files I'm including.
<script src="~/lib/three/CopyShader.js"></script>
<script src="~/lib/three/ShaderPass.js"></script>
<script src="~/lib/three/EffectComposer.js"></script>
<script src="~/lib/three/RenderPass.js"></script>
<script src="~/lib/three/GlitchPass.js"></script>
I've included CopyShader and ShaderPass because without them the EffectComposer throws "THREE.EffectComposer relies on THREE.CopyShader" and "THREE.EffectComposer relies on THREE.ShaderPass".
<script>
const hologram = document.querySelector('.hologram');
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, innerWidth / innerHeight, 0.1, 1000);
camera.position.set(0, 0, 100);
const renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.setSize(innerWidth, innerHeight);
hologram.appendChild(renderer.domElement);
const shader = new THREE.ShaderPass(THREE.CopyShader);
const composer = new THREE.EffectComposer(renderer);
const renderPass = new THREE.RenderPass(scene, camera);
composer.addPass(renderPass);
const glitchPass = new GlitchPass();
composer.addPass(glitchPass);
// rendering things here
function animate() {
camera.updateProjectionMatrix();
composer.render();
requestAnimationFrame(animate);
}
animate();
</script>
What am I missing here?
Change the order of imports. Pass is defined in EffectComposer.
<script src="~/lib/three/EffectComposer.js"></script>
<script src="~/lib/three/ShaderPass.js"></script>
BTW: This is a good example for one advantages of using ES6 modules. Compared to global scripts, such dependencies are automatically managed by the module system.
I'm trying to set up a very simple scene with Three.js, showing an imported mesh rotating. I combined a couple of the examples from the Three.js documentation and arrived at the following code:
var scene, camera, renderer;
var geometry, material, mesh;
init();
animate();
function init(){
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 1000;
// geometry = new THREE.BoxGeometry(200, 200, 200);
var jsonLoader = new THREE.JSONLoader();
jsonLoader.load('handgun.js', object_to_scene(geometry, material));
}
function object_to_scene(geometry, material){
material = new THREE.MeshBasicMaterial({
color: 0xff0000,
wireframe: true
});
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
function animate(){
requestAnimationFrame(animate);
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.02;
renderer.render(scene, camera);
}
You can see the original example commented out in the above, where we generated a Box using Three.js. That worked fine. However, importing the JSON file of the custom 3D model isn't working. Checking my console reveals the following error:
TypeError: onLoad is not a function three.js:18294:4
THREE.JSONLoader.prototype.load/<() three.js:18294
THREE.XHRLoader.prototype.load/<() three.js:18010
This appears to be an error with Three.js itself, however I've found only two instances of people reporting it on the Github account, and both were told that the Github was for reporting bugs, not asking for help (if this isn't a bug, then what is it?).
Has anyone else encountered this issue, and if you have resolved it, how did you do so?
Thanks!
Instead of
jsonLoader.load( 'handgun.js', object_to_scene( geometry, material ) );
You need to do this:
jsonLoader.load( 'handgun.js', object_to_scene );
object_to_scene( geometry, material ) is a function call that, in your case, returns undefined.
three.js r.75
I've exported a simplistic blender model I made earlier with the plugin provided by three.js, which created a .json file. I then tried to import that file into my project, but am having no success at all.
I have it on a local server, because of file transfers not being allowed through file://, therefore, I'm using HTTP.
The issue is that I cannot see the model. I'm using the following code to import it:
var loader = new THREE.JSONLoader();
loader.load( 'model/mountain.json', function ( geometry ) {
var mesh = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial() );
scene.add( mesh );
});
I have both camera and scenes setup properly because I can create and add native three.js shapes, such as boxes and plains, and I'm 100% sure the file is in the correct place.
I asked on reddit, and /u/Egenimo helped me with the answer!
Here's the whole code, as I figure it might help people who need to set up a scene aswell.
var canvas = document.getElementById("bgcanvas"),
renderer = new THREE.WebGLRenderer({ canvas: canvas, alpha: true }),
windowHeight = window.innerHeight,
windowWidth = window.innerWidth,
camera, scene, renderer, loader;
init();
function init() {
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x000000, 0);
renderer.shadowMapEnabled = true;
renderer.shadowMapType = THREE.PCFSoftShadowMap;
document.body.appendChild(renderer.domElement);
// camera
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 5;
// scene
scene = new THREE.Scene();
loader = new THREE.JSONLoader();
loader.load( 'cube.json', function ( geometry ) {
var mesh = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial({overdraw: true}));
scene.add( mesh );
});
console.log(scene.children.length);
render();
}
function render() {
requestAnimationFrame(function() {
render();
});
renderer.render(scene, camera);
}
I then ran into the issue of having a more complex model, with several objects, and ThreeJS would only import a single one, therefore, after looking it up, I found this answer by the Man himself!.
Hope this helps someone in need!
I am new to Three.JS and am trying to load a load a very simple (single cube) Sketchup model into Three.JS via the ColladaLoader, I get no errors but nothing is displayed:
var renderer = new THREE.WebGLRenderer();
var loader = new THREE.ColladaLoader();
var scene = new THREE.Scene();
var camera = new THREE.Camera();
loader.load('Test.dae', function (result) {
scene.add(result.scene);
});
camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set(0, 0, 5);
scene.add(camera);
renderer.render(scene,camera);
Can anyone spot any immediate errors? Thanks
Fixed. Whilst I had declared the renderer, I hadn't attached it to the document. The following code works:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(100, window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera.position.set(0, 0, 4);
var loader = new THREE.ColladaLoader();
loader.load("test.dae", function (result) {
scene.add(result.scene);
});
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
render();
You need to rerender the scene after the collada is loaded. Something like
loader.load('Test.dae', function (result) {
scene.add(result.scene);
renderer.render(scene,camera);
});
Additionally:
The camera might be inside your geometry. Faces are one-sided by default, they are invisible when looking from back/inside. You could try changing the camera or object location and/or set material.side = THREE.DoubleSide so the faces are visible from both front and back.
The scale of the model can be way off, so it can be too small or large to show. Try different camera positions (eg. z= -1000, -100, -10, -1, 1, 10, 100, 1000) and use lookAt() to point it to 0,0,0 or, I think colladaloader has a scale setting nowadays, not sure.
Loader defaults to position 0,0,0, so center of the world/scene. That doesn't necessarily mean center of screen, depends on camera. In some cases the Collada model itself can be such that the center is away from visible objects, so when it's placed on the scene it can be effectively "off-center". That's quite unlikely though.
You dont have any lights in the scene.
loader.load('test.dae', function colladaReady(collada) {
localObject = collada.scene;
localObject.scale.x = localObject.scale.y = localObject.scale.z = 2;
localObject.updateMatrix();
scene.add(localObject);
I think you need to add the object in the collada scene, or there might be problem with the scaling of the object that you are adding, scale it and than update the matrix of the object.
If your still having trouble it may be that some versions of IE stop you downloading local files (your Test.dae) so it may be worth trying it using firefox or putting your code up on a server.