I use three.js TrackballControls for rotating object.
Here is simple application - http://zheden.elitno.net/
I cannot rotate object horizontally when mouse position is on left side of scene. Vertical rotation is ok.
Could you please tell me what is wrong?
Here is my code:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, 1, 0.1, 1000);
var controls;
var renderer = new THREE.WebGLRenderer();
renderer.setSize(500, 500);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.CubeGeometry(1,1,1);
var material = new THREE.MeshLambertMaterial(
{
overdraw: true,
color: 0x00aa80,
shading: THREE.FlatShading
});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
var directionalLight = new THREE.DirectionalLight( 0xffffff );
directionalLight.position.x = 1;
directionalLight.position.y = 1;
directionalLight.position.z = 1;
directionalLight.position.normalize();
scene.add( directionalLight );
var light = new THREE.DirectionalLight( 0xffffff );
light.position.set( -1, -1, -1 );
scene.add( light );
var light1 = new THREE.AmbientLight( 0x222222 );
scene.add( light1 );
camera.position.z = 3;
controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
controls.keys = [ 65, 83, 68 ];
controls.addEventListener( 'change', render );
function render() {
renderer.render(scene, camera);
}
function animate() {
requestAnimationFrame(animate);
controls.update();
render();
};
animate();
Thanks!
Related
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>
My code is :
$(function() {
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setClearColor(0xdddddd);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMapSoft = true;
var axis = new THREE.AxisHelper(10);
scene.add(axis);
var grid = new THREE.GridHelper(50, 5);
var color = new THREE.Color("rgb(255,0,0)");
grid.setColors(color, 0x000000);
scene.add(grid);
var Ground_geometry = new THREE.BoxGeometry( 20, 0.1, 20 );
var Ground_material = new THREE.MeshPhongMaterial( {
color: 0xa0adaf,
shininess: 150,
specular: 0xffffff,
shading: THREE.SmoothShading
} );
var ground = new THREE.Mesh( Ground_geometry, Ground_material );
ground.scale.multiplyScalar( 3 );
ground.castShadow = false;
ground.receiveShadow = true;
scene.add( ground );
var ambient = new THREE.AmbientLight( 0x404040 );
scene.add( ambient );
spotLight = new THREE.SpotLight( 0xffffff );
spotLight.position.set( 10, 10, 15 );
spotLight.castShadow = true;
spotLight.shadowCameraNear = 8;
spotLight.shadowCameraFar = 30;
spotLight.shadowDarkness = 0.5;
spotLight.shadowCameraVisible = false;
spotLight.shadowMapWidth = 1024;
spotLight.shadowMapHeight = 1024;
spotLight.name = 'Spot Light';
scene.add( spotLight );
var controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.addEventListener( 'change', renderer );
var cubeGeometry = new THREE.BoxGeometry(5, 5, 5);
var cubeMaterial = new THREE.MeshPhongMaterial({
color: 0x456574 ,
shininess: 150,
specular: 0x222222,
shading: THREE.SmoothShading,
});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.x = 0;
cube.position.y = 0;
cube.position.z = 0;
scene.add(cube);
camera.position.x = 40;
camera.position.y = 40;
camera.position.z = 40;
camera.lookAt(scene.position);
renderer.render(scene, camera);
$("#webGL-container").append(renderer.domElement);
$(window).resize(function(){
SCREEN_WIDTH = window.innerWidth;
SCREEN_HEIGHT = window.innerHeight;
camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
camera.updateProjectionMatrix();
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
});
});
I am getting an error that says : TypeError: array[i].call is not a function
and is pointing to line 7484 of three.js library.
I have included the three.js library using:
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r73/three.js"></script>
So as you can see, its the v73 and I haven't touched the code. What could be the problem?
The error only comes after screen is clicked and then mouse pointer is dragged, so it must have got to do with that piece of code.
Assuming that you want the scene to render when OrbitControls sends a change event, you'll have to change the code to:
controls.addEventListener( 'change', render );
.
.
.
function render() {
renderer.render( scene, camera );
}
renderer.render( scene, camera );
I'm trying to create a simple plane which will combine a texture and a cubeCamera reflection and I'm failing and I'm not sure what to do next?
If I swap the envMap on the plane material to a simple jpg/png texturecube then it will work fine, but this is not what I want.
My goal is to create a glossy reflective plane with a texture that will be replicated to create a room and reflect any 3d meshes inside the room.
Here is what I have so far.
var scene, camera, cameraCube, renderer;
var light1, light2;
var wallMesh;
var init = function(){
// scene
scene = new THREE.Scene();
// cameras
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 100000 );
camera.position.set(0,50000,50000);
cameraCube = new THREE.CubeCamera( 60, window.innerWidth / window.innerHeight, 1, 100000 );
cameraCube.renderTarget.minFilter = THREE.LinearMipMapLinearFilter; // mipmap filter
scene.add(cameraCube)
// textureCube just for test
// var path = "http://three.dev/cortana/textures/";
// var format = '.png';
// var urls = [
// path + 'px' + format, path + 'nx' + format,
// path + 'py' + format, path + 'ny' + format,
// path + 'pz' + format, path + 'nz' + format
// ];
// var textureCube = THREE.ImageUtils.loadTextureCube( urls );
var texture = THREE.ImageUtils.loadTexture( 'http://three.dev/various/textures/white.png' );
// room
var plane = new THREE.PlaneBufferGeometry( 50000, 50000 );
var wallMaterial = new THREE.MeshLambertMaterial( {
color: 0x333333,
ambient: 0xdddddd,
map: texture,
envMap: cameraCube.renderTarget,
combine: THREE.MixOperation,
reflectivity: 0.5
} );
var wallMaterial = new THREE.MeshBasicMaterial({
envMap: cameraCube.renderTarget,
})
wallMesh = new THREE.Mesh( plane, wallMaterial );
wallMesh.rotateX(toRadians(-90));
wallMesh.position.set(0,-250,0);
scene.add( wallMesh );
// sphere
var sphereGeometry = new THREE.SphereGeometry( 100, 64, 64 );
var sphereMaterial = new THREE.MeshPhongMaterial( { ambient: 0x111111, color: 0x111111, specular: 0x333333, shininess: 50, shading: THREE.SmoothShading });
var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial );
sphere.scale.x = sphere.scale.y = sphere.scale.z = 20;
sphere.position.set( 0, 2000, 0 );
scene.add(sphere);
// lights
var ambient = new THREE.AmbientLight(0xffffff);
scene.add( ambient );
var directionalLight1 = new THREE.DirectionalLight( 0xffffff, 1 );
directionalLight1.position.set( 0, 50000, 0 ).normalize();
scene.add( directionalLight1 );
var color = new THREE.Color("rgb(0,255,0)");
light2 = new THREE.PointLight(color, 1, 50000);
light2.position.set(2000,500,2000);
scene.add( light2 );
// renderer
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setClearColor( 0xffffff, 1 );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.autoClear = false;
document.getElementsByTagName('body')[0].appendChild( renderer.domElement );
// controls
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.rotateSpeed = 0.5;
controls.minDistance = 1000;
controls.maxDistance = 50000;
controls.minPolarAngle = 0;
controls.maxPolarAngle = toRadians(90)
// Events
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
cameraCube.aspect = window.innerWidth / window.innerHeight;
cameraCube.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
controls.update();
//camera.lookAt( scene.position );
//cameraCube.rotation.copy( camera.rotation );
//renderer.render( scene, cameraCube );
wallMesh.visible = false;
cameraCube.updateCubeMap(renderer, scene);
wallMesh.visible = true;
renderer.render( scene, camera );
}
window.onload = function(){
init();
animate();
}
I'm kinda new to Three.js, I'm enjoying it a whole bunch, though I'm having an issue with shadow maps, I've read and looked everywhere but I just can't get it to work, can somebody point me in the direction of what I'm doing wrong?
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.BoxGeometry(1,1,1);
var cube = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial( {color: 0x808080 } ));
cube.castShadow = true;
scene.add( cube );
camera.position.y = 2;
var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.set( 0, 10, 0 );
directionalLight.castShadow = true;
scene.add( directionalLight );
var geo2 = new THREE.BoxGeometry(5,0.1,5);
var floor = new THREE.Mesh(geo2, new THREE.MeshLambertMaterial( {color: 0x808080 } ));
floor.position.y = -1;
floor.receiveShadow = true;
scene.add(floor);
renderer.shadowMapEnabled = true;
renderer.shadowMapType = THREE.PCFSoftShadowMap;
var ambient = new THREE.AmbientLight( 0x111111 );
directionalLight.shadowCameraVisible = true;
scene.add( ambient );
renderer.shadowCameraNear = 3;
renderer.shadowCameraFar = camera.far;
renderer.shadowCameraFov = 50;
function animate() {
camera.lookAt({x:0,y:0,z:0});
var timer = Date.now() * 0.0002;
camera.position.x = Math.cos(timer) * 5;
camera.position.z = Math.sin(timer) * 5;
requestAnimationFrame(animate);
render();
}
function render() {
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render(scene, camera);
}
animate();
These three lines:
renderer.shadowCameraNear = 3;
renderer.shadowCameraFar = camera.far;
renderer.shadowCameraFov = 50;
should be on your light not the renderer; so
directionalLight.shadowCameraNear = 3;
directionalLight.shadowCameraFar = camera.far;
directionalLight.shadowCameraFov = 50;
and since your light is directional you will need:
directionalLight.shadowCameraLeft = -500;
directionalLight.shadowCameraRight = 500;
directionalLight.shadowCameraTop = 500;
directionalLight.shadowCameraBottom = -500;
and you might need to play around with these values.
I'm working with three.js and attempting to create procedural texture which can be stored and then applied to objects later in a session.
Ideally, I would like to create these textures only once each.
I would like to be able to sample from existing assets to create new textures.
Within the three.js example, a version of this is shown where the texture is re-rendered every frame. http://threejs.org/examples/webgl_rtt.html
I have created an example of what I hope to achieve here: http://www.forsako.com/ThreeJS/RenderTest.html
Unfortunately, to make this work, I had to re-render the texture each frame.
Is there a way to perform this rendering so that the texture persists over multiple frames until I tell it to be released? Source from my main program follows.
<html>
<head>
<title>Render Test</title>
</head>
<style>
#mycontainer {
background: #000;
width: 800px;
height: 600px;
}
</style>
<body>
<div id="mycontainer"></div>
</body>
<script src="js/three.min.js"></script>
<script src="js/TrackballControls.js"></script>
<script src="js/stats.min.js"></script>
<script src="js/PlaneGeomUV.js"></script>
<script type="text/javascript">
var Renderer, Container, Scene, Camera, Quad1, Quad2, Plane, MaterialRTT, TextureRTT, LightAmb;
var SceneRTT, CameraRTT, Q1RTT, Q2RTT, Q3RTT, Q4RTT, MaterialFromFile, TextureFromFile;
var isRenderingTex = true;
var WidthWin = 800;
var HeightWin = 640;
var WidthTile = 428;
var HeightTile = 683;
Init();
Animate();
function Init(){
var CAngle = 45;
var CAspect = WidthWin / HeightWin;
var CNearCut = 0.1;
var CFarCut = 10000;
// Set up the main rendering object and attach it to an element on the page
Renderer = new THREE.WebGLRenderer();
Renderer.setSize( WidthWin, HeightWin );
Container = document.getElementById( "mycontainer" );
Container.appendChild( Renderer.domElement );
// Set up the textures and materials for rendering
TextureFromFile = THREE.ImageUtils.loadTexture( "Assets/Map_Tiles.png" );
TextureRTT = MakeTex( Renderer, TextureFromFile, WidthTile, HeightTile );
MaterialFromFile = new THREE.MeshBasicMaterial( { color: 0xffffff, map: TextureFromFile } );
MaterialRTT = new THREE.MeshBasicMaterial( { color: 0xffffff, map: TextureRTT } );
MaterialFromFile.side = THREE.DoubleSide;
MaterialRTT.side = THREE.DoubleSide;
// Set up the main renderable scene
Scene = new THREE.Scene();
Plane = new THREE.PlaneGeometry( WidthTile, HeightTile );
Quad1 = new THREE.Mesh( Plane, MaterialFromFile );
Quad1.position.x = WidthTile*0.5;
Scene.add( Quad1 );
Quad2 = new THREE.Mesh( Plane, MaterialRTT );
Quad2.position.x = -WidthTile*0.5;
Scene.add( Quad2 );
LightAmb = new THREE.AmbientLight( 0xffffff );
Scene.add( LightAmb );
Camera = new THREE.PerspectiveCamera( CAngle, CAspect, CNearCut, CFarCut );
Camera.position.z = 1200;
Scene.add( Camera );
// Create controls using the TrackballControls library to easily manipulate our camera
Controls = new THREE.TrackballControls( Camera );
Controls.target = new THREE.Vector3( 0, 0, 0 );
Controls.rotateSpeed = 4.0;
Controls.zoomSpeed = 6.0;
Controls.panSpeed = 1.0;
Controls.noZoom = false;
Controls.noPan = false;
Controls.staticMoving = true;
Controls.dynamicDampingFactor = 0.3;
Controls.keys = [ 65, 83, 68 ];
// Add the Three.js stats object so we can track fps
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
Container.appendChild( stats.domElement );
}
function MakeTex( Renderer_in, Texture_in, Width_in, Height_in ){
var ParamsTex = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };
var Tex_out = new THREE.WebGLRenderTarget( WidthWin, HeightWin, ParamsTex );
var tMaterial = new THREE.MeshBasicMaterial( { color: 0xffffff, map: Texture_in } );
// Set up the scene for rendering to texture
SceneRTT = new THREE.Scene();
var tPlane = new THREE.PlaneGeometry( WidthTile*0.5, HeightTile*0.5 );
Q1RTT = new THREE.Mesh( tPlane, tMaterial );
Q1RTT.position.x = WidthTile*0.25;
Q1RTT.position.y = HeightTile*0.25;
SceneRTT.add( Q1RTT );
Q2RTT = new THREE.Mesh( tPlane, tMaterial );
Q2RTT.position.x = -WidthTile*0.25;
Q2RTT.position.y = HeightTile*0.25;
SceneRTT.add( Q2RTT );
Q3RTT = new THREE.Mesh( tPlane, tMaterial );
Q3RTT.position.x = -WidthTile*0.25;
Q3RTT.position.y = -HeightTile*0.25;
SceneRTT.add( Q3RTT );
Q4RTT = new THREE.Mesh( tPlane, tMaterial );
Q4RTT.position.x = WidthTile*0.25;
Q4RTT.position.y = -HeightTile*0.25;
SceneRTT.add( Q4RTT );
tLightAmb = new THREE.AmbientLight( 0xffffff );
SceneRTT.add( tLightAmb );
CameraRTT = new THREE.OrthographicCamera( -Width_in / 2, Width_in / 2, Height_in / 2, -Height_in / 2, 0.1, 10000 );
CameraRTT.position.z = 600;
SceneRTT.add( CameraRTT );
//Renderer.clear();
//Renderer.render( SceneRTT, CameraRTT, Tex_out, true );
return Tex_out;
}
function Animate(){
requestAnimationFrame( Animate );
Controls.update();
stats.update();
Render();
}
function Render(){
Renderer.clear();
if( isRenderingTex ){
Renderer.render( SceneRTT, CameraRTT, TextureRTT, true );
//isRenderingTex = false;
}
Renderer.render( Scene, Camera );
}
</script>
</html>