Inserting CSS3DObject (CSS3DRenderer) into Curved plane glb with WebGL - javascript

I'm trying to implement WEBGL and CSS3DRenderer. I'm trying to simulate a HTML page on the CSS3DRenderer and "insert" or "position" this CSS into the imported GLB model.
I want to create a "HTML page" and insert it into the curved glb model
This is my code
import './style.css'
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { CSS3DRenderer, CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(200, 120, 300);
// Scene
const scene = new THREE.Scene();
const scene2 = new THREE.Scene();
scene.background = new THREE.Color(0xf0f0f0);
// Renderer
const renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const renderer2 = new CSS3DRenderer();
renderer2.setSize(window.innerWidth, window.innerHeight);
renderer2.domElement.style.position = 'absolute';
renderer2.domElement.style.top = 0;
renderer2.domElement.style.bottom = 0;
document.body.appendChild(renderer2.domElement);
const controls = new OrbitControls(camera, renderer2.domElement);
window.addEventListener('resize', onWindowResize);
const material = new THREE.MeshBasicMaterial({
color: 0x000000,
wireframe: true,
wireframeLinewidth: 1,
side: THREE.DoubleSide
});
// WEbgl
// const geometry = new THREE.PlaneGeometry(100, 100);
// const mesh = new THREE.Mesh(geometry, material);
// mesh.position.copy(object.position);
// mesh.rotation.x = 0;
// mesh.scale.copy(object.scale);
// mesh.position.x = 9;
// scene.add(mesh);
// CSS3dElement
// const element = document.createElement(`div`);
// element.innerHTML = `Tutorix is the best e-learning platform Tutorix is the best e-learning platform Tutorix is the best e-learning platform`;
// element.style.width = '100px';
// element.style.height = '100px';
// element.style.overflowY = 'auto';
// element.style.background = new THREE.Color(0x00F0FF).getStyle();
// const object = new CSS3DObject(element);
// object.position.copy(mesh.position);
// object.rotation.copy(mesh.rotation);
// object.scale.copy(mesh.scale);
// scene2.add(object);
// scene
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('/draco/');
const gltfLoader = new GLTFLoader();
gltfLoader.setDRACOLoader(dracoLoader);
gltfLoader.load(
'/models/monitor.glb',
(gltf) => {
gltf.scene.scale.set(100, 100, 100);
scene.add(gltf.scene);
const dd = gltf.scene;
dd.rotation.y = -1;
// CSS3dElement
const element = document.createElement(`div`);
element.innerHTML = `Tutorix is the best e-learning platform Tutorix is the best e-learning platform Tutorix is the best e-learning platform`;
element.style.width = '100px';
element.style.height = '100px';
element.style.overflowY = 'auto';
element.style.background = new THREE.Color(0x00F0FF).getStyle();
const object = new CSS3DObject(element);
object.position.copy(dd.position);
object.rotation.copy(dd.rotation);
object.scale.copy(dd.scale / 2);
scene2.add(object);
}
);
animate();
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer2.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
renderer2.render(scene2, camera);
}
The black is the imported GLB and the blue is the CSS3DObject
Maybe using another dependency in which can do the job

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.

Three.js Mesh loads correctly but not showing

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>

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.

use fabric js canvas as a threejs 3d model texture

juste starting to learn threejs and to do so decided to build a t-shirt configurator in combination with fabric js. my goal is that the user can upload a picture to the canvas (cnvs) which will be mapped to the gltf model of a t-shirt the probleme is that the texture doesn't show .
code :
var canvas2 = new fabric.Canvas('cnvs', {
backgroundColor: 'red'
});
fabric.Image.fromURL('eo.png', function(myImg) {
//i create an extra var for to change some image properties
var img1 = myImg.set({ left: 0, top: 0 ,width:150,height:150});
canvas2.add(img1);
canvas2.renderAll();
});
var canvasTexture = new THREE.CanvasTexture(canvas2);
canvasTexture.wrapS = THREE.RepeatWrapping;
canvasTexture.wrapT = THREE.RepeatWrapping;
const gltfLoader2 = new GLTFLoader();
gltfLoader2.load('tshirt2.gltf', (gltf2) => {
model = gltf2.scene;
model.traverse(child => {
console.log(child.material);
if (child.material && child.material.name === 'Pattern2D_13095') {
// Pattern2D_13095
child.material.map = new TextureLoader().load( new THREE.MeshStandardMaterial({
map: canvasTexture,
}));
}
});
canvas2.on("after:render", function() {
model.material.map.needsUpdate = true;
});
canvas2.on('mouse:down',function(event){
if(canvas2.getActiveObject()){
alert(event.target);
}
})
scene.add(model);
model.rotation.x = 1.5;
model.position.y=310;
model.position.x=-300;
model.position.z=-100;
model.scale.set(1000,1000,1000);
});
});
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
function render() {
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
renderer.render(scene, camera);
requestAnimationFrame(render);
}
function animate(){
requestAnimationFrame(animate);
cloudParticles.forEach(p => {
p.rotation.z -= 0.001;
});
root.rotation.z -= 0.01;
renderer.render(scene, camera);
model.material.needsUpdate = true;
}
animate();
lights/camera:
let cloudParticles = [];
let root;
let model;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1,
1000 );
camera.position.z = 2;
camera.rotation.x = 1.16;
camera.rotation.y = -0.12;
camera.rotation.z = 0;
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas});
scene.fog = new THREE.FogExp2(0x11111f, 0.002);
renderer.setClearColor(scene.fog.color);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild( renderer.domElement );
let directionalLight = new THREE.DirectionalLight(0xff8c19);
directionalLight.position.set(0,0,1);
scene.add(directionalLight);
let orangeLight = new THREE.PointLight(0xcc6600,50,450,1.7);
orangeLight.position.set(200,300,100);
scene.add(orangeLight);
let redLight = new THREE.PointLight(0xd8547e,50,450,1.7);
redLight.position.set(100,300,100);
scene.add(redLight);
let blueLight = new THREE.PointLight(0x3677ac,50,450,1.7);
blueLight.position.set(300,300,200);
scene.add(blueLight);
let directionalLight2 = new THREE.DirectionalLight(0xffffff);
directionalLight2.position.set(-110,-110,-120);
scene.add(directionalLight2);
HTML:
<div class="cnvscon">
<canvas id="cnvs" height="256" width="256" ></canvas></div>
<canvas id="c"></canvas>
here is an img of the result ( the mesh is black ):
result
gltfviewer
child.material.map = new TextureLoader().load( new THREE.MeshStandardMaterial({
map: canvasTexture }));
I'm afraid this code is incorrect. It should be sufficient to assign canvasTexture to the respective map property. Meaning:
child.material.map = canvasTexture;

THREE.JS Uncaught ReferenceError: OrbitControls is not defined

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const controls = new OrbitControls(camera);
camera.position.set(200, 0, 0);
controls.update();
const geometry = new THREE.SphereGeometry(50, 32, 32);
const material = new THREE.MeshBasicMaterial({
color: 0xffff00
});
const sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
<script src="https://cdn.jsdelivr.net/npm/three#0.129.0/build/three.min.js"></script>
When I run my javascript code. I get the following error "Uncaught ReferenceError: OrbitControls is not defined".
I saw this post about it, but it doesn't seem to help.
Any ideas?
My OrbitControls.js is in the same file under the three.js file
I got your code running without errors by importing OrbitControls and defining your renderer at the top and passing it into OrbitControls.
Edit, I added a second snippet that was adapted from a three.js example on their site that I think adds the yellow sphere you're looking for.
let camera, controls, scene, renderer;
init();
//render(); // remove when using next line for animation loop (requestAnimationFrame)
animate();
function init() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0xcccccc);
scene.fog = new THREE.FogExp2(0xcccccc, 0.002);
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(400, 200, 0);
// controls
controls = new THREE.OrbitControls(camera, renderer.domElement);
//controls.addEventListener( 'change', render ); // call this only in static scenes (i.e., if there is no animation loop)
controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
controls.dampingFactor = 0.05;
controls.screenSpacePanning = false;
controls.minDistance = 100;
controls.maxDistance = 500;
controls.maxPolarAngle = Math.PI / 2;
// world
const geometry = new THREE.SphereGeometry(50, 32, 32);
const material = new THREE.MeshBasicMaterial({
color: 0xffff00
});
const sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);
//
window.addEventListener('resize', onWindowResize);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
controls.update(); // only required if controls.enableDamping = true, or if controls.autoRotate = true
render();
}
function render() {
renderer.render(scene, camera);
}
<script src="https://cdn.jsdelivr.net/npm/three#0.122.0/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.122.0/examples/js/controls/OrbitControls.min.js"></script>
let camera, controls, scene, renderer;
init();
//render(); // remove when using next line for animation loop (requestAnimationFrame)
animate();
function init() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0xcccccc);
scene.fog = new THREE.FogExp2(0xcccccc, 0.002);
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(400, 200, 0);
// controls
controls = new THREE.OrbitControls(camera, renderer.domElement);
//controls.addEventListener( 'change', render ); // call this only in static scenes (i.e., if there is no animation loop)
controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
controls.dampingFactor = 0.05;
controls.screenSpacePanning = false;
controls.minDistance = 100;
controls.maxDistance = 500;
controls.maxPolarAngle = Math.PI / 2;
// world
const geometry = new THREE.SphereGeometry(50, 32, 32);
const material = new THREE.MeshBasicMaterial({
color: 0xffff00
});
const sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);
//
window.addEventListener('resize', onWindowResize);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
controls.update(); // only required if controls.enableDamping = true, or if controls.autoRotate = true
render();
}
function render() {
renderer.render(scene, camera);
}
<script src="https://cdn.jsdelivr.net/npm/three#0.122.0/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.122.0/examples/js/controls/OrbitControls.min.js"></script>

Categories

Resources