I have a library building on top of three.js, and I'd like to run it in a ijavascript (jupyter + ijavascript) notebook. Does anyone know if that's possible?
From what I can tell, three.js runs just fine using require('three'), but I'm having trouble attaching the renderer.
There is already a mature solution where you can code in a more Pythonic way using Jupyter-Widigts.
pythreejs three.js embedded in a jupyter widgit
To show a green sphere in a notebook.
ball = Mesh(geometry=SphereGeometry(radius=1),
material=MeshLambertMaterial(color='#00ff00'),
position=[0, 0, 0])
ball
Output
I came up with a solution shortly after posting the question:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, 300 / 150, 0.1, 1000 );
$$html$$ = `<canvas></canvas>`
var renderer = new THREE.WebGLRenderer({canvas: $$html$$});
renderer.setSize( 300, 150 );
Related
I'm trying to render shadows using the latest version of three.js (r102), and I'm not sure what I am doing wrong. I am using MeshPhongMaterial with castShadow and receiveShadow set on all relevant meshes, and a directional light facing towards the scene content. Could someone take a look at this and help me figure out how to get these shadows working? Thanks!
Live demo (toggle shadows in the menu):
https://argonjs.github.io/three-web-layer/
Source:
https://github.com/argonjs/three-web-layer
If you add a small cube in front of your WebLayer3D, it correctly casts shadows on rendered DOM layers:
//in app.ts just after light with shadow camera:
let geometryBox = new THREE.BoxBufferGeometry( 0.01, 0.01, 0.01 )
let materialRed = new THREE.MeshPhongMaterial( {color: 0xff0000} )
let cubeSmall = new THREE.Mesh( geometryBox, materialRed )
cubeSmall.position.set( 0.1, -0.03, 0.1 )
cubeSmall.castShadow = true
cubeSmall.receiveShadow = true
scene.add( cubeSmall )
So, only the planes produced by the WebLayer3D do not cast shadows, the setup for the scene / camera / light is correct.
Update: the explanation below is not the reason, see the solution with material.shadowSide in another answer.
If you look at the tree of objects in three.js realm (i.e. traversing through children[]), starting with todoLayer - a lot of them will have castShadow at "false". You will have to re-think your strategy here. Also note, castShadow=false on parent Object3D turns it off for the children.
I figured it out after the hint from Alex (thanks Alex!).
Basically, as strange as it seems, a plane in three.js will not cast shadows unless it is double-sided (Update: Or unless material.shadowSide is set to THREE.FrontSide). Once I set THREE.DoubleSide on the plane material, it worked as expected. Basically, for a textured plane to cast shadows, the following is needed (as of three.js r102):
var mesh = new THREE.Mesh(
new THREE.PlaneGeometry(1,1,2,2),
new THREE.MeshPhongMaterial({
map: texture,
side: THREE.DoubleSide, // important!
alphaTest: 0.1,
})
mesh.customDepthMaterial = new THREE.MeshDepthMaterial({
map: texture
depthPacking: THREE.RGBADepthPacking,
alphaTest: 0.1
})
I also had to adjust the light's shadow bias in order to eliminate artifacts.
I am using the editor as a standalone app and would like there to be an option in the Add menu to place an octahedron into my scene. I thought adding three.module.js to the editor would work but unfortunately it does not.
There doesn't seem to be many questions here on SO about my issue either, which doesn't give me a lot of confidence that a solution is out there. Still, if you have an idea, I'd love to hear it.
Here's an octahedron:
var geometry = new THREE.SphereGeometry( 5, 4, 2 );
var material = new THREE.MeshBasicMaterial( {color: 0xffff00} );
var sphere = new THREE.Mesh( geometry, material );
scene.add( sphere );
https://threejs.org/docs/api/geometries/SphereGeometry.html
In the editor, you can select "Sphere" in the add menu, then click the "Geometry" tab on the right to change the Width Segments to 4 and the Height Segments to 2.
I just discovered this piece of code, which produces a nice Halo effect:
Shader-Halo
I'm planning to remove the texture, and replace the SphereGeometry to a pipe or a line or something which will then act as a part of the lightning (I planing to chain a couple of glowing pipes/lines to appear as a lightning.)
So my question is: how to change this part in the code to draw a pipe/line instead of a sphere:
var ballGeometry = new THREE.SphereGeometry( 120, 32, 16 );
var ball = new THREE.Mesh( ballGeometry, customMaterial );
scene.add( ball );
I'm currently working on my first three js project, and getting quite an education. But, I've hit a wall, and am seeking a generalized outline of what to do.
I have three images that I want to use as background images. I want them to crossfade at a specified interval... let's say every 5 seconds, the background crossfades to the next one. After the last background is displayed, crossfade into the first one, and so forth in a loop.
I've found a few examples where there's crossfading between two objects, like this fiddle, but that seems to depend on having two cameras. I've taken other examples I've found as far as I could, nothing worthy of posting.
I don't understand enough about three, which is why I'm seeking help. If someone could help me define my approach, that would be fantastic. Should I be altering the opacity of my meshes? Doing something with shaders? Something else?
Here, at least, is how I'm adding one background:
camera = new THREE.PerspectiveCamera( 75, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 );
camera.position.z = 450;
scene = new THREE.Scene();
// Load the background texture
var summerTexture = THREE.ImageUtils.loadTexture( 'tree-animation/images/summer.png' );
summerMesh = new THREE.Mesh(
new THREE.PlaneGeometry(2, 2, 0),
new THREE.MeshBasicMaterial({
map: summerTexture,
}));
summerMesh.material.depthTest = false;
summerMesh.material.depthWrite = false;
backgroundCamera = new THREE.Camera();
summerScene = new THREE.Scene();
summerScene.add(backgroundCamera);
summerScene.add(summerMesh);
Any direction would be most appreciated!
This can be achieved by writing a custom shader and using the mix() or smooth-step() function between the images and add a clock to your render loop to update the shader uniforms to manipulate the transition in your shader over time.
Here is an example of a static blend of textures but can easily intergrated into your own project:
http://stemkoski.github.io/Three.js/Shader-Heightmap-Textures.html
check the frag shader
Does someone know how to make the spotlight reflection here: http://web251.merkur.ibone.ch/webgl/three/ look like the one here: http://web251.merkur.ibone.ch/webgl ? i.e. that it gets reflected to the camera? It's weird that it doesn't do so automatically. If you move around the planet with the mouse you'll notice. In this scene everything is static but the camera, and with camera movement also the eye E gets moved around, right? So what I'd expect is the spotLight reflection on the planet is rerendered/recalculated all the time, e.g. with Blinn's Halfvector, leading to a reflection on the planet inbetween E and the spotlight.
Help is really appreciated, we've searched for hours but couldn't find a clue what was wrong with our code!
Thanks in advance
Doidel
The first bit of starting code I used for playing with this was:
http://mrdoob.github.com/three.js/examples/webgl_materials_shaders.html
The key is adding a specularity map with the specularMap property for the (Phong) Material.
Such can be done as follows:
var MySpecularMap = THREE.ImageUtils.loadTexture( "MySpecularImage.jpg" );
var Color = THREE.ImageUtils.loadTexture( "MyColorImage.jpg" );
var mappedTexture = new THREE.MeshPhongMaterial( { color: 0xffffff, map: Color, specular: 0xffffff, specularMap: MymapSpecular} );
sphere = new THREE.SphereGeometry( 600, 32, 32 );
globe = new THREE.Mesh( sphere, mappedTexture );
scene.add( globe );
Also, for this type of demo OrbitControls seem to be the best.
Here's a finished example with {ColorMap, SpecularMap, BumpMap, Clouds, SkyDome}:
http://randompast.github.io/randomtests/three.js/earth/1/index.html