Three.js not showing textures when deploying website - javascript

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.

Related

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.

I have added the GUI code in my three js file but it's not working not raising any error either

I added the gui code in the in my code as it was shown in the github repo of mrdoob. It is not raising any error and it is not showing up in the page, i'm new to three js.
import * as THREE from './js/three.module.js';
import { GUI } from './js/dat.gui.module.js';
import { OrbitControls } from './js/OrbitControls.js';
import Stats from './js/stats.module.js';
import {
createPlaneLambertMaterial,
createCubeLambertMaterial,
createSphereLambertMaterial,
} from './basics-geometry.js';
import { createSpotlight } from './light.js';
import axesHelper from './helper.js';
function init() {
var scene = new THREE.Scene();
const fov = 45; // AKA Field of View
const aspect = window.innerWidth / window.innerHeight;
const near = 0.1; // the near clipping plane
const far = 1000;
var camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.x = -30;
camera.position.y = 40;
camera.position.z = 30;
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0xeeeeee, 1.0));
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
var controls = new OrbitControls(camera, renderer.domElement);
// x - red , y - green, z - blue axis lines
scene.add(axesHelper(20));
// Shape Geometry
const plane = createPlaneLambertMaterial({ receiveShadow: true });
scene.add(plane);
const cube = createCubeLambertMaterial({ castShadow: true });
scene.add(cube);
const sphere = createSphereLambertMaterial({ castShadow: true });
scene.add(sphere);
// Light
createSpotlight({ scene: scene, x: -40, y: 60, z: -10, castShadow: true });
controls.enableDamping = true;
// controls.autoRotate = true;
controls.update();
var stats = new Stats();
stats.showPanel(0); // 0: fps, 1: ms, 2: mb, 3+: custom
document.body.appendChild(stats.dom);
var helper = new THREE.GridHelper(2000, 100);
helper.position.y = -199;
helper.material.opacity = 0.25;
helper.material.transparent = true;
scene.add(helper);
let step = 0;
let rSpeed = 0;
// GUI
var params = new function () {
this.rotationSpeed = 0.02;
this.bouncingSpeed = 0.03;
};
var gui = new GUI();
gui.add(params, 'rotationSpeed', 0, 0.5);
gui.add(params, 'bouncingSpeed', 0, 0.5);
gui.open();
function render() {
stats.update();
controls.update();
step += params.bouncingSpeed;
rSpeed = params.rotationSpeed;
cube.rotation.x += rSpeed;
cube.rotation.y += rSpeed;
cube.rotation.z += rSpeed;
sphere.position.x = 20 + 10 * Math.cos(step);
sphere.position.y = 2 + 10 * Math.abs(Math.sin(step));
requestAnimationFrame(render);
renderer.render(scene, camera);
}
render();
document.getElementById('c').appendChild(renderer.domElement);
}
window.onload = init;
Github repo for the whole code
you have to add the gui domElement to the webpage
document.getElementById('gui').appendChild(gui.domElement);

How to animate objects different with three.js

I just wanted to create a very simple scene with 2 different objects that move
differently.
But my sphere isnt moving at all.
When I change the line:
scene.add(obj2)
to:
obj.add(obj2)
the sphere is moving exactly as the box
what can I change to just let the sphere rotate?
//set up the scene
const scene = new THREE.Scene();
const renderer = new THREE.WebGLRenderer();
const camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 0.1, 1000);
const light = new THREE.DirectionalLight();
scene.background = new THREE.Color("white");
renderer.setSize((3 * window.innerWidth) / 4, (3 * window.innerHeight) / 4);
document.body.appendChild(renderer.domElement);
camera.position.z = 17;
light.position.set(-1, 1, 1);
//-----GEOMETRY VARIABLES------//
let box = new THREE.BoxGeometry(1, 1, 1);
let sphere = new THREE.SphereGeometry(0.5, 32, 32);
//-----MATERIAL VARIABLES------//
let phong = new THREE.MeshPhongMaterial({
color: "pink",
emissive: 0,
specular: 0x070707,
shininess: 100,
});
//-----FUNCTIONALITY------//
//make the objects and add them to the scene
let obj, currentShape, currentMesh, obj2;
currentShape = box;
currentMesh = phong;
obj = new THREE.Mesh(currentShape, currentMesh);
scene.add(light);
scene.add(obj);
obj2 = new THREE.Mesh(sphere, currentMesh);
obj2.position.set(3, 0, 0);
scene.add(obj2);
//methods for making the objects move
let up = true;
function animate() {
requestAnimationFrame(animate);
obj.rotation.y += 0.01;
obj2.rotation.x += 0.02;
if (up) {
obj.translateOnAxis(new THREE.Vector3(0, 1, 0).normalize(), 0.1);
if (obj.position.y > 3.4) {
up = false;
}
} else if (!up) {
obj.translateOnAxis(new THREE.Vector3(0, 1, 0).normalize(), -0.1);
if (obj.position.y < -3.4) {
up = true;
}
}
renderer.render(scene, camera);
}
window.onload = () => {
document.getElementById("shape-form").onchange = evt => {
switch (evt.target.value) {
case "box":
currentShape = box;
break;
}
obj.geometry = currentShape;
obj.geometry.buffersNeedUpdate = true;
};
document.getElementById("mesh-form").onchange = evt => {
switch (evt.target.value) {
case "phong":
currentMesh = phong;
break;
}
obj.material = currentMesh;
obj.material.needsUpdate = true;
};
animate();
};
It's just hard to see a sphere rotating :)
Here's a simplified version of your example - I made both the cube and the sphere rotate and float around in gentle waves.
const renderer = new THREE.WebGLRenderer();
renderer.setSize((3 * window.innerWidth) / 4, (3 * window.innerHeight) / 4);
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
scene.background = new THREE.Color("white");
const camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 17;
const light = new THREE.DirectionalLight();
light.position.set(-1, 1, 1);
scene.add(light);
const phong = new THREE.MeshPhongMaterial({
color: "pink",
emissive: 0,
specular: 0x070707,
shininess: 100,
});
const boxGeom = new THREE.BoxGeometry(1, 1, 1);
const boxObj = new THREE.Mesh(boxGeom, phong);
scene.add(boxObj);
const sphereGeom = new THREE.SphereGeometry(0.5, 32, 32);
const sphereObj = new THREE.Mesh(sphereGeom, phong);
scene.add(sphereObj);
function animate() {
const time = +new Date() / 1000;
requestAnimationFrame(animate);
boxObj.rotation.y += 0.01;
sphereObj.rotation.x += 0.02;
boxObj.position.x = Math.sin(time * .2) * 3.4;
sphereObj.position.x = Math.cos(time * .3) * 3.4;
boxObj.position.y = Math.sin(time) * 3.4;
sphereObj.position.y = Math.cos(time) * 3.4;
renderer.render(scene, camera);
}
animate();
<script src="https://threejs.org/build/three.min.js"></script>

Rendering to render target makes some of my graphics invisible

Hi I have been playing with render targets but I ran into some problems. I created a simplified example here:
init = function() {
// RENDERER
canvas = document.getElementById("mycanvas");
renderer = new THREE.WebGLRenderer({
antialias: true
});
document.body.appendChild( renderer.domElement );
renderer.setClearColor(0x000000, 1.0);
renderer.setSize(window.innerWidth, window.innerHeight);
// SCENE
texscene = new THREE.Scene();
texcamera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
texcamera.position.z = 2;
// FRAMEBUFFER
var renderTargetParams = {
minFilter:THREE.LinearFilter,
stencilBuffer:false,
depthBuffer:false,
wrapS: THREE.RepeatWrapping,
wrapT: THREE.RepeatWrapping
};
rendertarget = new THREE.WebGLRenderTarget( 512, 512, renderTargetParams );
// CUBE
var cubeGeo = new THREE.BoxGeometry( 1, 1, 1, 1, 1, 1 );
var cubeMat = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
texcube = new THREE.Mesh( cubeGeo, cubeMat )
texscene.add(texcube);
var blueMaterial = new THREE.MeshBasicMaterial({color:0x7074FF})
var plane = new THREE.PlaneBufferGeometry( 100, 100 );
var planeObject = new THREE.Mesh(plane,blueMaterial);
planeObject.position.z = -15;
texscene.add(planeObject);
/////////////////////////////////
//SCENE
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
var boxMaterial = new THREE.MeshBasicMaterial({map:rendertarget.texture});
var boxGeometry2 = new THREE.BoxGeometry( 5, 5, 5 );
mainBoxObject = new THREE.Mesh(boxGeometry2,boxMaterial);
// Move it back so we can see it
mainBoxObject.position.z = -10;
// Add it to the main scene
scene.add(mainBoxObject);
animate();
}
animate = function() {
requestAnimationFrame(animate);
renderer.render(texscene, texcamera, rendertarget);
renderer.render(scene, camera);
texcube.rotation.y += 0.01;
texcube.rotation.z += 0.01;
mainBoxObject.rotation.x +=0.01;
mainBoxObject.rotation.y += 0.005;
mainBoxObject.rotation.z += 0.008;
}
init();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r83/three.js"></script>
I render a red cube and a blue plane to a render target then use it as a texture. Problem is the red cube is not visible in the final result.
Try for yourself to see the render target scene by changing
renderer.render(texscene, texcamera, rendertarget);
renderer.render(scene, camera);
to
renderer.render(texscene, texcamera);
Apparantly the problem is caused by turning off the depth buffer as I had done in the settings of my rendertarget
depthBuffer:false,
Removing this line makes my rendertarget render as it should with a red box on a blue background

ThreeJS - Intersection of a line and sphere

I have two objects on my scene: a red line and a sphere.
While camera rotating/zooming/moving, I need to check the following:
Does the line intersects with the sphere looking from the current position of the camera (please see images below)? Please use this JS fiddle that creates the scene on the images.
I know how to find the intersection between the current mouse position and objects on the scene (just like this example shows).
But how to do this in my case?
JS Fiddle Code:
/**
* PREPARE SCENE
*/
var mouse = {
x : 0,
y : 0
};
var projector = new THREE.Projector();
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75,
window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.x = -5;
camera.position.y = 5;
camera.position.z = 30;
var renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.TrackballControls(camera,
renderer.domElement);
controls.rotateSpeed = 3.0;
controls.zoomSpeed = 1.5;
controls.panSpeed = 1.0;
controls.staticMoving = true;
var grid = new THREE.GridHelper(20, 5);
scene.add(grid);
/**
* CREATE SPHERE
*/
var sphere = new THREE.Mesh(
new THREE.SphereGeometry(5, 10, 10),
new THREE.MeshNormalMaterial());
sphere.overdraw = true;
scene.add(sphere);
/**
* CREATE LINE
*/
var lineMaterial = new THREE.LineBasicMaterial({
color : 0xFF0000
});
var lineGeometry = new THREE.Geometry();
lineGeometry.vertices.push(new THREE.Vector3(8, 8, 8));
lineGeometry.vertices.push(new THREE.Vector3(8, 8, 20));
var line = new THREE.Line(lineGeometry, lineMaterial);
scene.add(line);
renderer.domElement.addEventListener('mousemove', render, false);
render();
function render(event) {
var mouse = {};
/*
* INTERSECTION
*/
if (event != null) {
//intersection job???
}
controls.update();
renderer.render(scene, camera);
}
So, I found the solution that is pretty simple (of course). See new JS Fiddle that checks intersection of the line and sphere and visualizes the ray for debugging.
The JS Fiddle code:
var camera, controls, scene, renderer;
init();
animate();
render();
function init() {
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 800;
controls = new THREE.TrackballControls(camera);
controls.rotateSpeed = 5.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 4;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.addEventListener('change', render);
// world
scene = new THREE.Scene();
sceneTarget = new THREE.Scene();
var grid = new THREE.GridHelper(500, 50);
scene.add(grid);
/**
* CREATE LINE
*/
var lineMaterial = new THREE.LineBasicMaterial({
color : 0xFF0000
});
var lineGeometry = new THREE.Geometry();
lineGeometry.vertices.push(new THREE.Vector3(100, 200, 100));
lineGeometry.vertices.push(new THREE.Vector3(300, 200, 200));
var line = new THREE.Line(lineGeometry, lineMaterial);
sceneTarget.add(line);
/*
* CREARE SPHERE
*/
var sphere = new THREE.Mesh(new THREE.SphereGeometry(150, 100, 100), new THREE.MeshNormalMaterial());
sphere.overdraw = true;
scene.add(sphere);
// renderer
renderer = new THREE.WebGLRenderer({
alpha: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.autoClear = false;
renderer.setClearColor(0xffffff, 1);
document.body.appendChild(renderer.domElement);
}
function animate() {
requestAnimationFrame(animate);
controls.update();
}
function render() {
renderer.render(scene, camera);
renderer.render(sceneTarget, camera);
intersect();
}
function intersect() {
var direction = new THREE.Vector3(100, 200, 100);
var startPoint = camera.position.clone();
var directionVector = direction.sub( startPoint );
var ray = new THREE.Raycaster(startPoint, directionVector.clone(). normalize());
scene.updateMatrixWorld(); // required, since you haven't rendered yet
var rayIntersects = ray.intersectObjects(scene.children, true);
if (rayIntersects[0]) {
//inersection is found
console.log(rayIntersects[0]);
//visualize the ray for debugging
var material = new THREE.LineBasicMaterial({
color: 0x0000ff
});
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(ray.ray.origin.x, ray.ray.origin.y, ray.ray.origin.z));
geometry.vertices.push(new THREE.Vector3(100, 200, 100));
var line = new THREE.Line(geometry, material);
sceneTarget.add( line );
}
}

Categories

Resources