Three.js - WebGL Rendering Canvas remains black - javascript

I recently started to work with WebGL by using the Threejs libary.
I tried to create some sort of image viewer, but I just can't seem to figure out how to do it right.
I want to display the image, a texture fetched from a HTML5-Canvas, on a PlaneGeometry object.
My code looks like this:
var RunWebGL = function(img, canvas){
var renderer = new THREE.WebGLRenderer();
renderer.setSize(img.width, img.height);
document.body.append(renderer.domElement);
//Init the Scene;
var scene = new THREE.Scene();
//Init the Camera;
var camera = new THREE.PerspectiveCamera(70, img.width/img.height, 1, 1000);
scene.add(camera);
//Init the texture from the image displayed in the canvas. Then use this image to create the Mesh used to give the created plane a texture;
var texture = new THREE.Texture(canvas);
var material = new THREE.MeshBasicMaterial({map : texture});
var geometry = new THREE.PlaneGeometry(img.widht, img.height);
var mesh = new THREE.Mesh(geometry, material);
//Init the Geometry and the texture(material) and mesh it together;
scene.add(mesh);
renderer.setClearColor(0xEEEEEE);
texture.needsUpdate = true;
renderer.render(scene, camera);
};
The HTML5-Canvas, which provides the image, displays it as expected.
Everything I get from the WebGL part tho is a black square everytime this code executes. On the search for an answer on this problem, I added "renderer.setClearColor();" - Which hasn't changed anything, execpt that I'm now getting a smooth grey instead of a dead black square.
I'm getting no Errors/Warnings/Whatsoever.
The img-object that is passed into my RunWebGL function is a standard JavaScript Image object.
If I could use this image as a texture instead of the canvas, I would be really happy. But an answer using the Canvas, or even a hint could help to decrease my struggle.
//Edit: I have created a JS-Fiddle that shows my problem. Here's the link: https://jsfiddle.net/a5ufknLu/2/
Cheers and thanks in advance,
Michael

Related

How do I make the alpha channels of my animated sprite see through?

I'm trying to learn the capabilities of ThreeJS by making a small game. I have an animated sprite that is working great in my scene by using a PlaneGeometry and using a png texture in my MeshBasicMaterial but unfortunately even though my png has an alpha channel, the mesh is displaying the alpha channel as black when instead I'd prefer it to obviously be transparent. Is there a way to correct this?
//this is a customer function you can see at the top of my codepen
texture = new THREE.SpriteSheetTexture('assets/monster.png', 4, 1, 250, 4);
//loading the basic material here
var material = new THREE.MeshBasicMaterial({
map: texture
});
geometry = new THREE.PlaneGeometry(1, 1, 1, 1);
monster = new THREE.Mesh( geometry, material );
scene.add( monster );
You can view how I have the code laid out here, note though, I cannot get the png resource working on codepen:
https://codepen.io/GreedFeed/pen/yrqpQY
You've to set the .transparent property of the THRRE.Material which states the material transparent and activates the special treatment of transparent objects:
var material = new THREE.MeshBasicMaterial({
map: texture,
transparent: true
});

Google Chrome is not displaying javascript updates (using Three.js)

I'm following along with this youTube tutorial https://www.youtube.com/watch?v=axGQAMqsxdw to create a POV game. I got to episode 8 of the tutorial, then google chrome began showing a white screen no matter what I changed in the javascript. There are no warnings or problems when inspecting the code with chrome's developer tools either.
I've tried to start from scratch with completely new files. I've cleared the caches for chrome. I've double checked the source code with my altered code, but none of my alterations seem like they would cause a problem (I am new to javascript though, so that could be a problem). Below is the newly started js file based 100% off the youTube tutorial.
var scene, camera, renderer, mesh;
function init(){
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x8CD9FF );
camera = new THREE.PerspectiveCamera (90, 1280/720, 0.1, 10);
mesh = new THREE.Mesh(
new THREE.BoxGeometry(1,1,1),
new THREE.MeshBasicMaterial ({color: 0xff9999, wireframe: true})
);
scene.add(mesh);
renderer = new THREE.WebGLRenderer();
renderer.setSize(1280/720);
document.body.appendChild(renderer.domElement);
animate();
}
function animate(){
requestAnimationFrame(animate);
renderer.render(scene,camera);
}
window.onload = init;
Take a look at the THREE documentation concerning renderer size here.
You need to set width and height pixels and not the ratio, so try to replace renderer.setSize(1280/720); with renderer.setSize(1280, 720)

Three.js r74 JSONLoader binds duplicate of all geometry to first bone

I'm rewriting this question since I understand more about the bug now. It looks like when using the JSONLoader in r74, the first named bone in an exported Maya scene gets a duplicate of all the geometry.
EDIT: Here's a JSFiddle
In this example I have 2 boxes. Each box is bound to a single bone, and each of those bones has keyframes that animate the position and rotation. There is another bone that has no geometry bound to it, and has keyframes that make no change to its position or rotation.
The stationary bone is called "joint1" in Maya. The bones that actually have geometry bound to them are called "joint2" and "joint3". If I were to rename the stationary bone "joint4" the result would be a duplicate of both boxes attached to the currently animating "joint2".
My guess is that either this is a bug, or I'm doing something wrong when loading the animations. Any tips would be appreciated. The only workaround I can figure out right now is to separate each animated object into a separate file, and that's really not feasible. Plus, that wouldn't solve the issue when I have a multi-bone skeleton. This example is just single bone rigs with no actual deformation.
Here's my current loader code.
//Load Scene, Materials, and Animation
var mixer, mesh;
var actions = {};
var sceneLoader = new THREE.JSONLoader();
sceneLoader.load( sceneFile, function( geometry,materials ) {
materials.forEach( function( material ){
material.skinning = true;
});
mesh = new THREE.SkinnedMesh( geometry, new THREE.MeshFaceMaterial( materials ) );
mixer = new THREE.AnimationMixer( mesh );
actions.main = mixer.clipAction( geometry.animations[ 0 ]);
actions.main.setEffectiveWeight( 1 );
actions.main.play();
scene.add( mesh );
});
//Render
var render = function () {
requestAnimationFrame( render );
controls.update;
var delta = clock.getDelta();
var theta = clock.getElapsedTime();
if ( mixer ) { mixer.update( delta ); }
renderer.render(scene, camera)
}
render();
This is still an issue, but I've found an ok workaround.
Since the duplicated geometry always gets assigned the default lambert shader that is always included when using the Maya Exporter. As long as all the objects that are intended to be kept have a material other than the default in Maya, you can insert
mesh.material.materials[0].visible = false;
into the loader code which will make any material with the default lambert invisible.
Here's a fiddle

Three.js - Extreme shadow on face of mesh

I've created a chest model using blender, created a handpainted texture for it and set the whole thing up in an environment rendered with Three.js. The chest front face however has a unusually extreme shadow:
Here's my Renderer setup:
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
return renderer;
This is the light source (in the screenshot, it's the only light source) causing this shadow:
var envLight = new THREE.PointLight(color, 0.5, 320);
envLight.position.set(0, 80, zPos);
return envLight;
Material setup:
var material = new THREE.MeshPhongMaterial();
//diffuse texture setup
material.map = THREE.ImageUtils.loadTexture(textureURL);
material.map.wrapS = material.map.wrapT = THREE.RepeatWrapping;
material.map.repeat.set(repeatX, repeatY);
// specular map setup
material.specularMap = THREE.ImageUtils.loadTexture(specularMapURL);
material.specularMap.wrapS = material.specularMap.wrapT = THREE.RepeatWrapping;
material.specularMap.repeat.set(repeatX, repeatY);
material.specular = that.specularLightingColor;
return material;
The mesh is created using this material together with the JSON data containing the geometry and UV mapping exported from Blender. I use THREE.JSONLoader to get the data at runtime.
Here's a screenshot from blender showing the mesh and UV map unwrapped, it seems to be an issue with the selected face as it matches the exact shape and position of the weird shadow.
I've tried disabling the shadow with Object3D's castShadow/receiveShadow attributes but that doesn't show any effect at all.
Another screenshot of the normals orientation of the mesh
(source: front-a-little.de)
I've updated to the latest three.js release (r70) and updated the completely re-written Blender Export addon.
The described issue was most likely a bug in a previous version of this exporter, an exported model using the new addon doesn't show the weird shadow.
The new exporter comes with new settings in the save screen, I had to make sure the "UVs" box under "Materials" is checked in order to load the model via Three.JSONLoader

How to use camera as texture image in Three.js

In three.js, I am trying to create a texture whose image is the current scene as viewed from a Camera. Using a CubeCamera to create a similar effect is well-documented; and with CubeCamera I have created an example of a scene to illustrate my goal at:
http://stemkoski.github.com/Three.js/Camera-Texture-Almost.html
However, I would like to use a regular Camera (rather than a CubeCamera) as the texture. How could I do this?
Ideally this would work.
Init:
renderTarget = new THREE.WebGLRenderTarget( 512, 512, { format: THREE.RGBFormat } );
var planelikeGeometry = new THREE.CubeGeometry( 400, 200, 200 );
var plane = new THREE.Mesh( planelikeGeometry, new THREE.MeshBasicMaterial( { map: renderTarget } ) );
plane.position.set(0,100,-500);
scene.add(plane);
Render:
renderer.render( scene, topCamera, renderTarget, true );
renderer.render( scene, topCamera );
And it almost does, but we have some unfinished business with y-flipped textures that ruins the party here.
So the best solution at the moment is to use the intermediry quad for flipping the texture (also saves a render):
http://mrdoob.github.com/three.js/examples/webgl_rtt.html
Based on mrdoob's example and suggestions, I have created a working example with very detailed comments, available at:
http://stemkoski.github.com/Three.js/Camera-Texture.html
part of my series of tutorial-style Three.js series of examples at
http://stemkoski.github.com/Three.js/

Categories