I have to make rotation for my Mesh in render. For this I have to see my mesh globally. I create Mesh form object loader (json). So, I it just inside call back function. And when I try to create var with object before the function and then to give value of function it doesn't work.
How I can make my Mesh globally?
var material = new THREE.MeshBasicMaterial({ map: earthTexture });
let objectLoader = new THREE.BufferGeometryLoader();
objectLoader.load('geometry.json',
function (geometry) {
var object = new THREE.Mesh(geometry, material);
scene.add(object);
});
I served it , I created var objectWrapper = new THREE.Object3D(); in which i put my Object
Use a global variable and assign its value in the callback function, then just check if the variable is not undefined:
var obj; // define this variable in the section - let camera, scene, renderer;
. . .
var material = new THREE.MeshBasicMaterial({ map: earthTexture });
let objectLoader = new THREE.BufferGeometryLoader();
objectLoader.load('geometry.json',
function (geometry) {
var obj = new THREE.Mesh(geometry, material);
scene.add(obj);
});
...
// somewhere in your animation loop
if (obj) obj.rotation.y += 0.1;
Related
I'm trying to attach a custom image to an object (.obj)
What I want is
But the result is
I want the image to be located in the center of the object for only one time. But the image is repeated to fill the entire material.
I googled a lot and read some articles about uv mapping but I could not figure out how to apply to a custom object.
Following is my code. Thanks in advance.
var mtlLoader = new MTLLoader();
mtlLoader.load("~~~.mtl", function (materials) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.load(
"~~.obj",
function (geometry) {
var textureLoader = new THREE.TextureLoader();
var texture = textureLoader.load("~~.jpg");
var material = new THREE.MeshLambertMaterial({
transparent: true,
map: texture, // <- ??
});
texture.minFilter = THREE.LinearFilter;
texture.wrapS = texture.wrapT = THREE.ClampToEdgeWrapping;
geometry.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material = material;
}
});
scene.add(geometry);
}
I have a GLTF version 1.0 model that I am importing into Three.js using LegacyGLTFLoader.js. When I do so, everything looks good, except that the model does not receive shadows. I am guessing that this is because the imported model's material is THREE.RawShaderMaterial, which does not support receiving shadows (I think). How can I fix this so that my imported model can receive shadows?
Here is sample code:
// Construct scene.
var scene = new THREE.Scene();
// Get window dimensions.
var width = window.innerWidth;
var height = window.innerHeight;
// Construct camera.
var camera = new THREE.PerspectiveCamera(75, width/height);
camera.position.set(20, 20, 20);
camera.lookAt(scene.position);
// Construct renderer.
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
renderer.shadowMapEnabled = true;
document.body.appendChild(renderer.domElement);
// Construct cube.
var cubeGeometry = new THREE.BoxGeometry(10, 1, 10);
var cubeMaterial = new THREE.MeshPhongMaterial({color: 0x00ff00});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.castShadow = true;
cube.translateY(15);
scene.add(cube);
// Construct floor.
var floorGeometry = new THREE.BoxGeometry(20, 1, 20);
var floorMaterial = new THREE.MeshPhongMaterial({color: 0x00ffff});
var floor = new THREE.Mesh(floorGeometry, floorMaterial);
floor.receiveShadow = true;
scene.add(floor);
// Construct light.
var light = new THREE.DirectionalLight(0xffffff);
light.position.set(0, 20, 0);
light.castShadow = true;
scene.add(light);
// Construct light helper.
var lightHelper = new THREE.DirectionalLightHelper(light);
scene.add(lightHelper);
// Construct orbit controls.
new THREE.OrbitControls(camera, renderer.domElement);
// Construct GLTF loader.
var loader = new THREE.LegacyGLTFLoader();
// Load GLTF model.
loader.load(
"https://dl.dropboxusercontent.com/s/5piiujui3sdiaj3/1.glb",
function(event) {
var model = event.scene.children[0];
var mesh = model.children[0];
mesh.receiveShadow = true;
scene.add(model);
},
null,
function(event) {
alert("Loading model failed.");
}
);
// Animates the scene.
var animate = function () {
requestAnimationFrame(animate);
renderer.render(scene, camera);
};
// Animate the scene.
animate();
Here are my resources:
https://dl.dropboxusercontent.com/s/y2r8bsrppv0oqp4/three.js
https://dl.dropboxusercontent.com/s/5wh92lnsxz2ge1e/LegacyGLTFLoader.js
https://dl.dropboxusercontent.com/s/1jygy1eavetnp0d/OrbitControls.js
https://dl.dropboxusercontent.com/s/5piiujui3sdiaj3/1.glb
Here is a JSFiddle:
https://jsfiddle.net/rmilbert/8tqc3yx4/26/
One way to fix the problem is to replace the instance of RawShaderMaterial with MeshStandardMaterial. To get the intended effect, you have to apply the existing texture to the new material like so:
var newMaterial = new THREE.MeshStandardMaterial( { roughness: 1, metalness: 0 } );
newMaterial.map = child.material.uniforms.u_tex.value;
You also have to compute normal data for the respective geometry so lighting can be computed correctly. If you need no shadows, the unlint MeshBasicMaterial is actually the better choice.
Updated fiddle: https://jsfiddle.net/e67hbj1q/2/
I want to load a 3D model and create the wireframe in threejs. How may I achieve this effect? Thank you very much.
This is the code I have for now, but it doesn't work.
var loader = new THREE.GLTFLoader();
loader.load('name.gltf', function(geometry, materials) {
var material = new THREE.MeshLambertMaterial();
var mesh = new THREE.Mesh(geometry, material);
group = new THREE.Object3D();
group.add(mesh);
scene.add(group);
});
According to the GLTFLoader docs, the callback's argument is an object with a .scene property containing your model. Like any nested three.js object, you can modify materials using .traverse().
var loader = new THREE.GLTFLoader();
loader.load('name.gltf', function(gltf) {
var object = gltf.scene;
object.traverse((node) => {
if (!node.isMesh) return;
node.material.wireframe = true;
});
scene.add(object);
});
var material = new THREE.MeshLambertMaterial({wireframe:true});
Hey guys basically I have a crude scene set up. I was finally able to load to a 3D model of a sports car into my scene.
I can animate an Object3D primitive with for example sphere.translateY(1).
I for the death of me cannot figure out how to do a similar translation animation on my car model. First it said car variable not found when I made a global for it, then I tried passing car into animate function to no avail.
I'm sure translateY only works on Object3D like sphere, so how do i do this simple translate on an imported 3d model? I tried incrementing position. Here is my code someone please help! (I ommitted camera and render code etc, it all works just need to animate this car!
var sphere;
var car;
function init() {
// THE USUAL STUFF, scene, camera, renderer
}
function addSceneElements() {
// Sphere
sphere = new THREE.Mesh(new THREE.SphereGeometry(8, 70, 20), blueMat);
sphere.position.set(-260, 9, 125);
scene.add(sphere);
var loader = new THREE.JSONLoader();
loader.load( "models/hotride.js", function(geometry){
var material = new THREE.MeshLambertMaterial({color: 0x66CCFF});
var car = new THREE.Mesh(geometry, material);
car.scale.set(7,7,7);
car.position.set(10, 22, -1000);
scene.add(car);
animate();
});
}
function animate() {
sphere.translateX(1);
//car.translateZ(2);
// car.position.z += clock.getDelta();
// render
renderer.render(scene, camera);
requestAnimationFrame( animate );
controls.update();
}
You have a global var car and a local var car
var car;
function init() {
// THE USUAL STUFF, scene, camera, renderer
}
function addSceneElements() {
// Sphere
sphere = new THREE.Mesh(new THREE.SphereGeometry(8, 70, 20), blueMat);
sphere.position.set(-260, 9, 125);
scene.add(sphere);
var loader = new THREE.JSONLoader();
loader.load( "models/hotride.js", function(geometry){
var material = new THREE.MeshLambertMaterial({color: 0x66CCFF});
var car = new THREE.Mesh(geometry, material); //// <<<< local var !!!
That means that the global car won't have the mesh assigned to the local car. Just remove var in the line !
car = new THREE.Mesh(geometry, material); //// <<<< global var !!!
You can add your model in a new Object3D, and manipulate this object for translation/rotation.
hii i am trying to get a sphree to render into the screen. here is my js file.
function Earth()
{
this.getEarth = init();
function init()
{
var map = {map:THREE.ImageUtils.loadTexture("images/earth_surface_2048.jpg")};
var material = new THREE.MeshBasicMaterial(map);
var geometry = new THREE.SphereGeometry(1,32,32);
return new THREE.Mesh(geometry, material);
}
function update()
{
getEarth.rotation.x += .01;
}
}
and here is the script that is in the html file
threejs is included to the page.
<script>
var renderer = null;
var scene = null;
var camera = null;
var mesh = null;
var earth = null;
$(document).ready(
function() {
var container = document.getElementById("container");
renderer = new THREE.WebGLRenderer({ antialias: true } );
renderer.setSize(container.offsetWidth,container.offsetHeight);
container.appendChild(renderer.domElement)
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 45,
container.offsetWidth / container.offsetHeight, 1, 4000 );
earth = new Earth();
scene.add(camera);
scene.add(earth.getEarth);
renderer.render( scene, camera );
}
);
</script>
i get no erros from the debugger, so any ideas ?
earth.getEarth is probably null or a function. I remember scene.add() silently ignoring stuff it can't take, like undefined values and so on.
How about changing var getEarth = init(); to this.getEarth = init(); so that code outside of your class scope will see that variable in your earth object. Althought I would advice against using a method-like name for a variable containing an object.