Three.js Mesh loads correctly but not showing - javascript

Im trying to apply Texture to my sphere using Three.js. I'm running a Python server.
Console prints Success! image-size: 1024 x 1024. Can't figure out what the problem is.
Main.js:
const scene = new THREE.Scene()
const geometry = new THREE.BoxGeometry(1, 1, 1)
const texture = texLoader.load('Fabric_Lace_026_height.png',
// On success
function(texture) {
console.log("Success!");
console.log(texture);
},
// Progress (ignored)
undefined,
// On error
function(err) {
console.log("Error");
console.log(err);}
);
const material = new THREE.MeshBasicMaterial({map: texture})
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)
const sizes = {width: window.innerWidth,height: window.innerHeight}
const camera = new THREE.PerspectiveCamera(75, sizes.width /sizes.height, 1, 1000)
camera.position.z = 3
const canvas = document.querySelector('canvas.webgl')
const renderer = new THREE.WebGLRenderer({canvas: canvas})
renderer.setSize(sizes.width, sizes.height)
renderer.render(scene, camera)

You are rendering your scene too early. Since you have no animation loop, you have to call render() when the texture is fully loaded. Try it like so:
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 3;
//
const loader = new THREE.TextureLoader();
const texture = loader.load('https://threejs.org/examples/textures/uv_grid_opengl.jpg',
// On success
function(texture) {
renderer.render(scene, camera); // FIX
},
// Progress (ignored)
undefined,
// On error
function(err) {
console.log(err);
}
);
//
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({map: texture});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
//
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
body {
margin: 0;
}
<script src="//cdn.rawgit.com/mrdoob/three.js/master/build/three.min.js"></script>

Related

Three.js not showing textures when deploying website

I am working on my first website design project and I am trying to load a texture for the background as space and a moon texture. However, when I deploy my website it does not show the added texture but will have the geometry.
Here is the link to the git repo: Git Repo
and the link to the actual website: Website Link
The black figures are the shapes that should have the meshes.
import './style.css';
import * as THREE from 'three';
import {
OrbitControls
} from 'three/examples/jsm/controls/OrbitControls';
// Setup
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector('#bg'),
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
camera.position.setZ(30);
camera.position.setX(-3);
renderer.render(scene, camera);
// Torus
const geometry = new THREE.TorusGeometry(10, 3, 16, 100);
const material = new THREE.MeshStandardMaterial({
color: 0xff6347
});
const torus = new THREE.Mesh(geometry, material);
scene.add(torus);
// Lights
const pointLight = new THREE.PointLight(0xffffff);
pointLight.position.set(5, 5, 5);
const ambientLight = new THREE.AmbientLight(0xffffff);
scene.add(pointLight, ambientLight);
// Helpers
const lightHelper = new THREE.PointLightHelper(pointLight)
const gridHelper = new THREE.GridHelper(200, 50);
scene.add(lightHelper, gridHelper)
// const controls = new OrbitControls(camera, renderer.domElement);
function addStar() {
const geometry = new THREE.SphereGeometry(0.25, 24, 24);
const material = new THREE.MeshStandardMaterial({
color: 0xffffff
});
const star = new THREE.Mesh(geometry, material);
const [x, y, z] = Array(3)
.fill()
.map(() => THREE.MathUtils.randFloatSpread(100));
star.position.set(x, y, z);
scene.add(star);
}
Array(200).fill().forEach(addStar);
// Background
const spaceTexture = new THREE.TextureLoader().load('space.jpg');
scene.background = spaceTexture;
// Avatar
const jeffTexture = new THREE.TextureLoader().load('jeff.png');
const jeff = new THREE.Mesh(new THREE.BoxGeometry(3, 3, 3), new THREE.MeshBasicMaterial({
map: jeffTexture
}));
scene.add(jeff);
// Moon
const moonTexture = new THREE.TextureLoader().load('moon.jpg');
const normalTexture = new THREE.TextureLoader().load('normal.jpg');
const moon = new THREE.Mesh(
new THREE.SphereGeometry(3, 32, 32),
new THREE.MeshStandardMaterial({
map: moonTexture,
normalMap: normalTexture,
})
);
scene.add(moon);
moon.position.z = 5;
moon.position.setX(-10);
jeff.position.z = -5;
jeff.position.x = 2;
// Scroll Animation
function moveCamera() {
const t = document.body.getBoundingClientRect().top;
moon.rotation.x += 0.05;
moon.rotation.y += 0.075;
moon.rotation.z += 0.05;
jeff.rotation.y += 0.01;
jeff.rotation.z += 0.01;
camera.position.z = t * -0.01;
camera.position.x = t * -0.0002;
camera.rotation.y = t * -0.0002;
}
document.body.onscroll = moveCamera;
moveCamera();
// Animation Loop
function animate() {
requestAnimationFrame(animate);
torus.rotation.x += 0.01;
torus.rotation.y += 0.005;
torus.rotation.z += 0.01;
moon.rotation.x += 0.005;
// controls.update();
renderer.render(scene, camera);
}
animate();
I was expecting the background and the texture of a sphere to be space and the moon respectively but they are not loading for some reason.

I've written code that takes geojson array and translates it into Vector3, but it isn't showing up

The plan is for it to draw borders using GeoJSON coords. Also when I write coordinates directly into the same file it works normally and I've noticed that my fbih variable doesn't get the fbih: THREE.Vector3 when hovered over. I'm using ViteJS + ThreeJS, Here's the code:
import './style.css'
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { Vector3 } from 'three';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector("#bg")
});
renderer.setPixelRatio (window.devicePixelRatio);
renderer.setSize( window.innerWidth, window.innerHeight);
camera.position.setZ(20);
renderer.render(scene,camera);
const teksturazemlje = new THREE.TextureLoader().load('slike/zemlja.png')
const zemlja = new THREE.Mesh (
new THREE.SphereGeometry(16, 500, 500 ),
new THREE.MeshStandardMaterial({
map:teksturazemlje,
})
);
scene.add(zemlja)
function koordinate([lon,lat]){
var phi = (90-lat)*(Math.PI/180);
var theta = (lon+180)*(Math.PI/180);
var x = -((16) * Math.sin(phi)*Math.cos(theta));
var z = ((16) * Math.sin(phi)*Math.sin(theta));
var y = ((16) * Math.cos(phi));
return new THREE.Vector3(x,y,z)
}
const boja = new THREE.MeshBasicMaterial({
color: 0xff00cc,
side : THREE.DoubleSide,
});
var fbih = [];
fetch ('granice/bih.json')
.then (res => res.json())
.then (data => {
for (let element of data.features[0].geometry.coordinates[0][0]) {
fbih.push(koordinate(element))
}
});
console.log(fbih)
const linije = new THREE.BufferGeometry().setFromPoints(fbih)
const line = new THREE.Line(linije,boja)
scene.add(line);
const ambientlight= new THREE.AmbientLight(0xffffff);
scene.add(ambientlight)
const controls = new OrbitControls(camera, renderer.domElement);
function animate(){
requestAnimationFrame(animate);
controls.update();
renderer.render (scene, camera);
}
controls.enableDamping = true;
controls.dampingFactor = 0.04;
controls.rotateSpeed = 0.07;
controls.maxDistance = 20;
controls.minDistance = 16.5;
controls.enablePan = false;
controls.zoomSpeed = 0.30;
animate()
It displays Vector3 array in console.log but it isn't displayed through BufferGeometry. Sorry if there are grammatical errors, English isn't my first language.

Make Image to Particles with Three JS in Next JS

now im learning about Three JS and now im in blocker that my expectation should be like this:
but now my code not shows any view, where my code was like this:
import { useEffect } from "react/cjs/react.development";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
export default () => {
useEffect(() => {
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
1,
1000
);
const canvas = document.querySelector("canvas.background");
let renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
new OrbitControls(camera, renderer.domElement);
const img = new Image();
let texture = new THREE.Texture(img);
img.onload = () => {
texture.needsUpdate = true;
const material = new THREE.PointsMaterial({
size: 20,
map: texture,
blending: THREE.AdditiveBlending,
transparent: true,
depthTest: false,
});
const particle = new THREE.Sprite(material);
particle.scale.x = particle.scale.y = 1;
scene.add(particle);
};
img.src = "/flower.png";
scene.add(camera);
camera.position.z = 3;
const animate = () => {
const elapsedTime = new THREE.Clock().getElapsedTime();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.render(scene, camera);
requestAnimationFrame(animate);
};
animate();
}, []);
return <canvas className="background" />;
};
I tried different answers from forum, but seems doesn't works for me
could you guys help? I'll appreciate
You can't use THREE.PointsMaterial with THREE.Sprite. THREE.PointsMaterial is intended for THREE.Points. Use THREE.SpriteMaterial instead.

Why I get a black model when I load a GLTF model which have materials?

I m trying to load my 3d model which have glb format.
Here's the code:
What I exept:
Image
What I have: Image
var renderer = new THREE.WebGLRenderer();
renderer.setSize(1000, 1000);
renderer.setPixelRatio(window.devicePixelRatio);
const camera = new THREE.PerspectiveCamera(75, 1000 / 1000, 0.1, 1000)
camera.position.z = 0.5;
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
scene.background = new THREE.Color('white');
const gltfLoader = new THREE.GLTFLoader();
const url = 'hub.glb';
gltfLoader.load(url, (gltf) => {
const root = gltf.scene;
scene.add(root);
});
var render = () => {
requestAnimationFrame(this.render);
renderer.render(scene, camera);
}
render();
When I check the variables, the color material is set and correct.
Here's the variable explorer: Image
Thank you !
Try adding some lights to your scene:
const ambientLight = new THREE.AmbientLight( 0xffffff, 0.4 );
scene.add( ambientLight );
const dirLight = new THREE.DirectionalLight( 0xefefff, 1.5 );
dirLight.position.set( 10, 10, 10 );
scene.add( dirLight );
Besides, when loading glTF assets you should configure the output encoding of the renderer like so:
renderer.outputEncoding = THREE.sRGBEncoding;

How to animate the gltf model with threejs

I have a cube model which is GLTF format, now i am trying to animate it by changing the textures material.
Now currently, there are 300 heat map images as the texture material, the requirement from supervisor is animating the cube model by loading heat map images one by one.
Texture materials set
About the animation, I tried to use VectorKeyFrameTrack to change the child.material. But it does not work.
the codes:
if (WEBGL.isWebGLAvailable() === false) {
document.body.appendChild(WEBGL.getWebGLErrorMessage());
}
var camera, scene, renderer;
init();
function init() {
//init scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0x999999);
//add directional light and spotlight
var light = new THREE.DirectionalLight(0xffffff);
light.position.set(3, 15.0, -29).normalize();
scene.add(light);
var light1 = new THREE.DirectionalLight(0xffffff);
light.position.set(-20, 7.0, -2).normalize();
scene.add(light1);
var light2 = new THREE.DirectionalLight(0xffffff);
light.position.set(-5, 15.0, 30).normalize();
scene.add(light2);
var light3 = new THREE.DirectionalLight(0xffffff);
light.position.set(15, 5.0, -15).normalize();
scene.add(light3);
//add camera
camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 500);
camera.position.y = 5;
camera.position.z = 10;
scene.add(camera);
//add grid
var grid = new THREE.GridHelper(50, 50, 0xffffff, 0x555555);
scene.add(grid);
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//Generate textures array
var loadedTexture = new THREE.TextureLoader().load("1.png");
var material = new THREE.MeshBasicMaterial({map: loadedTexture});
var loadedTexture2 = new THREE.TextureLoader().load("2.png");
var material1 = new THREE.MeshBasicMaterial({map: loadedTexture2});
//Load Collada file
var path = "./image/"
var format = ".png";
var a = "Avg_Displacement_";
var material_list = [];
var times = [];
for (var i = 0; i <= 314; i++) {
var loadedTexture = new THREE.TextureLoader().load(path + a + i + format);
var material = new THREE.MeshBasicMaterial({map: loadedTexture});
material_list.push(material);
times.push(i);
}
console.log(material_list);
var loader = new THREE.GLTFLoader();
loader.load('scene.gltf', function (gltf) {
gltf.scene.scale.set(0.3, 0.3, 0.3);
// console.log(gltf.scene.children[0].material);
// var kf = new THREE.VectorKeyframeTrack( '.scene.material', times, material_list );
// var clip = new THREE.AnimationClip('Action', 315, [kf]);
//
// mixer = new THREE.AnimationMixer(gltf);
// var clipAction = mixer.clipAction(clip);
// clipAction.play();
gltf.scene.traverse(function (child) {
if (child.isMesh) {
var kf = new THREE.VectorKeyframeTrack('child.material', times, material_list);
var clip = new THREE.AnimationClip('Action', 3, [kf]);
mixer = new THREE.AnimationMixer(child);
var clipAction = mixer.clipAction(clip);
clipAction.play()
// child.material = material;
}
scene.add(gltf.scene);
});
});
var controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.addEventListener('change', render);
controls.update();
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
render();
}
function render() {
renderer.render(scene, camera);
}
// function animate() {
//
// requestAnimationFrame( animate );
//
// mesh.material.map.offset.x += 0.005;
// mesh.material.map.offset.y += 0.005;
//
// renderer.render( scene, camera );
//
// }
child.material
the second problem is how to animate the model by loading each image as the texture as material.

Categories

Resources