everything works fine but sphere and box geometry dont show, plane works fine too! does anyone have a clue? i suspect something wrong maybe in the render function or animation frame, im fairly new to three.js and cant seem to know why the scene wont show the other geometry, i tried different materials, rotation, clear color, etc
var renderer,
scene,
camera,
myCanvas = document.getElementById('myCanvas');
//RENDERER
renderer = new THREE.WebGLRenderer({
canvas: myCanvas,
antialias: true,
});
renderer.setClearColor(0x000000);
renderer.setPixelRatio(window.devicePixelRatio); //device pixel ratio
renderer.setSize(window.innerWidth, window.innerHeight); //canvas size
//CAMERA
var camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 300, 10000)
//SCENE
var scene = new THREE.Scene();
//LIGHT
var light = new THREE.AmbientLight(0xffff, 0.5)
scene.add(light);
var light1 = new THREE.PointLight(0xffff, 0.5)
scene.add(light1);
//MATERIAL
var material = new THREE.MeshLambertMaterial({
color: 0xF3FFE2,
lightMap: null,
lightMapIntensity: 1,
emissive: 0x000000,
emissiveMap: null,
emissiveIntensity: 1,
specularMap: null
});
//GEOMETRY
var geometry = new THREE.BoxGeometry(100, 100, 100);
var mesh = new THREE.Points(geometry, material);
mesh.position.z = -1000;
mesh.position.x = -100;
scene.add(mesh);
var geometry2 = new THREE.SphereGeometry(50, 20, 20);
var mesh2 = new THREE.Points(geometry2, material);
mesh2.position.z = -1000;
mesh2.position.x = 100;
scene.add(mesh2);
var geometry3 = new THREE.PlaneGeometry(10000, 10000, 100, 100);
var mesh3 = new THREE.Mesh(geometry3, material);
mesh3.rotation.x = -90 * Math.PI / 180;
mesh3.position.y = -100;
scene.add(mesh3);
//RENDER LOOP
render();
function render() {
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
requestAnimationFrame(render);
}
Tried your code, everything is ok but the 2 objects need to be THREE.Mesh
var geometry = new THREE.BoxGeometry(100, 100, 100);
var mesh = new THREE.Mesh(geometry, material);
mesh.position.z = -1000;
mesh.position.x = -100;
scene.add(mesh);
var geometry2 = new THREE.SphereGeometry(50, 20, 20);
var mesh2 = new THREE.Mesh(geometry2, material);
mesh2.position.z = -1000;
mesh2.position.x = 100;
scene.add(mesh2);
Related
I'm tying to get the plane to receive shadow from the sphere, but somewhere on my way I do something wrong, anyone that has an idea about how to fix it?
//.................SETUP................//
import {
WebGLRenderer,
PerspectiveCamera,
Scene,
BoxGeometry,
MeshBasicMaterial,
Mesh,
Group,
PlaneGeometry,
AxesHelper,
GridHelper,
DoubleSide,
DirectionalLight,
AmbientLight,
MeshStandardMaterial,
DirectionalLightHelper,
Fog,
TextureLoader,
CubeTextureLoader,
SphereGeometry,
} from './three.module.js';
import { OrbitControls } from './q.js';
//................PROGRAM...............//
var renderer, camera, scene, light, light1, geometry, material, mesh;
// renderer
renderer = new WebGLRenderer({canvas:
document.getElementById('Canvas'), antialias: true, alfa: true});
//alfa: true gör att tomma pixlar i canvasen visar underliggande html-innehåll så att om man exempelvis skulle ha en bild under ett tomt canvas-element så kan man ändå se bilden.
renderer.setClearColor(0x555555);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enable = true;
// camera
camera = new PerspectiveCamera(35, window.innerWidth /
window.innerHeight, 0.1, 6000);
camera.position.set(0, 0, 100);
camera.lookAt(0, 0, 0);
//controls
var orbitcontrol = new OrbitControls(camera, renderer.domElement)
//scene
scene = new Scene();
//lights
//var ambientlight = new AmbientLight(0x333333);
//scene.add(ambientlight);
var sun = new DirectionalLight(0xffffff, 0.8);
sun.castShadow = true;
scene.add(sun);
sun.position.set(0, 40, 0);
//fog
//scene.fog = new Fog(0xffffff, 0, 200);
//helpers
var gridhelper = new GridHelper(10, 10);
scene.add(gridhelper);
var axishelper = new AxesHelper(3);
scene.add(axishelper);
var directionallighthelper = new DirectionalLightHelper(sun, 10, 0xff0000);
scene.add(directionallighthelper);
//material loaders
var bildimport = new TextureLoader().load('a.jpg');
var bildimport2 = new TextureLoader().load('träd.jpg');
var textureLoader = new TextureLoader();
scene.background = textureLoader.load('a.jpg');
//objects
//sphere
var geometrySphere = new SphereGeometry(10, 15);
var materialSphere = new MeshStandardMaterial({
color: 0xffff00f,
flatShading: true,
//wireframe: true,
});
var meshSphere = new Mesh(geometrySphere, materialSphere);
scene.add(meshSphere);
meshSphere.position.set(0,20,0);
meshSphere.castShadow = true;
meshSphere.receiveShadow = true;
//cube
geometry = new BoxGeometry(1, 1, 1);
var alt_material = [
new MeshBasicMaterial({map: bildimport2}),
new MeshBasicMaterial({map: bildimport}),
new MeshBasicMaterial({map: bildimport2}),
new MeshBasicMaterial({map: bildimport}),
new MeshBasicMaterial({map: bildimport2}),
new MeshBasicMaterial({map: bildimport}),
];
material = new MeshStandardMaterial({
color: 0xff0000,
map: bildimport2,
});
mesh = new Mesh(geometry, alt_material);
mesh.position.set(0, 50, 0);
mesh.castShadow = true;
scene.add(mesh);
//plane
var geometry2 = new PlaneGeometry(50, 50);
var material2 = new MeshStandardMaterial({
color: 0xfff00,
map: bildimport,
side: DoubleSide, // Gör att planet färgas på båda sidor isf bara på ovansidan.
});
var mesh2 = new Mesh(geometry2, material2);
mesh2.receiveShadow = true;
scene.add(mesh2);
mesh2.rotation.x = -0.5 * Math.PI;
//groups
//renderer loop
requestAnimationFrame(render);
var i = 0;
var increase_of_i = 0.01;
function render() {
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.01;
// mesh.position.y = 100 * Math.abs(Math.sin(i));
mesh.scale.x = 1 + Math.abs(Math.sin(2*i));
mesh.scale.y = 1 + Math.abs(Math.sin(2*i));
mesh.scale.z = 1 + Math.abs(Math.sin(2*i));
i += increase_of_i;
renderer.render(scene, camera);
requestAnimationFrame(render);
}
I'm tying to get the plane to receive shadow from the sphere, but somewhere on my way I do something wrong, anyone that has an idea about how to fix it?
There is a typo in your code. It should be renderer.shadowMap.enabled (the last d is missing).
Besides, you have not configured the directional light's shadow so far which might be necessary. You normally do this in a way such that the shadow camera's frustum encloses all shadow casting and receiving 3D objects. You can visually debug the frustum via THREE.CameraHelper like so:
scene.add( new THREE.CameraHelper( sun.shadow.camera ) );
The frustum can be configured like so:
sun.shadow.camera.top = 25;
sun.shadow.camera.bottom = - 25;
sun.shadow.camera.left = - 25;
sun.shadow.camera.right = 25;
sun.shadow.camera.near = 0.1;
sun.shadow.camera.far = 100;
I'm working on Threejs to animate a cube with different text on each cube faces. I used DynamicTexture to place text on cube faces, but it places same text on each side of cube. I don't know how to place different text on each side. Is there any way to do is and place text on runtime by user inputs? Thanks.
Main.js
var scene = new THREE.Scene();
scene.background = new THREE.Color('white');
var camera = new THREE.PerspectiveCamera(50, window.innerWidth/window.innerHeight, 1, 1000);
camera.position.set(4, 4, 4);
camera.lookAt(0, 0, 0);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.getElementById('display').appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera);
var dynamictexture = new THREEx.DynamicTexture(512, 512);
dynamictexture.context.font = "bolder 90px verdana";
dynamictexture.texture.needsUpdate = true;
dynamictexture.clear('#d35400').drawText('Text', undefined, 256, 'green');
var geometry = new THREE.BoxGeometry(2, 2, 2);
var material = new THREE.MeshBasicMaterial({color: 0xffffff, map: dynamictexture.texture, opacity:1,
transparent: true});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
function animate() {
requestAnimationFrame(animate);
controls.update();
dynamictexture.texture
renderer.render(scene, camera);
};
animate();
You can use THREE.MeshFaceMaterial(materials) to accomplish this. All you need to do is pass an array containing the materials and specifying the map for each of the faces.
var face_textures = [];
function createFaceTextures() {
var i;
for(i = 0; i < 6; i++) {
var dynamictexture = new THREEx.DynamicTexture(512, 512);
dynamictexture.context.font = "bolder 90px verdana";
dynamictexture.texture.needsUpdate = true;
dynamictexture.clear('#d35400').drawText(i.toString(), undefined, 256, 'green');
face_textures.push(dynamictexture);
}
}
createFaceTextures();
var scene = new THREE.Scene();
scene.background = new THREE.Color('white');
var camera = new THREE.PerspectiveCamera(50, window.innerWidth/window.innerHeight, 1, 1000);
camera.position.set(4, 4, 4);
camera.lookAt(0, 0, 0);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.getElementById('display').appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera);
var dynamictexture = new THREEx.DynamicTexture(512, 512);
dynamictexture.context.font = "bolder 90px verdana";
dynamictexture.texture.needsUpdate = true;
dynamictexture.clear('#d35400').drawText('Text', undefined, 256, 'green');
var geometry = new THREE.BoxGeometry(2, 2, 2,);
var material = new THREE.MeshBasicMaterial({color: 0xffffff, map: dynamictexture.texture, opacity:1, transparent: true});
var materials = [
new THREE.MeshBasicMaterial({map: face_textures[0].texture}),
new THREE.MeshBasicMaterial({map: face_textures[1].texture}),
new THREE.MeshBasicMaterial({map: face_textures[2].texture}),
new THREE.MeshBasicMaterial({map: face_textures[3].texture}),
new THREE.MeshBasicMaterial({map: face_textures[4].texture}),
new THREE.MeshBasicMaterial({map: face_textures[5].texture})
];
var cube = new THREE.Mesh(geometry, materials);
scene.add(cube);
function animate() {
requestAnimationFrame(animate);
controls.update();
dynamictexture.texture
renderer.render(scene, camera);
}
animate();
I want to draw a Octahedron,but the shape of the result is below expectation.I dont know the reason and next step I want to draw a Dodecahedron, any suggestions?The result of the Octahedron
My code:
var mesh, renderer, scene, camera, controls;
init();
animate();
function init() {
// renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera(40, window.innerWidth /
window.innerHeight, 1, 10000);
camera.position.set(20, 20, 20);
// controls
controls = new THREE.OrbitControls(camera);
// ambient
scene.add(new THREE.AmbientLight(0x222222));
// light
var light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(20, 20, 0);
scene.add(light);
// axes
scene.add(new THREE.AxisHelper(20));
// geometry
//var geometry = new THREE.SphereGeometry(5, 12, 8);
var vertices = [
0.5,0,0, 0,0.3,0, -0.5,0,0, 0,-0.3,0, 0,0,0.3, 0,0,-0.3
];
var faces = [
0,1,4, 1,2,4, 2,3,4, 3,0,4, 0,1,5, 1,2,5, 2,3,5, 3,0,5
];
var geometry = new THREE.PolyhedronGeometry(vertices, faces, 5, 1);
// material
var material = new THREE.MeshPhongMaterial({
color: 0x00ffff,
shading: THREE.FlatShading,
wireframe:true,
transparent: true,
opacity: 0.7,
});
// mesh
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
}
function animate() {
requestAnimationFrame(animate);
//controls.update();
renderer.render(scene, camera);
}
Use
var geometry = new THREE.OctahedronGeometry( 5, 0 ); // or DodecahedronGeometry
Read and understand the source code of OctahedronGeometry.js if you want to use PolyhedronGeometry directly.
If wireframe is true, use MeshBasicMaterial, instead.
three.js r.85
I am trying to make an opaque box with three.js, but the light is still going thought the box:
I have one "THREE.SpotLight" and 2 objects in my scene: the sphere is projecting the shadow onto the box.
There are 2 shadows (I think there should be only one):
the first, at the top of the box seems correct,
the second is weird (as if the box where transparent).
Illustration here: http://i.stack.imgur.com/ZNmI3.png
var scene, camera, renderer;
var material;
init();
function init() {
//Renderer
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.shadowMapEnabled = true;
renderer.setSize(window.innerWidth, window.innerHeight);
scene = new THREE.Scene();
//Camera
camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(0, 20, 20);
camera.lookAt(new THREE.Vector3(0, 15, 0));
//Material
material = new THREE.MeshLambertMaterial({
color: 0xffffff
});
//Box
var box = new THREE.Mesh(new THREE.BoxGeometry(7, 16, 7), material);
box.position.y = 8;
box.castShadow = true;
box.receiveShadow = true;
scene.add(box);
//Sphere
geometry = new THREE.SphereGeometry(.8, 48, 48);
var sphere = new THREE.Mesh(geometry, material);
sphere.position.set(-5, 17, -3);
sphere.castShadow = true;
sphere.receiveShadow = true;
scene.add(sphere);
// Lights
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-50, 40, -50);
spotLight.target.position.set(-5, 17, -3);
spotLight.castShadow = true;
spotLight.shadowMapWidth = 2048;
spotLight.shadowMapHeight = 2048;
spotLight.shadowCameraVisible = true;
scene.add(spotLight);
var ambientLight = new THREE.AmbientLight(0x444444);
scene.add(ambientLight);
document.body.appendChild(renderer.domElement);
}
renderer.render(scene, camera);
My question is:
How can i make the box opaque?
Jsfiddle here: http://jsfiddle.net/v81gs6u1/4/
It is not the light that is going through the box but the shadow. Try playing with the shadow bias.
In your case adding:
spotLight.shadowBias = 0.001;
takes care of the artifact.
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 );
}
}