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>
Related
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>
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>
I've created a 3D marquee by bending two meshes into a circle, however I'm having trouble getting them to center to the camera.
Please reference https://jsfiddle.net/siiiick/1jh49e1u/
var text = "EXPRESS FREE SHIPPING WORLDWIDE OVER 200€ / 200% 150$ ";
var geoParams = {
size: 208,
height: 1,
curveSegments: 4,
font: "junicode",
// bevelEnabled: false,
// bevelThickness: 1,
// bevelSize: 1,
}
var textMaterial = new THREE.MeshPhongMaterial({
color: 0x000000
});
var deg = Math.PI / 4.8;
var geoTop = new THREE.TextGeometry(text, geoParams);
var textTop = new THREE.Mesh(geoTop, textMaterial);
geoTop.computeBoundingBox();
textWidth = geoTop.boundingBox.max.x - geoTop.boundingBox.min.x;
controls.target.set(-textWidth * .1 - 10, 0, -textWidth / 3.8);
textTop.rotation.y = Math.PI;
modifier.set(new THREE.Vector3(0, 0, -1), new THREE.Vector3(0, 1, 0), deg).modify(textTop.geometry);
modifier.set(new THREE.Vector3(0, 0, -1), new THREE.Vector3(0, 1, 0), deg).modify(textTop.geometry);
textTop.position.set(-0.5 * textWidth + textWidth * .867, 0, -textWidth * .577);
var geoBot = new THREE.TextGeometry(text, geoParams);
var textBot = new THREE.Mesh(geoBot, textMaterial);
modifier.set(new THREE.Vector3(0, 0, -1), new THREE.Vector3(0, 1, 0), deg).modify(textBot.geometry);
modifier.set(new THREE.Vector3(0, 0, -1), new THREE.Vector3(0, 1, 0), deg).modify(textBot.geometry);
textBot.position.set(-0.5 * textWidth, 0, 0);
scene.add(textTop);
scene.add(textBot);
As you can see after a few seconds the the marquee isn't centered. Do you think it's as a result of the camera positioning or the mesh positioning?
Thanks
//Testing some easy camera centering code...
var renderer = new THREE.WebGLRenderer();
var w = 300;
var h = 200;
renderer.setSize(w, h);
document.body.appendChild(renderer.domElement);
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
45, // Field of view
w / h, // Aspect ratio
0.1, // Near
10000 // Far
);
camera.position.set(15, 10, 15);
camera.lookAt(scene.position);
controls = new THREE.OrbitControls(camera, renderer.domElement);
var light = new THREE.PointLight(0xFFFF00);
light.position.set(20, 20, 20);
scene.add(light);
var light1 = new THREE.AmbientLight(0x808080);
light1.position.set(20, 20, 20);
scene.add(light1);
var light2 = new THREE.PointLight(0x00FFFF);
light2.position.set(-20, 20, -20);
scene.add(light2);
var light3 = new THREE.PointLight(0xFF00FF);
light3.position.set(-20, -20, -20);
scene.add(light3);
var sphereGeom = new THREE.SphereGeometry(5, 16, 16);
var material = new THREE.MeshLambertMaterial({
color: 0x808080
});
var mesh = new THREE.Mesh(sphereGeom, material);
scene.add(mesh);
var mesh1 = new THREE.Mesh(sphereGeom, material);
mesh1.position.x += 5;
mesh.add(mesh1);
var mesh2 = new THREE.Mesh(sphereGeom, material);
mesh2.position.y += 5;
mesh2.position.x += 9;
mesh.add(mesh2);
var grp0 = mesh;
var mesh = new THREE.Mesh(sphereGeom, material);
scene.add(mesh);
mesh.position.x += 30;
var mesh1 = new THREE.Mesh(sphereGeom, material);
mesh1.position.x += 15;
mesh.add(mesh1);
var mesh2 = new THREE.Mesh(sphereGeom, material);
mesh2.position.y += 12;
mesh2.position.x += 9;
mesh.add(mesh2);
renderer.setClearColor(0xdddddd, 1);
var grp1 = mesh;
var curGrp;
var targPos;
var targLook;
var tmp = new THREE.Vector3();
var vbox;
function focusCam(targ) {
const boundingBox = new THREE.Box3();
boundingBox.setFromObject(targ)
var center = boundingBox.getCenter(new THREE.Vector3())
var sz = boundingBox.getSize(new THREE.Vector3());
var minZ = sz.length() + camera.near;
var lookOffset = new THREE.Vector3(0, 0, 1);
lookOffset.applyQuaternion(camera.quaternion);
lookOffset.multiplyScalar(minZ)
targLook = center.clone();
targPos = new THREE.Vector3().copy(center).add(lookOffset)
if (!vbox) {
vbox = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), material.clone())
vbox.material.transparent = true;
vbox.material.opacity = 0.15;
scene.add(vbox)
}
vbox.scale.copy(sz);
vbox.position.copy(center);
}
renderer.domElement.onclick = (evt) => {
if (!curGrp) {
curGrp = grp0;
} else if (curGrp === grp0) {
curGrp = grp1
} else if (curGrp === grp1) {
curGrp = grp0
}
focusCam(curGrp);
}
(function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
if (targPos) {
tmp.copy(targPos).sub(camera.position).multiplyScalar(0.01)
if (tmp.length() > 0.01) {
camera.position.add(tmp)
controls.target.add(tmp);//copy(targLook);
//camera.lookAt(targLook);
} else targPos = undefined;
}
})();
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>
Okay. I'm clearly missing something here. I'm simply trying to get this code to cast shadows. I've turned on receive shadows and cast shadows for the cube and the floor but it still isn't showing. This shouldn't be this hard. I've used casting shadows before however I'm clearing missing something here. Any ideas would help. I'm at a loss because I know casting shadows isn't that hard. I must be missing something obvious.
Thanks in advance.
var camera, scene, renderer;
var RED = 0xff3300;
init();
render();
function init() {
renderer = new THREE.WebGLRenderer();
//renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(window.innerWidth, window.innerHeight);
-
document.body.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 15000);
camera.position.set(1000, 500, 1000);
camera.lookAt(new THREE.Vector3(0, 200, 0));
scene = new THREE.Scene();
scene.background = new THREE.Color(0xcccccc);
var light = new THREE.SpotLight(0xdddddd, 1);
light.position.set(50, 600, 50);
scene.add(light);
var coloredCube = createCube(100, 100, 100, 0, 300, 0, 0, RED);
coloredCube.castShadow = true;
coloredCube.receiveShadow = true;
scene.add(coloredCube);
//create floor
var planeFloor = createSizedPlane(1000, 1000);
planeFloor = preparePlaneForScene(planeFloor, Math.PI / -2, 0, 0, 0, 0, 0);
planeFloor.castShadow = true;
planeFloor.receiveShadow = true;
scene.add(planeFloor);
}
function render() {
renderer.render(scene, camera);
}
function createSizedPlane(xSize, zSize, numberOfSegments) {
var planeGeometry = new THREE.PlaneGeometry(xSize, zSize, numberOfSegments);
planeGeometry.receiveShadow = true;
planeGeometry.castShadow = true;
var material = new THREE.MeshStandardMaterial({
roughness: 0.8,
color: 0xffffff,
metalness: 0.2,
bumpScale: 0.0005,
opacity: 1, transparent: false
}
);
return new THREE.Mesh(planeGeometry, material);
}
function preparePlaneForScene(plane, xRotation, yRotation, zRotation, xPosition, yPosition, zPosition) {
plane.rotation.x = xRotation;
plane.rotation.y = yRotation;
plane.rotation.z = zRotation;
plane.position.x = xPosition;
plane.position.y = yPosition;
plane.position.z = zPosition;
return plane;
}
function createCube(xSize, ySize, zSize, xPosition, yPosition, zPosition, yRotation, color) {
var cubeGeometry = new THREE.BoxGeometry(xSize, ySize, zSize);
var cubeMaterial = new THREE.MeshLambertMaterial({color: color});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.x = xPosition;
cube.position.y = yPosition;
cube.position.z = zPosition;
cube.rotation.y = yRotation;
cube.castShadow = true;
cube.receiveShadow = true;
return cube;
}
Enable shadowMap for renderer and casting shadow for light:
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFShadowMap;
spotLight.castShadow = true;
spotLight.shadow = new THREE.LightShadow(new THREE.PerspectiveCamera(60, 1, 1, 2500));
spotLight.shadow.bias = 0.0001;
spotLight.shadow.mapSize.width = 1024;
spotLight.shadow.mapSize.height = 1024;
THREE.SpotLightShadow should work too.
For directional light you would need orthographic projection (or use THREE.DirectionalLightShadow).
camera :
Camera = new THREE.PerspectiveCamera(45, Width / Height, 0.1, 10000);
Camera.position.set( 150, 400, 400);
Scene.add(Camera);
Light
Light = new THREE.SpotLight(0xffccff,.5, 0, Math.PI/2, 1);
Light.position.set(0, 2000, 0);
Light.castShadow = true;
Light.shadowBias = -0.0002;
Light.shadowCameraNear = 850;
Light.shadowCameraFar = 8000;
Light.shadowCameraFov = 600;
Light.shadowDarkness = .7;
Light.shadowMapWidth = 2048;
Light.shadowMapHeight = 2048;
Scene.add(Light);
Renderer
Renderer = new THREE.WebGLRenderer({
antialias: true,
sortObjects: false,
preserveDrawingBuffer: true,
shadowMapEnabled: true
});
document.body.appendChild(Renderer.domElement);
Renderer.shadowMap.type = THREE.PCFSoftShadowMap;
Renderer.shadowMap.cullFace = THREE.CullFaceBack;
Renderer.gammaInput = true;
Renderer.gammaOutput = true;
Renderer.setSize(window.innerWidth, window.innerHeight);
i use this function to add 3d model
function getModel(path,texture) {
var Material = new THREE.MeshPhongMaterial({shading: THREE.SmoothShading,
specular: 0xff9900,
shininess: 0,
side: THREE.DoubleSide,
shading: THREE.SmoothShading
});
Loader = new THREE.JSONLoader();
Loader.load(path,function(geometry){
geometry.mergeVertices();
geometry.computeFaceNormals();
geometry.computeVertexNormals();
TextureLoader.load(texture,function(texture){
Mesh = new THREE.Mesh(geometry, Material);
Mesh.material.map =texture;
Mesh.material.map.wrapS = THREE.RepeatWrapping;
Mesh.material.map.wrapT = THREE.RepeatWrapping;
Mesh.material.map.repeat.set(38,38);
//Mesh.position.y -= 1;
Mesh.position.y = 160;
Mesh.position.x = 0;
Mesh.position.z = 0;
Mesh.scale.set(40,40,40);
Mesh.castShadow = true;
Mesh.receiveShadow = true;
Scene.add(Mesh);
});
});
}
and the plane to recive shadow is
var planeGeometry = new THREE.PlaneBufferGeometry(100,100);
var planematerial = new THREE.MeshLambertMaterial(
{
shininess: 80,
color: 0xffaaff,
specular: 0xffffff
});
var plane = new THREE.Mesh(planeGeometry,planematerial);
plane.rotation.x = - Math.PI / 2;
plane.position.set(0,100,0);
plane.scale.set( 10, 10, 10 );
plane.receiveShadow = true;
plane.castShadow = true;
Scene.add(plane);
I just tried adjusting the position of the lights and adjusted the values of shadowCameraNear,Light.shadowCameraFar and Light.shadowCameraFov .but not no changes are seen
The camera is at (150, 400, 400), the object casting the shadow is at (0, 160, 0), the object receiving the shadow is at (0, 100, 0) and the shadowCameraNear frustum is set at 850. That is, your camera is about 200 and 400 units from the two shadowing objects, respectively, but your shadow viewing near frustum is 850 units away. Adjust your positioning. You can set
Light.shadowCameraVisible = true;
to show the camera frustum in debug mode to help out.