I've tried practically everything and the code seems to be perfectly valid. I've tried changing the threejs version, changing from MeshPhongMaterial to MeshBasicMaterial and back, and tried copy pasting code from online. However I still get the same result. CubeCamemra.js works perfectly for me on this ->> http://blog.romanliutikov.com/post/58910953451/dynamic-reflections-in-three-js, but when I try to implement it locally, it renders black. Please tell me if I am missing anything important. Thanks in advance!
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
camera.position.z = 5;
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var controls = new THREE.TrackballControls(camera);
var cubeCamera = new THREE.CubeCamera(0.1, 1000, 256); // parameters: near, far, resolution
cubeCamera.renderTarget.minFilter = THREE.LinearMipMapLinearFilter; // mipmap filter
scene.add(cubeCamera);
var sphere = new THREE.Mesh(
new THREE.SphereGeometry(0.5, 30, 30),
new THREE.MeshBasicMaterial({
envMap: cubeCamera.renderTarget,
color: 0x00ffff
})
);
//sphere.position.y = 3;
scene.add(sphere);
var cube = new THREE.Mesh(new THREE.CubeGeometry(1,1,1),new THREE.MeshNormalMaterial());
scene.add(cube);
cube.position.y = 3;
function render() {
requestAnimationFrame(render);
sphere.visible = false;
cubeCamera.updateCubeMap(renderer, scene);
sphere.visible = true;
renderer.render(scene,camera);
controls.update();
}
render();
http://puu.sh/aqcib/6c2b15d6ca.png -- pic of whats happening
Related
I'm trying to add light and see its changes in a simple scene in threejs but no matter the intensity or the color I set for the light, I see no change. Actually, if I don't include the light code, nothing changes as well, so why is HemisphereLight not working in my case?
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 200, window.innerWidth/window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var planeGeometry = new THREE.PlaneGeometry(25, 60, 20, 20);
var planeMaterial = new THREE.MeshBasicMaterial({color:"green"})
var plane = new THREE.Mesh( planeGeometry, planeMaterial );
var light = new THREE.HemisphereLight(0xffffff, 0x000000, 2);
scene.add(light);
scene.add(plane);
plane.rotateZ(Math.PI/2)
camera.position.z = 10;
scene.background = new THREE.Color(0xffffff);
var render = function (time) {
requestAnimationFrame( render );
renderer.render(scene, camera);
};
render();
What version of Three.JS do you use?
I made a JSFiddle with your code, using only Javascript and Three.js version 105 and everything worked, when I used Three.JS version r54, it indeed didn't work.
Sorry that I ask this question like this, can't comment yet haha.
I'll remove this if asked
You can check what version you're using with:
console.log(THREE. REVISION)
<script src="https://threejs.org/build/three.js"></script>
<script type="module">
console.log(THREE. REVISION)
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 200, window.innerWidth/window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var planeGeometry = new THREE.PlaneGeometry(25, 60, 20, 20);
var planeMaterial = new THREE.MeshBasicMaterial({color:"green"})
var plane = new THREE.Mesh( planeGeometry, planeMaterial );
var light = new THREE.HemisphereLight(0xffffff, 0x000000, 2);
scene.add(light);
scene.add(plane);
plane.rotateZ(Math.PI/2)
camera.position.z = 10;
scene.background = new THREE.Color(0xffff00);
var render = function (time) {
requestAnimationFrame( render );
renderer.render(scene, camera);
};
render();
</script>
All of this goes into 1 HTML File.
Here is my code:
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.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = true;
controls.autoRotate = true;
// Cube
var Cubegeometry = new THREE.BoxGeometry(1, 1, 1);
const CubeImgTexture = new THREE.CubeTextureLoader().setPath('imgs/textures/cube/').load([
's1.png', 's5.png',
's2.png', 's4.png',
's3.png', 's6.png'
]);
var Cubematerial = new THREE.MeshStandardMaterial({
map: CubeImgTexture
});
var CubeMesh = new THREE.Mesh(Cubegeometry, Cubematerial);
scene.add(CubeMesh);
camera.position.z = 5;
controls.update();
var animate = function() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
};
When I run it, I get a blank screen and an error saying that "Argument 6 is not valid for any of the 6-argument overloads."
What does this mean?
The problem is with
var Cubematerial = new THREE.MeshStandardMaterial({
map: CubeImgTexture
});
You never initialize anything named CubeImgTexture. If you're trying to pass a cubeTexture into the .map property, you're going to run into problems because map only expects a regular texture. Maybe you're trying to assign it to the .envMap property instead?
I need to place a number of objects on the canvas, using three js. I'm getting stuck at the point of trying to change the location of the objects. My code is as below:
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( 2, 1, 1 );
//geometry.position.x = 1;
//geometry.position.y = 1;
//geometry.position.z = 1;
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
//scene.children[1].position.set(0, 0, 0);
var cube = new THREE.Mesh(geometry, material);
scene.add( cube );
camera.position.z = 5;
renderer.render( scene, camera );
I've commented out the two different ways I tried to achieve this (both failed). Can anyone suggest a solution?
You have to set position to a mesh, not a geometry:
var geometry = new THREE.BoxGeometry( 2, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh(geometry, material);
cube.position.set(1, 1, 1);
scene.add( cube );
I am working in a three.js project. In the project I have to show all edges of geometries even those edges are intersecting with other objects' surfaces.
Here is the snippet code that illustrates my problem.
var camera, scene, renderer, material, stats, group, wireframeMaterial;
init();
animate();
function init() {
// Renderer.
renderer = new THREE.WebGLRenderer({antialias: true, alpha:true,clearAlpha:0,clearColor: 0xff0000});
//renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
// Add renderer to page
document.body.appendChild(renderer.domElement);
// Create camera.
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 400;
// Create scene.
scene = new THREE.Scene();
group=new THREE.Group()
// Create material
material = new THREE.MeshBasicMaterial();
wireframeMaterial=new THREE.LineBasicMaterial( { color: 0x000000, side:THREE.FrontSide ,transparent:false,opacity:1,linewidth: 1 })
// Create cube and add to scene.
var geometry = new THREE.BoxGeometry(200, 200, 200);
var mesh1 = new THREE.Mesh(geometry, material);
group.add(mesh1);
var geometry2 = new THREE.BoxGeometry(100,100,100);
var mesh2 = new THREE.Mesh(geometry2, material);
group.add(mesh2);
mesh2.position.fromArray([0,150,0])
var edges = new THREE.EdgesGeometry( geometry );
var line = new THREE.LineSegments( edges, wireframeMaterial );
mesh1.add( line );
var edges2 = new THREE.EdgesGeometry( geometry2 );
var line2 = new THREE.LineSegments( edges2, wireframeMaterial );
mesh2.add( line2 );
scene.add(group)
// Add listener for window resize.
window.addEventListener('resize', onWindowResize, false);
}
function animate() {
requestAnimationFrame(animate);
group.rotation.x += 0.005;
group.rotation.y += 0.01;
renderer.render(scene, camera);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
body {
padding: 0;
margin: 0;
}
canvas {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/97/three.min.js"></script>
In fiddle code you can see there are two cubes top of each other. I want bottom edges of small cube to become visible. One solution is making mesh basic material transparent. However in that situation edges that are behind cubes it self will be visible too which is not allowed in the project.
So are there any alternative solution for this issue?
Found a good solution, you need to use the polygonOffset parameters of the basic material.
var material = new THREE.MeshBasicMaterial({
polygonOffset: true,
polygonOffsetFactor: 1, // positive value pushes polygon further away
polygonOffsetUnits: 1
});
Found it on this question: three.js EdgesHelper showing certain diagonal lines on Collada model
EdgesGeometry will render the hard edges only.
WireframeGeometry will render all edges.
var camera, scene, renderer, material, stats, group, wireframeMaterial;
init();
animate();
function init() {
// Renderer.
renderer = new THREE.WebGLRenderer({antialias: true, alpha:true,clearAlpha:0,clearColor: 0xff0000});
//renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
// Add renderer to page
document.body.appendChild(renderer.domElement);
// Create camera.
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 400;
// Create scene.
scene = new THREE.Scene();
group=new THREE.Group()
// Create materials
var material = new THREE.MeshBasicMaterial({
polygonOffset: true,
polygonOffsetFactor: 1, // positive value pushes polygon further away
polygonOffsetUnits: 1
});
var wireframeMaterial= new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 2 } );
// Create cube and add to scene.
var geometry = new THREE.BoxGeometry(200, 200, 200);
var edges = new THREE.EdgesGeometry(geometry);
var line = new THREE.LineSegments( edges, wireframeMaterial );
var mesh = new THREE.Mesh(geometry, material);
group.add(mesh, line);
var geometry2 = new THREE.BoxGeometry(100,100,100);
var wire = new THREE.EdgesGeometry(geometry2);
var line2 = new THREE.LineSegments( wire, wireframeMaterial );
var mesh2 = new THREE.Mesh(geometry2, material);
line2.position.fromArray([0,150,0]);
mesh2.position.fromArray([0,150,0]);
group.add(mesh2, line2);
scene.add(group)
// Add listener for window resize.
window.addEventListener('resize', onWindowResize, false);
// Add stats to page.
stats = new Stats();
document.body.appendChild( stats.dom );
}
function animate() {
requestAnimationFrame(animate);
group.rotation.x += 0.005;
group.rotation.y += 0.01;
renderer.render(scene, camera);
stats.update();
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
<script type="text/javascript" src="https://rawgit.com/mrdoob/three.js/master/build/three.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/mrdoob/stats.js/r17/build/stats.min.js"></script>
Preface
I've created a super contrived example of what I want to create of using 3js geometry and video. I'm certain it wont need html5 video but the demo uses it for visiblity.
Here is a live code hosted by
codepen.io
Problem:
I'm super new to webGL and associated libraries(3js).
Question:
How do I map a video onto a sphere using 3js?
JS
// renderer
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// camera
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 500;
// scene
var video, texture;
video = document.getElementById( 'video' );
var scene = new THREE.Scene();
texture = new THREE.VideoTexture( video );
texture.minFilter = THREE.LinearFilter;
texture.magFilter = THREE.LinearFilter;
texture.format = THREE.RGBFormat;
//sphere
var sphere = new THREE.Mesh(new THREE.SphereGeometry(150, 100, 100), new THREE.MeshNormalMaterial());
sphere.overdraw = true;
scene.add(sphere);
renderer.render(scene, camera);
HTML
<!--sphere gets placed here -->
<div id="container"></div>
<!-- example video -->
<video id="video" width="400" src="http://avideos.5min.com//415/5177415/517741401_4.mp4#t=20"autoplay muted loop></video>
here's what I've assimilated from other posts I've found:
// setting up the renderer
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
var container = document.createElement('div');
document.body.appendChild( container );
container.appendChild( renderer.domElement );
// creating a new scene
// SCENE
scene = new THREE.Scene();
// CAMERA
var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
var VIEW_ANGLE = 100, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;
var camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
camera.target = new THREE.Vector3(0, 0, 0);
camera.position.set(0,150,400);
camera.lookAt(scene.position);
scene.add(camera);
var video = document.getElementById( 'myVideo' );
//sorry, not 100% sure why this is necessary -eg why the renderer doesn't automatically update the video texture in render()
videoImageContext = videoImage.getContext( '2d' );
// background color if no video present
videoImageContext.fillStyle = '#000000';
videoImageContext.fillRect( 0, 0, videoImage.width, videoImage.height );
videoTexture = new THREE.Texture( video );
videoTexture.minFilter = THREE.LinearFilter;
videoTexture.magFilter = THREE.LinearFilter;
var movieMaterial = new THREE.MeshBasicMaterial( { map: videoTexture,overdraw: true } );
// the geometry on which the movie will be displayed;
// movie image will be scaled to fit these dimensions.
var sphere = new THREE.SphereGeometry(100, 100, 40);
sphere.applyMatrix(new THREE.Matrix4().makeScale(-1, 1, 1));
var movieScreen = new THREE.Mesh( sphere, movieMaterial );
scene.add(movieScreen);
render();
function render(){
requestAnimationFrame(render);
if ( video.readyState === video.HAVE_ENOUGH_DATA )
{
videoImageContext.drawImage( video, 0, 0 );
if ( videoTexture )
videoTexture.needsUpdate = true;
}
// calling again render function
renderer.render(scene, camera);
}