Why my 3d background is not loading in ThreeJS? - three.js

I'm using CubeTextureLoader for a 3d background of 2 images and it aint working. Even though the path to images is fine and I get the images working fine in TextureLoader.
import * as THREE from "three"
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls.js"
import * as dat from "dat.gui"
import nebula from './images/nebula.jpg'
import stars from './images/stars.jpg'
const renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.shadowMap.enabled=true
renderer.setClearColor(0x590d18, 1);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
const orbit=new OrbitControls(camera,renderer.domElement)
const axesHelper = new THREE.AxesHelper(2);
scene.add(axesHelper);
camera.position.set(-10, 30, 30);
orbit.update()
const planeGeometry=new THREE.PlaneGeometry(30,30)
const planeMaterial=new THREE.MeshStandardMaterial({
color:0xffffff,
side:THREE.DoubleSide
})
const plane=new THREE.Mesh(planeGeometry,planeMaterial)
scene.add(plane)
plane.rotation.x=-0.5*Math.PI
plane.receiveShadow=true
const gridHelper=new THREE.GridHelper(30)
scene.add(gridHelper)
const sphereGeometry = new THREE.SphereGeometry(4,50,50);
const sphereMaterial = new THREE.MeshStandardMaterial({
color: 0x0000ff,
wireframe:false,
});
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
scene.add(sphere);
sphere.position.set(-10,4,4)
sphere.castShadow=true
const spotLight=new THREE.SpotLight(0xFFFFFF)
scene.add(spotLight)
spotLight.position.set(-100,100,0)
spotLight.castShadow=true
spotLight.angle=0.2
const sLightHelper=new THREE.SpotLightHelper(spotLight)
scene.add(sLightHelper)
scene.fog=new THREE.FogExp2(0xFFFFFF,0.02)
//loading an image
//const textureLoader=new THREE.TextureLoader()
//scene.background=textureLoader.load(stars) THIS WORKS
const cubeTextureLoader=new THREE.CubeTextureLoader() THIS DONT
scene.background=cubeTextureLoader.load([
stars,
stars,
nebula,
stars,
stars,
stars
])
const gui=new dat.GUI()
const options={
sphereColor:'#ffea00',
wireframe:false,
speed:0.01,
angle:0.2,
penumbra:0,
intensity:1
}
gui.addColor(options,'sphereColor').onChange(function(e){
sphere.material.color.set(e)
})
gui.add(options,'wireframe').onChange(function(e){
sphere.material.wireframe=e
})
gui.add(options,"speed",0,0.1)
gui.add(options,"angle",0,1)
gui.add(options,"penumbra",0,1)
gui.add(options,"intensity",0,1)
let step=0
function animate(time) {
box.rotation.x = time/1000;
box.rotation.y = time/1000;
step+=options.speed
sphere.position.y=10*Math.abs(Math.sin(step))
spotLight.angle=options.angle;
spotLight.penumbra=options.penumbra;
spotLight.intensity=options.intensity;
sLightHelper.update()
renderer.render(scene, camera);
}
renderer.setAnimationLoop(animate)
I was expecting a 3d background , but instead I get the original black color.
I'm using CubeTextureLoader for a 3d background of 2 images and it aint working. Even though the path to images is fine and I get the images working fine in TextureLoader.

I had the same problem a while back and it turns out all the faces of the CubeTextureLoader must be squares.
So, cropping the images to have a 1:1 dimension might work.

Related

Three JS export GLFT model doesn't look like in Blender Rendered Mode

I'm newbie to both 3JS and Blender , when I export my model to .glb , then import it to my 3JS project . But somehow they are not the same.
In Blender Rendered Mode it look so smooth but in 3JS , all the color , the mesh , ... so terrible, what did i miss to adjust in 3JS project , please help me :(
(all of my Blender setting are default)
import * as THREE from 'three';
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js';
import {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader.js'
//import img
import galaxy from '../img/galaxy.jpg';
//setting value place
const monkeyURL = new URL('../asssets/racoon_2_1.glb',import.meta.url);
const renderer = new THREE.WebGLRenderer();
renderer.gammaOutput = true;
renderer.setSize(window.innerWidth,window.innerHeight); //note this place to change the size of scene to fit the html css
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth/window.innerHeight,
0.1,
1000
);
//spot light
const spotLight= new THREE.SpotLight(0xFFFFFF);
scene.add(spotLight);
spotLight.position.set(00,10,10);
spotLight.castShadow=true;
const spotLight1= new THREE.SpotLight(0xFFFFFF);
scene.add(spotLight1);
spotLight1.position.set(00,10,-10);
spotLight.castShadow=true;
spotLight.angle=0.5;
const spotLightHelper = new THREE.SpotLightHelper(spotLight);
scene.add(spotLightHelper);
//change color background or image
//renderer.setClearColor(0xFFEA00);
//const textureLoader = new THREE.TextureLoader();
//scene.background = textureLoader.load(galaxy);
//model Blender
const assetLoader = new GLTFLoader();
assetLoader.load(monkeyURL.href,function(gltf){
const model = gltf.scene;
scene.add(model);
model.position.set(0,0,0);
}, undefined, function(error){
console.error(error);
});
//orbit controls
const orbit = new OrbitControls(camera, renderer.domElement);
//axes
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);
//camera
camera.position.set(0,2,5);
//functions :D
orbit.update();
function animate()
{
renderer.render(scene,camera);
}
renderer.setAnimationLoop(animate);
Get some help to fix my error

Threejs loading models

I'm new to three.js, and I'm trying to load in my tree model, but all I see if a blank screen.
I've validated the GLB file using gltf-viewer.donmccurdy.com (though the textures didn't seem to load (I'd converted from GLTF to GLB), and I don't get any JS errors in the developer tools, so I'm at a bit of a block (at least mentally).
I've loaded the camera, I've created an Ambient light to light the object (I've reduced the code as it did have directional and point lighting as well).
I'm making the assumption that all objects are loaded at 0,0,0 in terms of coordinates. Does anyone have any experience with GLB files not rendering or where I've gone wrong.
import {
Camera,
Color,
Scene,
PerspectiveCamera,
WebGLRenderer,
AmbientLight,
} from "https://cdn.skypack.dev/three#0.132.2";
import { GLTFLoader } from 'https://cdn.skypack.dev/three#0.132.2/examples/jsm/loaders/GLTFLoader.js';
const container = document.querySelector('#scene-container');
const scene = new Scene();
const renderer = new WebGLRenderer();
const hlight = new AmbientLight (0x404040,100);
const fov = 80;
const aspect = container.clientWidth / container.clientHeight;
const near = 0.1;
const far = 100;
const camera = new PerspectiveCamera(fov, aspect, near, far);
const loader = new GLTFLoader();
scene.background = new Color('white');
camera.position.set(0, 50, 100);
scene.add(hlight);
renderer.setSize(container.clientWidth, container.clientHeight);
renderer.setPixelRatio(window.devicePixelRatio);
container.append(renderer.domElement);
loader.load('tree.glb', function(gltf){
const tree = gltf.scene.children[0];
tree.scale.set(1.5,1.5,1.5);
scene.add(gltf.scene);
});
renderer.render(scene, camera);

Cube exported using GLTF with 0 roughness Principled BSDF material doesn't display properly in Three.js

I've been having issues with my Blender materials showing up in three.js. One important detail I keep seeing mentioned on SO and elsewhere is that the GLTF format has limited support for exporting your node setup in Blender and it's best to stick with the basics like Principled BSDF. However, even with a basic Principled BSDF setup(pictured below), creating a grey reflective cube with roughness 0, I can't see any of the reflectiveness in three.js(also pictured).
Here's my three.js scene:
import * as THREE from "three"
import {GLTFLoader} from "three/examples/jsm/loaders/GLTFLoader.js"
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls.js"
(async () => {
const gScene = new THREE.Scene()
const canvas = document.querySelector("#c")
const gRenderer = new THREE.WebGLRenderer({canvas})
const gCamera = new THREE.PerspectiveCamera(50, canvas.clientWidth/canvas.clientHeight, 0.1, 1000)
gCamera.position.x = 0
gCamera.position.Y = 100
gCamera.position.z = 20
const controls = new OrbitControls(gCamera, canvas)
controls.target.set(0,5,0)
controls.update()
const ambientLight = new THREE.AmbientLight(0xffffff, 40)
gScene.add(ambientLight)
const gltfLoader = new GLTFLoader()
let scene = await new Promise((resolve, reject) => {
gltfLoader.load('./scene.glb', (loadedGLB) => {
resolve(loadedGLB.scene)
})
})
gScene.add(scene)
function resizeRendererToDisplaySize(renderer){
const canvas = renderer.domElement
const pixelRatio = window.devicePixelRatio
const width = canvas.clientWidth * pixelRatio | 0
const height = canvas.clientHeight * pixelRatio | 0
const needResize = canvas.width !== width || canvas.height !== height
if (needResize){
renderer.setSize(width, height, false)
}
return needResize
}
function render(){
if(resizeRendererToDisplaySize(gRenderer)){
let canvas = gRenderer.domElement
gCamera.aspect = canvas.clientWidth/ canvas.clientHeight
gCamera.updateProjectionMatrix()
}
gRenderer.render(gScene,gCamera)
requestAnimationFrame(render)
}
requestAnimationFrame(render)
})()
Blend file: https://drive.google.com/file/d/1rJXmlKuZsNXl3zRt8YqaB7nUamOfKRw3/view?usp=sharing
You can achieve what you are looking for by adding a HDR environment map to your scene. The idea is to load a respective texture e.g. via RGBELoader, pre-processing it with PMREMGenerator and then applying it to Scene.environment. By doing so the texture is set as the environment map for all PBR materials in your scene.
I suggest you have a look at the basic glTF example from the repository for more details. Also make sure to use the same renderer configuration (meaning ensure to work in sRGB color space and use tone mapping).
https://threejs.org/examples/webgl_loader_gltf

How to load texture with transparent background and make it movable?

smile on shirt has black background
smile with transparent true
GOAL: I would like users to be able to add images/colors with buttons
PROBLEM: but the png image texture(smiley face) loaded with textureLoader() has black background and lines crossing the image. :frowning:
MINOR PROBLEM:
(1) Are there any ways to match the background color of the image and the obj/gltf(shirt) that I load?
Here are my codes.
const colorSelection = {
"pink": "#ff2d55",
"purple": "#5856d6",
"blue": "#007aff",
"orange": "#ff9500",
}
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 });
const loader = new THREE.OBJLoader();
const myCanvas = document.getElementById("container");
const controls = new THREE.OrbitControls(camera, renderer.domElement);
const axisHelper = new THREE.AxisHelper(5);
const hlight = new THREE.AmbientLight (0x404040);
const directionalLight = new THREE.DirectionalLight(0xffffff,0.4);
const geometry = new THREE.SphereGeometry(50,50,50);
const texture = new THREE.TextureLoader().load("assets/smile2.png");
const newMat = new THREE.MeshPhongMaterial({ map: texture });
myCanvas.appendChild( renderer.domElement );
renderer.setSize( 800, 800 );
renderer.setClearColor ("darkgrey", 1);
camera.position.set(200,300,200);
controls.addEventListener("change", animate);
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
};
// SCENES and LIGHTING
scene.add(axisHelper);
scene.add(hlight);
scene.add(directionalLight);
directionalLight.position.set(0,1155,325);
directionalLight.castShadow = true;
function changeTextureColor(color) {
loader.load("assets/standard-t-shirt/source/tshirt.obj", function(obj) {
obj.scale.set(0.4,0.4,0.4)
obj.position.set(0,-500,0)
obj.traverse((child) => {
if (child instanceof THREE.Mesh) {
child.material.emissive = new THREE.Color(colorSelection[color])
console.log(child.material)
}
})
console.log(obj.children)
obj.children[0].material = newMat
scene.add(obj)
})
}
document.querySelectorAll("button").forEach(colorBtn => colorBtn.addEventListener("click", function () {
console.log(this.id)
const userColor = this.id;
changeTextureColor(userColor);
}))
Thanks so much for reading!
You need the transparent: true setting when creating your material, like so:
const newMat = new THREE.MeshPhongMaterial({ map: texture, transparent: true });

Create 3D globe like Paperplanes or A world of change

I have a project, where I have to show a globe on home page, where visitor can select location(major known cities) & then make a search. I google & find some best examples like :
http://paperplanes.world &
http://news-lab-trends-experiment.appspot.com/
If there is any raw code available so that I can make changes as per requirements. I look around some js https://threejs.org/ & http://www.webglearth.org, how these can be helpful.
If you just want some abstract representation of the earth, it doesn't make much sense to go for webglearth and the likes, as you a) will not need that complexity they implement and b) can't easily adjust the appearance of the globe towards something as simple as the examples.
The good news is that all that isn't really as complicated as it might sound at first. For a simplified 3d-model, there are some of them out there. Just have a look at these search-results. I believe this is the one that was used for the paperplanes project.
Positioning stuff on a spherical shape isn't that hard either, you just need to make yourself familiar with spherical coordinates (the math-version of latitude/longitude) and the THREE.Spherical class. A simple example for this below (for simplicity using a unit-sphere as earth, but it would be mostly the same if you would load a complex-model instead, as long as it's roughly spherical):
const textureLoader = new THREE.TextureLoader();
function setup(scene) {
// add some helpers
scene.add(new THREE.GridHelper(50, 100, 0x444444, 0x222222));
scene.add(new THREE.AxisHelper(2));
// add a textured sphere representing the earth
const texture = textureLoader.load(
'https://raw.githubusercontent.com/' +
'jiwonkim/d3gl/master/img/earth-blank.png'
);
const earth = new THREE.Mesh(
new THREE.SphereGeometry(1, 36, 18),
new THREE.MeshStandardMaterial({
map: texture,
metalness: 0,
roughness: 1
})
);
scene.add(earth);
const marker = new THREE.Mesh(
new THREE.BoxGeometry(0.05, 0.2, 0.05),
new THREE.MeshStandardMaterial({color: 0xff5500})
);
const lat = 52.5;
const lng = 10;
// compute position (adjust theta/phi conversion to the
// orientation of your model)
const spherical = new THREE.Spherical(
1, // radius
(90 - lat) / 180 * Math.PI, // latitude -> phi
(90 + lng) / 180 * Math.PI // longitude -> theta
);
marker.position.setFromSpherical(spherical);
earth.add(marker);
// compute orientation
const v3 = new THREE.Vector3();
v3.copy(marker.position).normalize();
marker.quaternion.setFromUnitVectors(marker.up, v3);
}
// ---- boilerplate-code
// .... setup renderer
const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
// .... setup scene
const scene = (window.scene = new THREE.Scene());
// .... setup camera and controls
const camera = new THREE.PerspectiveCamera(
70,
window.innerWidth / window.innerHeight,
.01,
100
);
const controls = new THREE.OrbitControls(camera);
camera.position.set(-3, 3, 4);
camera.lookAt(new THREE.Vector3(0, 0, 0));
// .... setup some lighting
const dirLight = new THREE.DirectionalLight(0xffffff, 0.6);
dirLight.position.set(1, 0, 0.5);
scene.add(dirLight, new THREE.AmbientLight(0x666666));
// .... setup and run demo-code
setup(scene);
requestAnimationFrame(function loop(time) {
controls.update();
renderer.render(scene, camera);
requestAnimationFrame(loop);
});
// .... bind events
window.addEventListener("resize", ev => {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
});
document.body.appendChild(renderer.domElement);
body {margin: 0; background: black;}
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/build/three.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>

Resources