Three.js - Extreme shadow on face of mesh - javascript

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

Related

Three.js – Applying texture to Collada mesh yields unexpected result

Following the Three.js ColladaLoader example, I've exported a Cinema4D soda
can model (consisting of 4 meshes) to a .dae file. One of the meshes, the body of the can, I want to add a texture to.
In Cinema4D I've already made a texture based on a UV map of the mesh (spherical). However, when I try to apply the texture to the mesh, it simply shows a solid white fill. I've added the entire code in this Codepen. Relevant code below, edited for brevity:
loader = new THREE.ColladaLoader();
loader.load('can.dae', function (collada) {
can = collada.scene;
can.traverse(function (node) {
var textureLoader
if (node.name == 'wrapper') {
textureLoader = new THREE.TextureLoader();
textureLoader.load('wrapper.png', function (texture) {
node.material = new THREE.MeshBasicMaterial({
map: texture
});
node.material.needsUpdate = true;
});
}
});
scene.add(can);
});
Illustration of the result. As you can see, the wrapper of the can isn't the red wrapper.png provided, but a solid white fill. I've tried experimenting with mapping and wrapping modes, but to no avail. Any help very much appreciated!
FYI: I've already ruled out CORS issues.
I added a cube in your loader and gave it that material and it worked.. so the implication is that your can mesh does not have proper UV coordinates assigned to it.. Perhaps it is using an automatic cylindrical mapping in your authoring software which is not exporting it's UVs? What software are you authoring in?
scene.add(new THREE.Mesh(new THREE.BoxGeometry(1,1,1),node.material));
https://codepen.io/manthrax/pen/ePBZbZ?editors=1001

Three.js: flip image loaded with loadTextureCube

I have a legacy code snippet that has long since been part of a web application. The goal is to render a cube from 6 image urls via three.js. The problem is, that the bottom image is flipped around on its y axis. All other sides look fine.
There is no way to flip the original image, since they are provided by an external service. Also when I open the bottom image directly, it is displayed correctly, only in the three.js cube its flipped.
Since I have no prior experience with three.js, I first looked at the documentation for this functionality and realized that the code used in our script is deprecated. unfortunately there is no detailed documentation of the old function (THREE.ImageUtils.loadTextureCube) - or I was simply unable to find it (if someone knows where it is, a link would be great!).
I know that for the long term, a reimplementation to replace all deprecated functions would in order, but since this would take a lot more time (for someone unfamiliar with three.js), I first wanted to check if the problem can be fixed using the existing code base.
I read in various other posts/issues that this is a known issue because three.js for some internal reason defaults to flipY=true on textures. The problem I have is that I don't know (due to lack of documentation) how to change this parameter on one side of the cube only. I expect a function can be applied to the loader that could update this parameter for one of the images or a transformation could be applied to the loaded image afterwards.
I really hope somebody knows (remembers) how this can be achieved with the old loader function.
The following partial code is from my script:
// passed list of urls (images.bottom is flipped around)
var urls = [ images.left, images.right, images.top, images.bottom, images.back, images.front ];
// SCENE
scene = new THREE.Scene();
// TEXTURES
textureCube = THREE.ImageUtils.loadTextureCube( urls );
textureCube.format = THREE.RGBFormat;
textureCube.mapping = THREE.CubeReflectionMapping;
// MATERIALS
var cubeShader = THREE.ShaderLib[ "cube" ];
var cubeMaterial = new THREE.ShaderMaterial( {
fragmentShader: cubeShader.fragmentShader,
vertexShader: cubeShader.vertexShader,
uniforms: cubeShader.uniforms,
depthWrite: false,
side: THREE.BackSide
} );
cubeMaterial.uniforms[ "tCube" ].value = textureCube;
var cubeGeometry = new THREE.BoxGeometry(50,50,50);
cube = new THREE.Mesh( cubeGeometry, cubeMaterial );
scene.add( cube );
// RENDER
renderer = new THREE.WebGLRenderer();
renderer.autoClear = false;
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( containerWidth, containerHeight );
renderer.setFaceCulling( THREE.CullFaceNone );
$container.append( renderer.domElement );
...

Three-JS Mesh visible on opposite side of model

So I'm using a custom model made in blender for ThreeJS. I exported it to a .obj file and used the Three-js conversion utility to make a json file. I have it set to rotate, and as it rotates, you can see the other side of the model.
This is the code I'm using to load it:
loader.load("pegnin.js", function(geometry, materials){
material = new THREE.MeshPhongMaterial( {
color: 0xff0000,
polygonOffset: true,
polygonOffsetFactor: 1, // positive value pushes polygon further away
polygonOffsetUnits: 1
});
material.depthTest = true;
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
});
Live Demo
three.js assumes that front-faces have counter-clockwise winding order. Stated another way, the front-face in three.js is determined by the winding order of the face -- not the face normal.
It is likely that front-faces in your model have clockwise winding order.
A work-around that does not require you to change your model is to set:
mesh.material.side = THREE.DoubleSide;
three.js r.85

Three.js - WebGL Rendering Canvas remains black

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

How to texture animated js model exported from blender ? [Three.js]

I have successfully animated a model in blender using bone animation technique and i have also textured it in blender using uv texturing. Then Using three.js export add-on in blender i have exported the model making sure uv and animation in checked in. However i don't know the technique to load the texture for the animated model. I viewed the morph normal example included in three.js where there is simple color texture is used using Lambert material. I have texture from external file. How do i load the texture. In js animated model file there is location for the texture and it is in same location. But it doesn't load. i used the face material technique as well.
the location for three.js example that i used to modify:
http://threejs.org/examples/webgl_morphnormals.html
Here is my code:
var loader = new THREE.JSONLoader();
loader.load( "bird_final.js", function( geometry, materials ) {
morphColorsToFaceColors( geometry );
geometry.computeMorphNormals();
// the old code to set color to the model
//var material = new THREE.MeshLambertMaterial( { color: 0xffffff, morphTargets: true, morphNormals: true, vertexColors: THREE.FaceColors, shading: THREE.SmoothShading } );
// my code
var meshAnim = new THREE.MorphAnimMesh( geometry, new THREE.MeshFaceMaterial( materials ) );
meshAnim.duration = 500;
meshAnim.scale.set( 20, 20, 20 );
meshAnim.position.y = 150;
meshAnim.position.x = -100;
scene1.add( meshAnim );
morphs.push( meshAnim );
} );
Except the documentation and some basic tutorials scattered across the web, is there anywhere i can learn three.js from ground up. like i know setting up scene and creating basic geometry stuffs but some detail info like loading textured model loading scenes etc.
I have created a series of commented examples for Three.js that illustrate features one at a time, starting with very basic features and progressing to more advanced ones (including loading models).
http://stemkoski.github.io/Three.js
Hope this helps!
Working with complex geometry, materials, textures, and animations are some of the hardest things to figure out in THREE.js - that's why we started there with our editor.
We make all of these easy. Export an FBX file (or OBJ/MTL, or Collada) from Blender. Bring it into a project in Verold Studio, then load it into your THREE.js program using our loader. Service is free for use, you pay us if you want enablement services or have a client who wants a maintenance/support agreement.
See the example below, couldn't be easier to bring your scene to THREE.js,
http://jsfiddle.net/rossmckegney/EeMCk/
// 1. Set and then start the animation :)
this.model.setAnimation("mixamo.com");
this.model.playAnimation(true);
//this.model.pauseAnimation();
// 2. Get the threedata for a model
console.log(this.model.threeData);
// 3. Move the model
this.tweenObjectTo(
this.model.threeData, // the model
new THREE.Vector3(1, 0, 0), // go to
new THREE.Quaternion(), // rotation
1, // time, in seconds
false, // smooth start
true); // smooth end
// 4. Clone the model
that = this;
this.model2 = this.model.clone({
success_hierarchy: function(clonedModel) {
that.veroldEngine.getActiveScene().addChildObject(clonedModel);
}
});

Categories