Buggy edges in three.js when using gltf - javascript

Does anybody know how to get rid of this bug?
It doesn't occur on stuff created in three.js code (as for example the tree is not a .gltf but handcrafted code). However, the "sheep-like" thing I imported through a gltf (exported by blockbench) and I mean yeah - this looks completely inacceptable. I tried different scales but the edges are bugged no matter what scale I set the sheep to.
const loader = new GLTFLoader();
loader.load( './sheep.gltf', function ( gltf ) {
var gltfO = gltf.scene;
//gltfO.scale.set(0.05, 0.05, 0.05);
gltfO.position.set(0,-sz/2,0);
scene.add( gltfO );
}, undefined, function ( error ) {
console.error( error );
} );

Turns out this is an issue with UV Mapping. At least I figured out a work around that one can apply in blockbench. Instead of just painting the rectangle in the UV you also need to paint the border OUTSIDE the rectangle. Not really a solution but it's at least a workaround. Probably doesn't work for non unicolor texture? I don't know. But it works in this case.

Related

Three.js is there a way to adapt the geometry to the texture

I am working in a project in Three.js and I need to have multiple images floating into a 3D space. So I started to simply use these images as textures on planes. However, images have a different height and width so I am just wondering if there is a way to make the plane adapt to the size of the textures. Or be proportional with it.
There's maybe a simple way to do it but I didn't find anything. May one of you can help me, or tell me to stop looking for it ?
When loading a texture, you can check its size and THEN create the plane to host it with the right width/height ratio:
var loader = new THREE.TextureLoader();
var texture = loader.load( "./img.png", function ( tex ) {
console.log( tex.image.width, tex.image.height );
// here you can create a plane based on width/height image linear proportion
} );

three.js rectAreaLight up to date

So this abandoned? feature of three.js seems to have become somewhat of a holy grail; I've tried to implement it a couple of times unsuccessfully.
The example working on an old release is here: https://threejs.org/examples/#webgl_lights_rectarealight
My minimal broken example is here:
https://jsfiddle.net/bitsofcoad/1k3arL33/
var width = 20;
var height = 20;
var rectLight = new THREE.RectAreaLight( 0xffffff, 500, width, height );
rectLight.intensity = 500.0;
rectLight.position.set( 0, 30, 0 );
rectLight.lookAt( mesh2.position );
scene.add( rectLight )
var rectLightHelper = new THREE.RectAreaLightHelper( rectLight );
scene.add( rectLightHelper );
I have made sure to include the proper rectarealight library in the jsfiddle.
This thread was particularly enlightening on the topic of why this PR had some difficulties:
https://github.com/mrdoob/three.js/pull/9234
And this thread was interesting to see how far other people had gotten in developing a similar type of light for three.js:
Improved Area Lighting in WebGL & ThreeJS
I don't really know what happened to break abelnation's example, or even if it is completely broken ( I may have screwed up my jsfiddle... ), but I think there is still considerable interest in this feature.
The soft edges look so nice, I'm tempted to cannibalize WestLangley's custom shader (http://jsfiddle.net/hh74z2ft/89/), which has pretty much all the functionality I need.
Anybody else able to get the basic functions working? Thanks!
Both MeshStandardMaterial and MeshPhysicalMaterial support area lights. The other materials do not.
three.js r.89

Wrong positions of exported objects when exporting from blender to three.js

I'm exporting a simple scene from blender to three. Aside from the texture not showing up (which I'm also fighting with), I have a weird problem with the positions of objects. Here's how it looks in blender:
and this is how it renders in three
as you can see, elements are stacked up on each other (and the skybox texture is missing, even though it's referenced properly in the json, embedded as a base64 image). I'm using Three.js exporter v 1.5.0, three.js v84 and blender v 2.77
this is my configuration:
here's the code loading the scene:
var loader = new THREE.ObjectLoader();
loader.load(
'../dist/landscape.json',
function ( obj ) {
scene.add(obj)
}
);
now, I do realise that this way I'm adding a scene to a scene but for some reason, if I try to extract children from it like this:
loader.load(
'../dist/landscape.json',
function ( obj ) {
obj.children.forEach(function(elem) {
scene.add(elem)
}
}
)
I only get half of the objects. No idea why. Besides the objects are still stacked up on each other. I checked the positions in the result versus the original values in blender, and aside from the standard y/z swap x values are reversed (though that's not the cause of the problem), and rotation is removed from the bridge which causes it to render upside down. I'm completely lost
Also, here are the .blend and .json files:
http://www.filehosting.org/file/details/653174/landscape.blend
http://www.filehosting.org/file/details/653175/landscape.json
EDIT:
Partial solution: Scale was set to 10 in exporter, caused the objects to look as if they were misplaced. The thing is, they are still rotated and there's still some mismatch compared to the original. picture here:
I've just come across this issue for myself once again. Having the scale setting at 1 didn't fix it. The issue was that I hadn't applied object transformations in Blender.
Select all problematic objects in your blender file (or just all with A)
Press CTRL+A
Select Rotation & Scale
Repeat for Location if necessary

How to render clipped surfaces as solid objects

In Three.js, I have a 3d object where I am using local clipping planes to only render a part of the object.
However, since 3d objects are "hollow" (meaning only the outer surface is rendered), when we clip anything off that surface we can "see into" the object. Here's an example of what I mean, clipping a corner off a cube. Notice how we can see the backside of the opposite corner.
I would like to give the appearance of the object being solid. Based on this issue, it seems that the best way to accomplish this is to create a surface over the clipped region, thus capping the hole and making the object appear like it isn't hollow.
My question is, how do I know where to build this surface? Does Three.js provide a way to get a list of vertices that intersect between a plane and any arbitrary surface? If not, how might I approach this problem myself?
I found this question, but the author didn't describe how they solved the problem I am having here.
You want to render a clipped surface as if it were a solid -- i.e., not hollow.
You can achieve that effect with MeshPhongMaterial -- or any three.js material for that matter -- with a simple hack to the material shader.
material.onBeforeCompile = function( shader ) {
shader.fragmentShader = shader.fragmentShader.replace(
'#include <output_fragment>',
`
vec3 backfaceColor = vec3( 0.4, 0.4, 0.4 );
gl_FragColor = ( gl_FrontFacing ) ? vec4( outgoingLight, diffuseColor.a ) : vec4( backfaceColor, opacity );
`
)
};
This should look pretty good. It will require material.side = THREE.DoubleSide;
Alternatively, see https://threejs.org/examples/webgl_clipping_stencil.html.
three.js r.148
I made a THREE.SectionHelper class which could be interesting if you want to set a different material/color for the inside of the mesh that you are clipping. Check a demo in this fiddle.
var sectionHelper = new THREE.SectionHelper( mesh, 0xffffff );
scene.add(sectionHelper);

Disappearing Objects - Three.js CanvasRenderer

I am very stuck, I do not understand why my objects are disappearing with canvas renderer. While it works exactly as expected with webGL renderer, I need to display this on mobile devices and as such do not have access to a webGL renderer
I have tried overdraw:true but this does not seem to make the missing objects disappear
http://jsfiddle.net/xH9GD/3/
When I comment out the room the boxes remain but they get very mangled on my iPhone.
I understand the concept of Z-fighting however I don't think this is occurring as the zPosition of each of the faces should be seperate to the others
floor = drawTopFacingWall(room.width, room.length );
wall1 = drawLeftFacingWall( room.length, room.depth );
wall2 = drawFrontFacingWall( room.width, room.depth );
wall3 = drawRightFacingWall( room.length, room.depth );
roof = drawBottomFacingWall( room.width, room.length );
wall4 = drawBackFacingWall( room.width, room.depth );
The "disappearing" geometry is caused by a limitation of CanvasRenderer due to the way it handles depth-sorting.
While WebGLRenderer sorts at the pixel level, CanvasRenderer sorts at the polygon level.
The best you can do is to increase the tessellation of your geometry.
var geometry = new THREE.PlaneGeometry( width, height, 10, 10 );
three.js r.66

Categories