Unable to add shadows - javascript

I just started learning three.js but was unable to put shadows of objects on the plane. All things are working, but objects are not casting their shadow on the plane. Here is my js file. I don't know what is missing in the code. Both HTML and javascript files are attached herewith.
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<script type = "text/javascript" src="../../../libs/three/three.js"></script>
<script type="text/javascript" src = "../../../libs/three/controls/TrackballControls.js"></script>
<script type="text/javascript" src = "../javascript/first_scene.js"></script>
<title>First_Scene</title>
</head>
<body>
<div id ="webgl-output"></div>
<script type="text/javascript">
(function(){
init()
}
)();
</script>
</body>
</html>
function init()
{
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth /
window.innerHeight,0.1, 1000);
var renderer =new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0x000000));
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.Enabled = true;
var axes = new THREE.AxesHelper(20);
scene.add(axes);
var planeGeometry = new THREE.PlaneGeometry(60,20,1,1)
var planeMaterial = new THREE.MeshLambertMaterial({
color: 0xffffff
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.receiveShadow = true;
plane.rotation.x = -0.5 * Math.PI;
plane.position.set(15,0,0);
scene.add(plane);
var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
var cubeMaterial = new THREE.MeshLambertMaterial({
color: 0xff0000
});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.castShadow = true;
cube.position.set(-4, 4, 0);
scene.add(cube);
var sphereGeometry = new THREE.SphereGeometry(4, 20, 20);
var sphereMaterial = new THREE.MeshLambertMaterial({
color: 0x7777ff,
});
var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.castShadow = true;
sphere.position.set(20, 0, 2);
sphere.castShadow = true;
scene.add(sphere);
camera.position.set(-30, 40, 30);
camera.lookAt(scene.position);
var ambienLight = new THREE.AmbientLight(0x353535);
scene.add(ambienLight);
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-10, 20, -5);
spotLight.castShadow = true;
scene.add(spotLight);
document.getElementById("webgl-output").appendChild(renderer.domElement);
renderer.render(scene, camera);
}

There is a typo in your code. It's not renderer.shadowMap.Enabled but renderer.shadowMap.enabled. Full code:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth /
window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0x000000));
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
var axes = new THREE.AxesHelper(20);
scene.add(axes);
var planeGeometry = new THREE.PlaneGeometry(60, 20, 1, 1)
var planeMaterial = new THREE.MeshLambertMaterial({
color: 0xffffff
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.receiveShadow = true;
plane.rotation.x = -0.5 * Math.PI;
plane.position.set(15, 0, 0);
scene.add(plane);
var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
var cubeMaterial = new THREE.MeshLambertMaterial({
color: 0xff0000
});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.castShadow = true;
cube.position.set(-4, 4, 0);
scene.add(cube);
var sphereGeometry = new THREE.SphereGeometry(4, 20, 20);
var sphereMaterial = new THREE.MeshLambertMaterial({
color: 0x7777ff,
});
var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.castShadow = true;
sphere.position.set(20, 0, 2);
scene.add(sphere);
camera.position.set(-30, 40, 30);
camera.lookAt(scene.position);
var ambienLight = new THREE.AmbientLight(0x353535);
scene.add(ambienLight);
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-10, 20, -5);
spotLight.castShadow = true;
scene.add(spotLight);
document.body.appendChild(renderer.domElement);
renderer.render(scene, camera);
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.132.2/build/three.min.js"></script>

Related

Animating rotation of object based on new pivot in Three.js

I want to do this in Three.JS:
I did the spiral and downward movement, but I don't do the knocking motion.
var planeGeometry = new THREE.PlaneGeometry(10,10);
var planeMaterial = new THREE.MeshBasicMaterial({color: 0x828282, wireframe: false, side: THREE.DoubleSide});
var planeMesh = new THREE.Mesh(planeGeometry, planeMaterial);
planeMesh.rotation.x = 1.0 * THREE.Math.degToRad(90);
scene.add(planeMesh);
var cylinderGeometry = new THREE.CylinderGeometry(0.2, 0.2, 14);
var cylinderMaterial = new THREE.MeshBasicMaterial({color: 0x00ff00, wireframe: false});
var cylinderMesh = new THREE.Mesh(cylinderGeometry, cylinderMaterial);
cylinderMesh.position.set(0,7,0);
scene.add(cylinderMesh);
groupDown = new THREE.Group();
groupSpiral = new THREE.Group();
groupKnock = new THREE.Group();
var woodPeckerGeometry = new THREE.BoxGeometry(1,3,2);
var woodPeckerMaterial = new THREE.MeshBasicMaterial({color: 0xffffff, wireframe: false});
var woodPeckerMesh = new THREE.Mesh(woodPeckerGeometry , woodPeckerMaterial );
groupDown.add(woodPeckerMesh );
groupDown.position.set(0, 10, 2);
groupSpiral.add(groupDown)
groupKnock.add(groupSpiral)
scene.add(groupKnock);
and the render function:
var render = function () {
groupDown.position.y -= 0.03;
if(groupDown.position.y < 1.6) {
groupDown.position.y = 13;
}
groupSpiral.rotation.y += 0.03;
};
So the question is that how can I do knocking motion?
You could increase the groupDown rotation on the z axis like you did with its position and the "woodpecker" would start to knock on the cylinder. The problem with this is that the pivot for the rotation is at the center of the box.
To fix this, you can add the "woodpecker" to a group (i.e. pivotGroup), set its position up relative to its height on this new group and treat pivotGroup as the new object for animation. This way, the box would rotate from its base.
See the complete example below.
var camera, scene, renderer, groupSpiral, groupDown, groupKnock;
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 10, 10000);
camera.position.z = 30;
camera.position.y = 24;
camera.rotation.x = -0.55;
scene.add(camera);
var planeGeometry = new THREE.PlaneGeometry(10, 10);
var planeMaterial = new THREE.MeshBasicMaterial({color: 0x828282, wireframe: false, side: THREE.DoubleSide});
var planeMesh = new THREE.Mesh(planeGeometry, planeMaterial);
planeMesh.rotation.x = 1.0 * THREE.Math.degToRad(90);
planeMesh.rotation.z = 1.0 * THREE.Math.degToRad(45);
scene.add(planeMesh);
var cylinderGeometry = new THREE.CylinderGeometry(0.3, 0.3, 14);
var cylinderMaterial = new THREE.MeshBasicMaterial({color: 0x00ff00, wireframe: false});
var cylinderMesh = new THREE.Mesh(cylinderGeometry, cylinderMaterial);
cylinderMesh.position.y = 7;
scene.add(cylinderMesh);
var coneGeometry = new THREE.ConeGeometry(0.3, 1, 32);
var coneMaterial = new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: false});
var coneMesh = new THREE.Mesh(coneGeometry, coneMaterial);
coneMesh.position.set(1, 1.8, 0);
coneMesh.rotation.z = Math.PI / -2;
groupDown = new THREE.Group();
groupSpiral = new THREE.Group();
groupKnock = new THREE.Group();
var woodPeckerGeometry = new THREE.BoxGeometry(1, 3, 1.5);
var woodPeckerMaterial = new THREE.MeshBasicMaterial({color: 0xffffff, wireframe: false});
var woodPeckerMesh = new THREE.Mesh(woodPeckerGeometry, woodPeckerMaterial);
woodPeckerMesh.position.set(0, 1, 0);
woodPeckerMesh.rotation.set(0, 0, Math.PI);
groupKnock.add(coneMesh);
groupKnock.add(woodPeckerMesh);
groupDown.add(groupKnock);
groupDown.position.set(0, 12, 1.5);
groupDown.rotation.y = Math.PI / 2;
groupSpiral.add(groupDown)
scene.add(groupSpiral);
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
$(renderer.domElement).appendTo("body");
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
groupDown.position.y -= 0.03;
if(groupDown.position.y < 1.6) {
groupDown.position.y = 12;
}
groupSpiral.rotation.y += 0.03;
groupKnock.rotation.z += 0.035;
if(groupKnock.rotation.z > Math.PI/6) {
groupKnock.rotation.z = 0;
}
renderer.render(scene, camera);
}
$(document).ready(function() {
init();
animate();
});
* {
padding: 0;
margin: 0;
overflow: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/109/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

How to reflect an image on a IcosahedronGeometry in three.js?

I would like to make IcosahedronGeometry in three.js and reflect an image on the front side of the geometry.
I already made a IcosahedronGeometry and made it rotate on it's axis.
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
// RENDERER
var renderer = new THREE.WebGLRenderer({
antialias: true
});
// RENDERER - SIZE OF CANVAS
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor('#ffffff');
document.body.appendChild(renderer.domElement);
// RESPONSIVE RENDERING
window.addEventListener('resize', () => {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
});
var groundMaterial = new THREE.MeshPhongMaterial({
shininess: 100,
color: 0xffffff,
specular: 0xffffff
});
const cubeCamera = new THREE.CubeCamera(75, 1000, 512);
scene.add(cubeCamera);
// GEOMETRY
var geometry = new THREE.IcosahedronGeometry(2, 1);
var material = new THREE.MeshStandardMaterial({
color: 0x98bbbd,
side: THREE.FrontSides,
roughness: 1,
metalness: 0.5,
envMap: cubeCamera.renderTarget
});
material.roughness = 0;
material.metalness = 1;
material.flatShading = true;
material.envMap = cubeCamera.renderTarget.texture;
var sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);
console.log(sphere.position);
console.log(cubeCamera.position);
cubeCamera.position.copy(sphere.position);
cubeCamera.update(renderer, scene);
// FLOOR
var floorTexture = new THREE.ImageUtils.loadTexture('images/woman.png');
// floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping;
// floorTexture.repeat.set(1000, 1000);
var floorMaterial = new THREE.MeshBasicMaterial({
map: floorTexture,
side: THREE.BackSide
});
var floorGeometry = new THREE.PlaneGeometry(5, 5, 1, 1);
var floor = new THREE.Mesh(floorGeometry, floorMaterial);
floor.position.y = 0;
floor.position.x = 0;
floor.position.z = 3;
scene.add(floor);
cubeCamera.lookAt(floor);
// CONTROLS
var orbit = new THREE.OrbitControls(camera, renderer.Mesh);
camera.position.z = 5;
// LIGHTS
var topLeftLight = new THREE.PointLight(0xffffff, 1, 1);
topLeftLight.position.set(-50, 50, -25);
scene.add(topLeftLight);
var topRightLight = new THREE.PointLight(0xffffff, 1, 10);
topRightLight.position.set(50, 150, -25);
scene.add(topRightLight);
var lightBottomRight = new THREE.PointLight(0xffffff, 1, 100);
lightBottomRight.position.set(40, -50, 25);
scene.add(lightBottomRight);
var lightBottomLeft = new THREE.PointLight(0xffffff, 1, 100);
lightBottomLeft.position.set(-40, -50, 25);
scene.add(lightBottomLeft);
var lightTopRight = new THREE.PointLight(0xffffff, 1, 100);
lightTopRight.position.set(40, 50, 25);
scene.add(lightTopRight);
var lightTopLeft = new THREE.PointLight(0xffffff, 1, 100);
lightTopLeft.position.set(-40, 50, 25);
scene.add(lightTopLeft);
var backLight = new THREE.PointLight(0xffffff, 1, 100);
backLight.position.set(0, 0, -25);
scene.add(backLight);
var light = new THREE.AmbientLight(0x404040, 2); // soft white light
scene.add(light);
// update function
function render() {
requestAnimationFrame(render);
sphere.rotation.x += 0.005;
sphere.rotation.y += 0.005;
sphere.visible = false;
cubeCamera.update(renderer, scene);
sphere.visible = true;
renderer.render(scene, camera);
}
render();
I would like to see a rotating IcosahedronGeometry which reflects an image on the front side. I tried adding a cube camera and pointing it at the PlaneGeometry with an image texture but nothing is reflecting.
I would like to simulate something like this, but it doesn't have to be exactly the same.
The desired result.
3 issues.
you have to call cubeCamera.update before you access cubeCamera.renderTarget.texture
The parameters to CubeCamera are new CubeCamera(near, far, size).
The code had new CubeCamera(75, 1000, 512) which means only things 75 to 1000 units away from the camera would be visible. The image plane you had is 3 units away so would not be visible.
You don't call lookAt with the CubeCamera as it's always looking in all directions.
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
// RENDERER
var renderer = new THREE.WebGLRenderer({
antialias: true
});
// RENDERER - SIZE OF CANVAS
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor('#ffffff');
document.body.appendChild(renderer.domElement);
// RESPONSIVE RENDERING
window.addEventListener('resize', () => {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
});
var groundMaterial = new THREE.MeshPhongMaterial({
shininess: 100,
color: 0xffffff,
specular: 0xffffff
});
const cubeCamera = new THREE.CubeCamera(0.001, 10, 512);
scene.add(cubeCamera);
// GEOMETRY
var geometry = new THREE.IcosahedronGeometry(2, 1);
var material = new THREE.MeshStandardMaterial({
color: 0x98bbbd,
side: THREE.FrontSide,
roughness: 1,
metalness: 0.5,
});
cubeCamera.update(renderer, scene);
material.roughness = 0;
material.metalness = 1;
material.flatShading = true;
material.envMap = cubeCamera.renderTarget.texture;
var sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);
// FLOOR
var loader = new THREE.TextureLoader();
var floorTexture = loader.load('https://i.imgur.com/UKBsvV0.jpg');
var floorMaterial = new THREE.MeshBasicMaterial({
map: floorTexture,
side: THREE.BackSide
});
var floorGeometry = new THREE.PlaneGeometry(5, 5, 1, 1);
var floor = new THREE.Mesh(floorGeometry, floorMaterial);
floor.position.y = 0;
floor.position.x = 0;
floor.position.z = 3;
scene.add(floor);
// CONTROLS
var orbit = new THREE.OrbitControls(camera, renderer.Mesh);
camera.position.z = 5;
// LIGHTS
var topLeftLight = new THREE.PointLight(0xffffff, 1, 1);
topLeftLight.position.set(-50, 50, -25);
scene.add(topLeftLight);
var topRightLight = new THREE.PointLight(0xffffff, 1, 10);
topRightLight.position.set(50, 150, -25);
scene.add(topRightLight);
var lightBottomRight = new THREE.PointLight(0xffffff, 1, 100);
lightBottomRight.position.set(40, -50, 25);
scene.add(lightBottomRight);
var lightBottomLeft = new THREE.PointLight(0xffffff, 1, 100);
lightBottomLeft.position.set(-40, -50, 25);
scene.add(lightBottomLeft);
var lightTopRight = new THREE.PointLight(0xffffff, 1, 100);
lightTopRight.position.set(40, 50, 25);
scene.add(lightTopRight);
var lightTopLeft = new THREE.PointLight(0xffffff, 1, 100);
lightTopLeft.position.set(-40, 50, 25);
scene.add(lightTopLeft);
var backLight = new THREE.PointLight(0xffffff, 1, 100);
backLight.position.set(0, 0, -25);
scene.add(backLight);
var light = new THREE.AmbientLight(0x404040, 2); // soft white light
scene.add(light);
// update function
function render() {
sphere.rotation.x += 0.005;
sphere.rotation.y += 0.005;
sphere.visible = false;
cubeCamera.update(renderer, scene);
sphere.visible = true;
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r105/three.min.js"></script>
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r105/js/controls/OrbitControls.js"></script>

three.js rendering text to scene

I'm new at three.js.
In my work, I have to made 3d graphical website.
So after searched in google, I found that three.js is suitable to manipulate WebGL conveniently.
In three.js document(https://threejs.org/docs/#api/en/geometries/TextGeometry),
TextGeometry is API for draw text in the scene.
[src.js]
init = () => {
window.addEventListener('resize', resizeWindow);
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 10000);
var controls = new THREE.OrbitControls( camera );
controls.update();
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xdd3b56);
renderer.setSize(window.innerWidth, window.innerHeight);
// Set shadow
renderer.shadowMap.enabled = true;
// Show Axis
var axes = new THREE.AxisHelper(5);
scene.add(axes);
// Text
var loader = new THREE.FontLoader();
loader.load( './helvetiker_regular.typeface.json', function ( font ) {
var geometry = new THREE.TextGeometry( 'Hello three.js!', {
font: font,
size: 80,
height: 5,
curveSegments: 12,
bevelEnabled: true,
bevelThickness: 10,
bevelSize: 8,
bevelSegments: 5
} );
} );
var textMaterial = new THREE.MeshPhongMaterial({color: 0xFE98A0});
var text = new THREE.Mesh(geometry, textMaterial);
text.position.x = 0;
text.position.y = 10;
text.position.z = 10;
scene.add(text);
// Light
var spotLight = new THREE.SpotLight(0xFFFFFF);
spotLight.position.set(-40, 60, 30);
spotLight.castShadow = true;
spotLight.shadow.mapSize.width = 5120;
spotLight.shadow.mapSize.height = 5120;
scene.add(spotLight);
// Camera Setting
camera.position.x = 0;
camera.position.y = 30;
camera.position.z = 30;
camera.lookAt(scene.position);
document.getElementById("threejs_scene").appendChild(renderer.domElement);
renderScene();
function renderScene() {
requestAnimationFrame(renderScene);
controls.update();
renderer.render(scene, camera);
}
}
window.onload = init();
[index.html]
<html>
<head>
<script src="three.js"></script>
<script src="OrbitControls.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="threejs_scene"></div>
<script src="src.js"></script>
</body>
</html>
When I execute my code, it throws [.WebGL-0x7fb612852000]RENDER WARNING: Render count or primcount is 0. and WebGL: too many errors, no more errors will be reported to the console for this context. errors.
So I searched it at google, it occured when Three.js is trying to render an object that does not exist yet.
But in my code, I already defined it.
var textMaterial = new THREE.MeshPhongMaterial({color: 0xFE98A0});
var text = new THREE.Mesh(geometry, textMaterial);
text.position.x = 0;
text.position.y = 10;
text.position.z = 10;
How can I solve this issue?
My last goal is display text in the scene.
Thanks.
window.onload = function(params) {
/*
*
* SET UP THE WORLD
*
*/
//set up the ratio
var gWidth = window.innerWidth;
var gHeight = window.innerHeight;
var ratio = gWidth / gHeight;
var borders = [40, 24] //indicate where the ball needs to move in mirror position
var light = new THREE.AmbientLight(0xffffff, 0.5);
var light1 = new THREE.PointLight(0xffffff, 0.5);
light1.position.set(0, 5, 0);
light1.castShadow = true;
// set the renderer
var renderer = new THREE.WebGLRenderer();
var camera = new THREE.PerspectiveCamera();
camera.position.set(10, 10, 10);
camera.lookAt(new THREE.Vector3(0, 0, 0));
//properties for casting shadow
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setSize(gWidth, gHeight);
document.body.appendChild(renderer.domElement);
var scene = new THREE.Scene();
scene.add(light);
scene.add(light1);
var ground = new THREE.Mesh(new THREE.BoxGeometry(10, 0.5, 10), new THREE.MeshLambertMaterial())
ground.receiveShadow = true;
scene.add(ground)
var geometry;
var loader = new THREE.FontLoader();
var mesh;
requestAnimationFrame(render);
function render() {
if (mesh) {
mesh.rotation.y += 0.01;
mesh.rotation.z += 0.007;
}
renderer.render(scene, camera);
requestAnimationFrame(render);
}
loader.load('https://cdn.rawgit.com/mrdoob/three.js/master/examples/fonts/helvetiker_regular.typeface.json', function(font) {
var geometry = new THREE.TextGeometry('Hello three.js!', {
font: font,
size: 80,
height: 5,
curveSegments: 12,
bevelEnabled: true,
bevelThickness: 10,
bevelSize: 8,
bevelSegments: 5
});
var material = new THREE.MeshLambertMaterial({
color: 0xF3FFE2
});
mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, 2, 0);
mesh.scale.multiplyScalar(0.01)
mesh.castShadow = true;
scene.add(mesh);
var canv = document.createElement('canvas')
canv.width = canv.height = 256;
var ctx = canv.getContext('2d')
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, canv.width, canv.height);
ctx.fillStyle = 'black'
ctx.fillText("HERE IS SOME 2D TEXT", 20, 20);
var tex = new THREE.Texture(canv);
tex.needsUpdate = true;
var mat = new THREE.MeshBasicMaterial({
map: tex
});
var plane = new THREE.Mesh(new THREE.PlaneGeometry(10, 10), mat);
scene.add(plane)
});
}
body {
padding: 0;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.min.js"></script>
<html>
<head>
</head>
<body>
</body>
</html>

create a 3D object by adding a default height javascript

I have this code which should create a 3D form. The idea is that I have whatever coordinates stored into a vector in the same plan to which I should add a default height in order to make it 3D. As you can see I am a beginner in programming and this is the first time I use ThreeJS so can you tell me what am I doing wrong? Honestly I have no clue and I would like to know if there is another way of adding the default height to my 2D vector coordinates in order to make it 3D without using ThreeJS. Thank you!
$(document).ready(function(){
function storeCoordinate(x, y, array) {
array.push(x);
array.push(y);
}
var coords = [];
var z=500;
storeCoordinate(3, 5, coords);
storeCoordinate(10, 100, coords);
storeCoordinate(30, 120, coords);
storeCoordinate(3, 5, coords);
for (var i = 0; i < coords.length; i+=2) {
var x = coords[i];
var y = coords[i+1];
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var shape = new THREE.Shape( coords );
ctx.moveTo(coords[i],coords[i+1]);
ctx.lineTo(coords[i+2],coords[i+3]);
ctx.stroke();
}
var render,mycanvas,scene,camera,renderer,light;
init();
animate();
function init(){
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 1, 1000 );
var extrudedGeometry = new THREE.ExtrudeGeometry(shape, {amount: 5, bevelEnabled: false});
var extrudedMesh = new THREE.Mesh(extrudedGeometry, new THREE.MeshPhongMaterial({color: 0xff0000}));
scene.add(extrudedMesh);
document.body.onmousemove = function(e){
extrudedMesh.rotation.z = e.pageX / 100;
extrudedMesh.rotation.x = e.pageY / 100;
}
//lights
dirLight = new THREE.DirectionalLight(0xffffff);
dirLight.intensity = .9;
dirLight.position.set(500, 140, 500);
dirLight.castShadow = true;
dirLight.shadowMapHeight = 2048
dirLight.shadowMapWidth = 2048
dirLight.shadowDarkness = .15
spotLight = new THREE.PointLight( 0xffffff );
spotLight.intensity = .5
spotLight.position.set( -500, 140, -500 );
camera.add( spotLight)
camera.add(dirLight);
lighthelper = new THREE.DirectionalLightHelper(dirLight, 20);
lighthelper.children[1].material.color.set(0,0,0)
lighthelper.visible = false;
scene.add(lighthelper);
ambientLight = new THREE.AmbientLight( 0x020202, 1 );
scene.add( ambientLight );
light = new THREE.PointLight(0xffffff);
light.position.set(-100,200,100);
scene.add(light);
renderer = new THREE.WebGLRenderer({canvas: mycanvas});
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.autoRotate = true;
controls.enableZoom = true;
controls.enablePan = true;
controls.rotateSpeed = 3.0;
controls.zoomSpeed = 1.0;
controls.panSpeed = 2.0;
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.minDistance = 1.1;
controls.maxDistance = 1000;
controls.keys = [65, 83, 68]; // [ rotateKey, zoomKey, panKey ]
}
function animate() {
window.requestAnimationFrame( animate );
render();
}
function render() {
renderer.render( scene, camera );
}
var loader = new THREE.OBJLoader();
});
Just an option of how you can do it, using THREE.ExtrudeGeometry():
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 3);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var grid = new THREE.GridHelper(5, 10, "white", "gray");
grid.geometry.rotateX(Math.PI * 0.5);
scene.add(grid);
var points = [
new THREE.Vector2(0, 1),
new THREE.Vector2(1, 1),
new THREE.Vector2(1, 0)
]
var shape = new THREE.Shape(points);
var extrudeGeom = new THREE.ExtrudeGeometry(shape, {
amount: 0.5,
bevelEnabled: false
});
var mesh = new THREE.Mesh(extrudeGeom, new THREE.MeshBasicMaterial({
color: "aqua",
wireframe: true
}));
scene.add(mesh);
render();
function render() {
requestAnimationFrame(render)
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/92/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

THREE.JS does not cast shadows

I was doing a Three js tutorial and this code should cast shadows, but when render shadows does not exists over the plane.
What is wrong on code? I'm reading documentation and other codes and I can not find the problem.
Best regards!
EDIT:
If i make a loop with requestAnimationFrame just works... but only in that case... why?
<!DOCTYPE html>
<html>
<head>
<title>Learning THREE JS Basic</title>
<script src="../../libs/three.js"></script>
<script src="../../libs/jquery.js"></script>
<style>
body {
margin : 0;
overflow : hidden;
}
</style>
</head>
<body>
<div id="visor"></div>
<script>
$(function () {
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xEEEEEE);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
var axes = new THREE.AxisHelper(20);
scene.add(axes);
var planeGeometry = new THREE.PlaneGeometry(60, 20, 1, 1);
var planeMaterial = new THREE.MeshLambertMaterial({
color: 0xFFFFFF
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -0.5*Math.PI;
plane.position.x = 15;
plane.position.y = 0;
plane.position.z = 0;
plane.receiveShadow = true;
scene.add(plane);
var cubeGeometry = new THREE.BoxGeometry(4,4,4);
var cubeMaterial = new THREE.MeshLambertMaterial({
color: 0xFF0000
});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.x = -4;
cube.position.y = 3;
cube.position.z = 0;
cube.castShadow = true;
scene.add(cube);
var sphereGeometry = new THREE.SphereGeometry(4, 20, 20);
var sphereMaterial = new THREE.MeshLambertMaterial({
color: 0x7777FF
});
var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.x = 20;
sphere.position.y = 4;
sphere.position.z = 2;
sphere.castShadow = true;
scene.add(sphere);
var spotLight = new THREE.SpotLight(0xFFFFFF);
spotLight.position.set(-40, 60, -10);
spotLight.castShadow = true;
scene.add(spotLight);
camera.position.x = -30;
camera.position.y = 40;
camera.position.z = 30;
camera.lookAt(scene.position);
$("#visor").append(renderer.domElement);
renderer.render(scene, camera);
});
</script>
</body>
</html>
three.js r.74 and r.75 have a bug in which shadows are not always rendered in the first call to render(). This bug has been fixed in three.js r.76dev.
Your work-around is to call renderer.render( scene, camera ) a 2nd time, or to have an animation loop.
three.js r.75

Categories