Three.js secret: I cannot run any example - three.js

I'm beginner in WebGL
I follow the examples and I always get error.
Why my example does not work.
While it works for the others with similar code?
(function() {
// Set basic some variables.
var documentWidth = document.body.clientWidth,
documentHeight = document.body.clientHeight,
viewAngle = 45,
drawNear = 0.1,
drawFar = 10000,
aspectRatio = documentWidth / documentHeight,
renderer = new THREE.WebGLRenderer(),
scene = new THREE.Scene();
... follow jsfiddle

you did not include three.js. https://jsfiddle.net/2pha/naudwtaL/1/
https://rawgit.com/mrdoob/three.js/master/build/three.min.js
The older design of jsfiddle made it easy to include some external libraries by having a combobox for you to select from.
The new design has moved these options as seen in the below picture.
While you can add three.js via the combobox selector thing, as of now you can only include three.js r54 which is quite old, so you are probably better off including it the way I did in the fiddle I linked to.

Related

Three.js | Not able to add Dynamic Text Geometry to 3d mesh

I am working on a POC in which I have to customize a watch in 3d model.
I am using thee.js for doing webgl stuff. I was able to change strap color , dial color and load texture images on strap. But I am stuck when I try to add dynamic text on the the watch , I have to update text on watch's back dial as user types in Engrave Text text box . For this I tried https://github.com/jeromeetienne/threex.dynamictexture library , which works on a new geometry but I am not able to add it watch's existing model.
I have pushed all code in github : https://github.com/bhupendra1011/watch-3d-engrave , as I was not able to load external 3d models from my fiddle account {CORS issue}.
Demo of the POC can be seen here : https://bhupendra1011.github.io/watch-3d-engrave/index.html
Below is the code to add text on watch dial; For loading text click on use textures textbox in index.html
function engraveTextOnWatch(val = "IWC") {
dynamicTexture = new THREEx.DynamicTexture(512, 512);
dynamicTexture.context.font = "bolder 90px Verdana";
// watch back dial geometry & material where text needs to be engraved
var backDialGeometry = object3d.children[1].children[0].children[0].geometry;
var backDialMaterial = object3d.children[1].children[0].children[0].material;
// geometry to add dynamic text
var geometry = new THREE.CubeGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({
map: dynamicTexture.texture
});
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh); // adding mesh to scene , but this needs to be attache to watch's back dial geomtry
/* tried adding dynamicTexture to watch back dial material, but this is not working , text not appearing */
//backDialMaterial.map = dynamicTexture.texture;
dynamicTexture.texture.needsUpdate = true;
dynamicTexture.drawText(val, 2, 256, "orange");
}
Kindly let me know how can I add dynamic text on existing model.
Thanks.
I was able to reproduce your problem in Blender and it comes from your model's UV map.
I downloaded your model, opened it in Three.js editor and converted it to .obj to open it in blender to reproduve your problem
As you can see on the image, applying a texture is just as messy. You need to rework the model's uvmap to achieve the desired effect like so (I used a random image from your folder)
And while you're at it, you might want to consider optimizing your model, which is pretty heavy and could be simplified for faster load without losing visual quality (but it's entirely up to you, I'm just suggesting).
Here's the current model
Here's a quick possible replacement. Cylinder that's open on one end and beveled on the edge loop

Jmonkey: Make RigidBodyControl React to Gravity

I am trying my best to make an object fall, and so far I can't even come close. Here is the code i am trying.
BulletAppState bulletAppState = new BulletAppState();
cubemesh = new Box(1f,1f,1f);
Geometry something = new Geometry("cube", cubemesh);
Material bronze = new Material(assetManager,
"Common/MatDefs/Light/Lighting.j3md");
something.setLocalTranslation(0,1,0);
bronze.setTexture("DiffuseMap", assetManager.loadTexture("Textures/bronze.jpg"));
something.setMaterial(bronze);
rootNode.attachChild(something);
RigidBodyControl control = new RigidBodyControl(10f);
Vector3f direction = new Vector3f(0,-9.81f,0);
something.addControl(control);
//all the random lines i've tried
stateManager.attach(bulletAppState);
control.setGravity(direction);
bulletAppState.getPhysicsSpace().setGravity(direction);
rootNode.attachChild(something);
bulletAppState.getPhysicsSpace().add(control);
Help will be appreciated.
The physics in your example do work for me. But using your material, i can't see anything because there's no light.
Try attaching a Light:
AmbientLight light = new AmbientLight();
light.setColor(ColorRGBA.White);
rootNode.addLight(light);
Trying random lines won't get you very far. I recommend reading the jME wiki so you understand what these lines actually do. Here's a minimalistic example which uses a Material that doesn't need light:
public void simpleInitApp() {
BulletAppState bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
Geometry something = new Geometry("cube", new Box(1,1,1));
something.setMaterial( new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md") );
something.setLocalTranslation(0,2,0);
something.addControl( new RigidBodyControl(10f) );
rootNode.attachChild(something);
bulletAppState.getPhysicsSpace().add(something);
}
This example displays a colourful falling cube. If this doesn't work for you, there might be something wrong with your jME version or its setup
(I'm using jMonkeyEngine 3.1-alpha1).

Three js crossfade three backgrounds continously

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

Outline object (normal scale + stencil mask) three.js

For some time, I've been trying to figure out how to do an object selection outline in my game. (So the player can see the object over everything else, on mouse-over)
This is how the result should look:
The solution I would like to use goes like this:
Layer 1: Draw model in regular shading.
Layer 2: Draw a copy in red color, scaled along normals using vertex shader.
Mask: Draw a black/white flat color of the model to use it as a stencil mask for the second layer, to hide insides and show layer 1.
And here comes the problem. I can't really find any good learning materials about masks. Can I subtract the insides from the outline shape? What am I doing wrong?
I can't figure out how to stack my render passes to make the mask work. :(
Here's a jsfiddle demo
renderTarget = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, renderTargetParameters)
composer = new THREE.EffectComposer(renderer, renderTarget)
// composer = new THREE.EffectComposer(renderer)
normal = new THREE.RenderPass(scene, camera)
outline = new THREE.RenderPass(outScene, camera)
mask = new THREE.MaskPass(maskScene, camera)
// mask.inverse = true
clearMask = new THREE.ClearMaskPass
copyPass = new THREE.ShaderPass(THREE.CopyShader)
copyPass.renderToScreen = true
composer.addPass(normal)
composer.addPass(outline)
composer.addPass(mask)
composer.addPass(clearMask)
composer.addPass(copyPass)
Also I have no idea whether to use render target or renderer for the source of the composer. :( Should I have the first pass in the composer at all? Why do I need the copy pass? So many questions, I know. But there are just not enough resources to learn from, I've been googling for days.
Thanks for any advice!
Here's a js fiddle with working solution. You're welcome. :)
http://jsfiddle.net/Eskel/g593q/6/
Update with only two render passes (credit to WestLangley):
http://jsfiddle.net/Eskel/g593q/9/
The pieces missing were these:
composer.renderTarget1.stencilBuffer = true
composer.renderTarget2.stencilBuffer = true
outline.clear = false
Now I think I've found a bit simpler solution, from the THREEx library. It pre-scales the mesh so you dont need a realtime shader for it.
http://jeromeetienne.github.io/threex.geometricglow/examples/geometricglowmesh.html

Lights look different in Three.js than 3DS Max

I am using the r65 of Three.js. When I light a scene in 3ds max I then export it as a an obj to load in Three.js. I take a second step and export the model to FBX so I can extract the lighting and load in Three.js. I am noticing that the lights are not as "strong" in Three.js, almost like a multipier should be added to the intensity possibly? Could it be that I am missing some property on the light in Three.js?
Here is what the scene looks like in 3ds Max
Here is what it looks like when it's imported to Three.js
After playing around with settings, after turning on the gammaOutput and gammaInput
So it looks a little better with the gamma output on, but still not what I was hoping it would look like from 3ds max. I created a fiddle but due to the Access-Control-Allow-Origin errors I couldn't figure out how to get the fiddle to work, but hopefully the code there will help see what I am trying to do.
// scene
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer();
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
renderer.gammaOutput = true;
renderer.gammaInput = true;
container.appendChild(renderer.domElement);
loader = new THREE.OBJMTLLoader();
var modelFilePath = "http://goo.gl/ecHpSf?gdriveurl";
var materialFilePath = "http://goo.gl/bZWZEA?gdriveurl";
loader.load(modelFilePath, materialFilePath, function (object) {
materials.push.apply(materials, object.children);
scene.add(object);
object.position.set(0, 0, 0);
});
// setup lighting
var light = new THREE.PointLight(0xffffff, 1);
light.position = new THREE.Vector3(32.2274, 54.6139, 38.2715);
light.distance = 103.74199676513672;
light.intensity = 1;
scene.add(light);
Can anyone suggest anything that might help, it seems like I am close. Thanks!
Do check out material specular component. R65 changed a bit specular component
computation: #4636 (WebGLRenderer: Specular component implementation)
I've got similar problem implementing A3dsViewer 3ds converter to the three.js.
Try to export/save 3ds file and do conversion with the A3dsViewer to the three.js
maybe such workflow will help.
Additionally maybe such settings can help:
renderer.gammaInput = false; // do false
renderer.gammaOutput = true;
After further experimenting I have found that 3ds max has values set for far attenuation start/end. As far as I can tell, there is no way to export this value into Three.js since far attenuation [End] == Distance. Doing a search, it looks like I am limited by the values the light source takes in Three.js. I will follow this up with another post on SO.

Resources