My project uses geometry where each face is its own mesh. I need to clip the geometry to cut away a portion of it and have a stenciled cap face cover the clipped edges. I examined and tinkered with the Three.js clipping stencil example and I understand how to use a stencil to cap trimmed solid geometry, but when I try it on collections of face geometries it doesn't work. Here is some code I have been tinkering with, based on the example:
body { margin: 0; }
canvas { display: block; }
<script type="module">
import * as THREE from 'https://unpkg.com/three#0.120.1/build/three.module.js';
import { OrbitControls } from 'https://unpkg.com/three#0.120.1/examples/jsm/controls/OrbitControls.js';
import { BufferGeometryUtils } from 'https://unpkg.com/three#0.120.1/examples/jsm/utils/BufferGeometryUtils.js';
var camera, scene, renderer;
var planes, planeObjects;
init();
animate();
function createPlaneStencilGroup( geometry, plane, renderOrder )
{
var group = new THREE.Group();
var baseMat = new THREE.MeshBasicMaterial();
baseMat.depthWrite = false;
baseMat.depthTest = false;
baseMat.colorWrite = false;
baseMat.stencilWrite = true;
baseMat.stencilFunc = THREE.AlwaysStencilFunc;
// back faces
var mat0 = baseMat.clone();
mat0.side = THREE.BackSide;
mat0.clippingPlanes = [ plane ];
mat0.stencilFail = THREE.IncrementWrapStencilOp;
mat0.stencilZFail = THREE.IncrementWrapStencilOp;
mat0.stencilZPass = THREE.IncrementWrapStencilOp;
var mesh0 = new THREE.Mesh( geometry, mat0 );
mesh0.renderOrder = renderOrder;
group.add( mesh0 );
// front faces
var mat1 = baseMat.clone();
mat1.side = THREE.FrontSide;
mat1.clippingPlanes = [ plane ];
mat1.stencilFail = THREE.DecrementWrapStencilOp;
mat1.stencilZFail = THREE.DecrementWrapStencilOp;
mat1.stencilZPass = THREE.DecrementWrapStencilOp;
var mesh1 = new THREE.Mesh( geometry, mat1 );
mesh1.renderOrder = renderOrder;
group.add( mesh1 );
return group;
}
function init()
{
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 36, window.innerWidth / window.innerHeight, 1, 100 );
camera.position.set( 2, 2, 2 );
initLights();
planes = [
new THREE.Plane( new THREE.Vector3( 0, - 1, 0 ), 0.42 ),
new THREE.Plane( new THREE.Vector3( 0, 0, - 1 ), 0.25 )
];
var material = new THREE.MeshStandardMaterial( {
color: 0x00ff00,
metalness: 0.1,
roughness: 0.75,
side: THREE.DoubleSide,
clippingPlanes: planes,
clipShadows: true,
shadowSide: THREE.DoubleSide,
} );
// Simple sphere geometry. Something I know works, for comparison.
var sphereGeom = new THREE.SphereBufferGeometry( 0.5, 32, 32 );
sphereGeom.translate( -1.1, 0, 0 );
// Make a cube out of 6 planes and merge them together
var planeGeoms = [];
for(var i = 0; i < 6; i++)
{
planeGeoms.push( new THREE.PlaneBufferGeometry( 1, 1 ) );
}
var mergedBufferGeom = BufferGeometryUtils.mergeBufferGeometries( planeGeoms );
// Set up clip plane rendering
planeObjects = [];
var planeGeom = new THREE.PlaneBufferGeometry( 4, 4 );
for ( var i = 0; i < 2; i ++ )
{
var poGroup = new THREE.Group();
var plane = planes[ i ];
var stencilGroup_sphere = createPlaneStencilGroup( sphereGeom, plane, i + 1 );
var stencilGroup_Box = createPlaneStencilGroup( mergedBufferGeom, plane, i + 1 )
// plane is clipped by the other clipping planes
var planeMat = new THREE.MeshStandardMaterial( {
color: 0x0000ff,
metalness: 0.1,
roughness: 0.75,
clippingPlanes: planes.filter( p => p !== plane ),
stencilWrite: true,
stencilRef: 0,
stencilFunc: THREE.NotEqualStencilFunc,
stencilFail: THREE.ReplaceStencilOp,
stencilZFail: THREE.ReplaceStencilOp,
stencilZPass: THREE.ReplaceStencilOp,
} );
var po = new THREE.Mesh( planeGeom, planeMat );
po.onAfterRender = function ( renderer ) {
renderer.clearStencil();
};
po.renderOrder = i + 1.1;
plane.coplanarPoint( po.position );
po.lookAt(
po.position.x - plane.normal.x,
po.position.y - plane.normal.y,
po.position.z - plane.normal.z,
);
scene.add( stencilGroup_sphere );
scene.add( stencilGroup_Box );
poGroup.add( po );
planeObjects.push( po );
scene.add( poGroup );
}
var sphereMesh = new THREE.Mesh( sphereGeom, material );
sphereMesh.renderOrder = 6;
scene.add( sphereMesh );
var planeMeshes = [];
for(var i = 0; i < 6; i++)
{
planeMeshes.push( new THREE.Mesh(planeGeoms[i], material) );
}
planeMeshes[0].position.copy(new THREE.Vector3(.5, 0, 0));
planeMeshes[1].position.copy(new THREE.Vector3(0, .5, 0));
planeMeshes[2].position.copy(new THREE.Vector3(0, 0, .5));
planeMeshes[3].position.copy(new THREE.Vector3(-.5, 0, 0));
planeMeshes[4].position.copy(new THREE.Vector3(0, -.5, 0));
planeMeshes[5].position.copy(new THREE.Vector3(0, 0, -.5));
planeMeshes[0].lookAt(new THREE.Vector3(2, 0, 0));
planeMeshes[1].lookAt(new THREE.Vector3(0, 2, 0));
planeMeshes[2].lookAt(new THREE.Vector3(0, 0, 2));
planeMeshes[3].lookAt(new THREE.Vector3(-2, 0, 0));
planeMeshes[4].lookAt(new THREE.Vector3(0, -2, 0));
planeMeshes[5].lookAt(new THREE.Vector3(0, 0, -2));
for(var i = 0; i < 6; i++)
scene.add( planeMeshes[i] );
// Renderer
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.shadowMap.enabled = true;
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0x263238 );
renderer.localClippingEnabled = true;
window.addEventListener( 'resize', onWindowResize, false );
document.body.appendChild( renderer.domElement );
// Controls
var controls = new OrbitControls( camera, renderer.domElement );
controls.minDistance = 2;
controls.maxDistance = 20;
controls.update();
}
function initLights()
{
scene.add( new THREE.AmbientLight( 0xffffff, 0.5 ) );
var dirLight = new THREE.DirectionalLight( 0xffffff, 1 );
dirLight.position.set( 5, 10, 7.5 );
dirLight.castShadow = true;
dirLight.shadow.camera.right = 2;
dirLight.shadow.camera.left = - 2;
dirLight.shadow.camera.top = 2;
dirLight.shadow.camera.bottom = - 2;
dirLight.shadow.mapSize.width = 1024;
dirLight.shadow.mapSize.height = 1024;
scene.add( dirLight );
}
function onWindowResize()
{
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate()
{
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
</script>
It contains 2 clipping planes, a cube made from 6 separate PlaneGeometries, and a solid sphere for comparison. I made the stencil for the cube using an additional BufferGeometry made from merging the planes together into a single geometry object. The stencil for the cube appears to be the right shape and size, but only one cap face is drawn and it is not at the location of either of the clipping planes. Is there anything else I'm supposed to do with the stencil or the clipping plane beyond what the example already does to make it work on geometry of this type?
Turns out the PlaneBufferGeometries that were getting merged for the stencil were not in the same positions as the plane meshes that used those geometries. That is why the cap face wasn't being drawn properly. I had not considered the fact that if you apply a transform to a Mesh, then get the Mesh's geometry to use elsewhere, that geometry won't reflect the transform applied to the Mesh. I got it to work by applying the transform matrices from the plane meshes to the PlaneBufferGeometries that needed to be merged.
Related
I am using threejs to build a map application, and I need to make all building models translucent, but in this case, the transparent buildings will overlap, resulting in a confusing display effect, as shown in the following figure
Overlapping renderings
The effect I hope to achieve is similar to the example on mapboxgl, the nearby buildings can directly block the buildings behind, which is much more refreshing
Expected renderings
How can this be done?
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xcccccc );
scene.fog = new THREE.FogExp2( 0xcccccc, 0.002 );
scene.background = new THREE.Color( 0x4186D1 );
// scene.fog = new THREE.FogExp2( 0x4186D1, 0.002 );
scene.fog = new THREE.Fog( 0x4186D1, 800, 1800 );
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, 2000 );
camera.position.set( 400, 200, 0 );
// controls
controls = new MapControls( 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.BoxGeometry( 1, 1, 1 );
geometry.translate( 0, 0.5, 0 );
const material = new THREE.MeshPhongMaterial( { color: 0xffffff, transparent: true, opacity: 0.7, flatShading: true } );
for ( let i = 0; i < 500; i ++ ) {
const mesh = new THREE.Mesh( geometry, material );
mesh.position.x = Math.random() * 1600 - 800;
mesh.position.y = 0;
mesh.position.z = Math.random() * 1600 - 800;
mesh.scale.x = 20;
mesh.scale.y = Math.random() * 80 + 10;
mesh.scale.z = 20;
mesh.updateMatrix();
mesh.matrixAutoUpdate = false;
scene.add( mesh );
}
// lights
const dirLight1 = new THREE.DirectionalLight( 0xffffff );
dirLight1.position.set( 1, 1, 1 );
scene.add( dirLight1 );
const dirLight2 = new THREE.DirectionalLight( 0x002288 );
dirLight2.position.set( - 1, - 1, - 1 );
scene.add( dirLight2 );
const ambientLight = new THREE.AmbientLight( 0x222222 );
scene.add( ambientLight );
//
window.addEventListener( 'resize', onWindowResize );
const gui = new GUI();
gui.add( controls, 'screenSpacePanning' );
I'm trying to animate the movement of a sphere along a predefined set of vertices.
I'm able to animate from one point to another using the below code
function animate() {
requestAnimationFrame(animate)
sphere.position.lerp(new THREE.Vector3(100, 2, 0), 0.05)
render()
}
function render() {
renderer.render(scene, camera)
}
animate()
this works for a single animation from initial position to (100, 2, 0). How do i keep on adding vertices, so that it will be animated in sequence.
You can animate a mesh along a path with plain three.js by defining a curve based on your sequence of points and then using this curve for animation.
let camera, scene, renderer, clock;
let mesh, path;
const duration = 10;
let time = 0;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.set( 3, 2, 3 );
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
clock = new THREE.Clock();
const controls = new THREE.OrbitControls( camera, renderer.domElement );
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshNormalMaterial();
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
scene.add( new THREE.AxesHelper( 2 ) );
// points and path
const points = [
new THREE.Vector3( 0, 0, 0 ),
new THREE.Vector3( 1, 2, - 2 ),
new THREE.Vector3( 2, 2, - 0.5 ),
new THREE.Vector3( 2, 1, - 2 )
];
path = new THREE.CatmullRomCurve3( points, true );
// visualize the path
const lineGeometry = new THREE.BufferGeometry().setFromPoints( path.getPoints( 32 ) );
const lineMaterial = new THREE.LineBasicMaterial();
const line = new THREE.Line( lineGeometry, lineMaterial );
scene.add( line );
}
function animate() {
requestAnimationFrame( animate );
time += clock.getDelta();
const t = Math.min( time / duration, 1 );
if ( t === 1 ) time = 0;
path.getPointAt( t, mesh.position ); // animating
renderer.render( scene, camera );
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.137.5/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.137.5/examples/js/controls/OrbitControls.js"></script>
Description of the problem
I have a simple box mesh with a morphTarget and a slider which adjusts the morphTargetInfluence. The morph affects the mesh as it should but it also shrinks any other mesh in the scene.
I've put together a jsfiddle (modified from the threejs morph target) example below to demo the issue. In this demo moving the slider correctly morphs the corner of the red cube but incorrectly shrinks the size of the blue cube. The cube meshes are entirely unrelated so I don't see how the morph could affect the blue cube.
https://jsfiddle.net/djmm7vv2/
// JS code from jsfiddle
var container, stats;
var camera, scene, renderer;
var geometry, objects;
var mesh, mesh2;
init();
animate();
function init() {
// Create cameras, lights, scene, ect.
container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 15000 );
camera.position.z = 500;
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x222222 );
scene.fog = new THREE.Fog( 0x000000, 1, 15000 );
var light1 = new THREE.PointLight( 'white', 1);
light1.position.set( 100, 100, 100 );
var light2 = new THREE.PointLight( 'white', 1);
light2.position.set( -100, 100, 100 );
scene.add( light1 );
scene.add( light2 );
// Create first mesh (red cube)
var geometry = new THREE.BoxGeometry( 100, 100, 100 );
var material = new THREE.MeshLambertMaterial( { color: 'red', morphTargets: true } );
// Create 1 blend shape
for ( var i = 0; i < 1; i ++ ) {
var vertices = [];
for ( var v = 0; v < geometry.vertices.length; v ++ ) {
vertices.push( geometry.vertices[ v ].clone() );
if ( v === i ) {
vertices[ vertices.length - 1 ].x *= 2;
vertices[ vertices.length - 1 ].y *= 2;
vertices[ vertices.length - 1 ].z *= 2;
}
}
geometry.morphTargets.push( { name: "target" + i, vertices: vertices } );
}
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
// Add second mesh (blue cube)
var blue = new THREE.MeshLambertMaterial( { color: 'blue', morphTargets: true } );
var box2 = new THREE.BoxGeometry( 100, 100, 100 );
mesh2 = new THREE.Mesh( box2, blue );
scene.add( mesh2 );
mesh2.position.x = 150
// Create simple GUI slider to change morph influence on mesh (red cube)
var params = {
influence1: 0,
};
var gui = new dat.GUI();
var folder = gui.addFolder( 'Morph Targets' );
folder.add( params, 'influence1', 0, 1 ).step( 0.01 ).onChange( function( value ) { mesh.morphTargetInfluences[ 0 ] = value; } );
folder.open();
// Render it all
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
mesh.rotation.y += 0.01;
renderer.render( scene, camera );
}
...And here's the answer https://github.com/mrdoob/three.js/issues/12691#issuecomment-345416590. My blue mesh material had morphTargets set to true. Changing it to false corrected the issue.
var blue = new THREE.MeshLambertMaterial( { color: 'blue', morphTargets: false } );
If anyone knows why this is the case I would love to know more. The documentation on MeshLambertMaterials is sparse. Maybe this has to do with keeping material textures from freaking out when the morph is applied?
Simple Program to display the bars in a certain location with a certain height, with a certain color. New to Three.js, so learning about the framework.
When I run my script to load the bar position, colors, the lights, camera and the controls. I find that the Box colors are constant, with the basic mesh so I tried with a MeshPhongMaterial also constant. So I need a little help.
// Begin
function plotRF(bar_data){
// Bar Data
this.bars = bar_data
// Call the canvas for screan sizing
this.canvas = document.getElementById("BarCanvas")
// create the scene
scene = new THREE.Scene();
// Define the camera
camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 8000 );
camera.position.z = 500;
camera.position.y = 500;
//camera.rotation.x = 90 * Math.PI / 180;
// Set the render engine
var renderer = new THREE.WebGLRenderer({ canvas: BarCanvas });
// Set the render size
renderer.setSize( this.canvas.width, this.canvas.height);
// Add some Lights
this.add_lights()
// Add controls
controls = new THREE.OrbitControls( camera, renderer.domElement );
// Define Geometry
//this.coords()
this.add_bars();
var render = function () {
requestAnimationFrame( render );
renderer.render(scene, camera);
};
render();
};
plotRF.prototype.add_bars = function(){
// Bar height
var multiplier = 20;
// Bar Size
var lw = 5;
// loop through the Javascript data
for (i = 0; i< this.bars.length; i++){
var geo = new THREE.BoxGeometry( lw, lw, this.bars[i][0]*multiplier );
//geo.add(
var rfcolour = this.colorTable(this.bars[i][0]);
var mat = new THREE.MeshPhongMaterial( {
color: rfcolour,
emissive: 0x072534,
side: THREE.DoubleSide,
shading: THREE.FlatShading} );
//mat.wireframe = true;
cube = new THREE.Mesh( geo, mat );
cube.position.x = this.bars[i][1]/10;
cube.position.y = this.bars[i][2]/10;
cube.position.z = this.bars[i][0]*multiplier/2;
scene.add( cube );
console.log("bar added, x:" + this.bars[i][1] +", y:" + this.bars[i][2] + ", RF:" + this.bars[i][0]) ;
}
};
plotRF.prototype.colorTable = function(RF){
if (RF < 1 ) {
return new THREE.Color(255,0,0);
} else if (RF < 1.2) {
return new THREE.Color(240,50,50);
} else if (RF < 1.4) {
return new THREE.Color(230,100,100);
} else if (RF < 1.6) {
return new THREE.Color(220,150,150);
} else if (RF < 1.8) {
return new THREE.Color(210,200,200);
} else if (RF < 2.0) {
return new THREE.Color(200,220,220);
} else if (RF < 3.0) {
return new THREE.Color(150,220,220);
} else {
return new THREE.Color(100,240,240);
}
plotRF.prototype.add_lights = function(RF){
var lights = [];
lights[ 0 ] = new THREE.PointLight( 0xffffff, 0.8, 500 );
lights[ 1 ] = new THREE.PointLight( 0xffffff, 0.8, 500 );
lights[ 2 ] = new THREE.PointLight( 0xffffff, 0.8, 500 );
lights[ 0 ].position.set( 0, 2000, 0 );
lights[ 1 ].position.set( 1000, 2000, 1000 );
lights[ 2 ].position.set( - 1000, - 2000, - 1000 );
scene.add( lights[ 0 ] );
scene.add( lights[ 1 ] );
scene.add( lights[ 2 ] );
}
Figure of the constant colors is below. Note the colors are registering correctly the R,G,B values are correct in the THREE.Color function.
you have to set colors like it described in documentation, for example:
return new THREE.Color("rgb(255, 0, 0)"); // red
When passing r,g,b directly in the THREE.Color method the values must be between 0 and 1.
How to show a cube map reflection on a object without showing the cubemap in the background?
I like to receive a reflection on a lever mechanism without showing a cubemap in the background. The background should be with a gradient from blue to white.
So basicially, the cubemap should be only visible on the object.
Thank you very much in advance!
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container;
var loader;
var camera, cameraTarget, controls, scene, renderer;
init();
animate();
function init() {
var previewDiv = document.getElementById("preview");
camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 15 );
camera.position.set( 3, 0.15, 3 );
cameraTarget = new THREE.Vector3( 0, -0.25, 0 );
controls = new THREE.OrbitControls( camera );
controls.maxPolarAngle = Math.PI / 2.2;
controls.minDistance = 3;
controls.maxDistance = 8;
// controls.noPan = true;
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0xdae1e6, 2, 15 );
// Ground
var plane = new THREE.Mesh(
new THREE.PlaneBufferGeometry( 40, 40 ),
new THREE.MeshPhongMaterial( { color: 0x999999, specular: 0x101010 } )
);
plane.rotation.x = -Math.PI/2;
plane.position.y = -0.5;
scene.add( plane );
plane.receiveShadow = true;
// feinleinen
var feinleinen = THREE.ImageUtils.loadTexture( 'textures/feinleinen.jpg' );
feinleinen.anisotropy = 1;
feinleinen.wrapS = feinleinen.wrapT = THREE.RepeatWrapping;
feinleinen.repeat.set( 5, 5 );
// create a cube
var basisGeometry = new THREE.BoxGeometry(3,0.02,3);
var basisMaterial = new THREE.MeshPhongMaterial( { color: 0xffffff, map: feinleinen } );
var basis = new THREE.Mesh(basisGeometry, basisMaterial);
basis.castShadow = false;
basis.receiveShadow = true;
// position the cube
basis.position.set( 0, -0.47, 0 );
// add the cube to the scene
scene.add(basis);
var loader = new THREE.JSONLoader();
loader.load('/models/hebelmechanik.js', function(geo, mat){
var chrome = new THREE.MeshLambertMaterial( { ambient: 0x444444, color: 0x111111, shininess: 800, specular: 0x111111, shading: THREE.SmoothShading, reflectivity: 1.1 } );
var mesh = new THREE.Mesh(geo, chrome);
mesh.position.set( 0, - 0.497, 0 );
mesh.rotation.set( 0, - Math.PI / 2, 0 );
mesh.scale.set( 0.008, 0.008, 0.008 );
mesh.castShadow = true;
mesh.receiveShadow = true;
loadJson(mesh );
});
function loadJson(mesh){
scene.add( mesh );
}
// Lights
scene.add( new THREE.AmbientLight( 0x777777 ) );
addShadowedLight( 1, 1, 1, 0xffffff, 1.35 );
addShadowedLight( 0.5, 1, -1, 0xffffff, 1 );
// renderer
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setClearColor( scene.fog.color );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.gammaInput = true;
renderer.gammaOutput = true;
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
renderer.shadowMapCullFace = THREE.CullFaceBack;
previewDiv.appendChild (renderer.domElement);
// resize
window.addEventListener( 'resize', onWindowResize, false );
}
function addShadowedLight( x, y, z, color, intensity ) {
var directionalLight = new THREE.DirectionalLight( color, intensity );
directionalLight.position.set( x, y, z )
scene.add( directionalLight );
directionalLight.castShadow = true;
// directionalLight.shadowCameraVisible = true;
var d = 1;
directionalLight.shadowCameraLeft = -d;
directionalLight.shadowCameraRight = d;
directionalLight.shadowCameraTop = d;
directionalLight.shadowCameraBottom = -d;
directionalLight.shadowCameraNear = 1;
directionalLight.shadowCameraFar = 4;
directionalLight.shadowMapWidth = 2048;
directionalLight.shadowMapHeight = 2048;
directionalLight.shadowBias = -0.005;
directionalLight.shadowDarkness = 0.15;
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
camera.lookAt( cameraTarget );
controls.update();
renderer.render( scene, camera );
}
</script>
You can add a cubemap reflection to your model by specifying the envMap property of the model's material.
Use a pattern like this one:
var path = "textures/cube/foo/";
var format = '.png';
var urls = [
path + 'px' + format, path + 'nx' + format,
path + 'py' + format, path + 'ny' + format,
path + 'pz' + format, path + 'nz' + format
];
var envMap = THREE.ImageUtils.loadTextureCube( urls, THREE.CubeReflectionMapping, callback ); // callback function is optional
var material = new THREE.MeshPhongMaterial( {
color : 0x999999,
specular : 0x050505,
shininess : 50,
envMap : envMap,
combine : THREE.MixOperation, // or THREE.AddOperation, THREE.MultiplyOperation
reflectivity : 0.5
} );
three.js r.71