Three.js cylinder example keeps drawing torus - three.js

I'm attempting to get a basic THREE.js example to work and modify it from there on out but it just keeps outputting a torus, no matter what I change.
I've copied the exact code from the docs page into a JSFiddle and again I get a torus.
Here is the docs page example:
CylinderGeometry
And here is the jsfiddle with the torus: https://jsfiddle.net/ded9grxn/
I've tried adding the code from the docs page to the example like so:
var geometry = new THREE.CylinderGeometry( 5, 5, 20, 32 );
var material = new THREE.MeshPhongMaterial(
{
color: 0x156289,
emissive: 0x072534,
side: THREE.DoubleSide,
shading: THREE.FlatShading
});
mesh.add(
new THREE.Mesh(
geometry,
material
)
);
But to no avail. Any help is appreciated!

The reason you fiddle does not work is that the script you invoke (https://threejs.org/docs/scenes/js/geometry.js) looks at the hash in the URL of the window to select the object.
If you go to
https://threejs.org/docs/scenes/geometry-browser.html#CylinderGeometry
you get the cylinder.
If you go to
https://threejs.org/docs/scenes/geometry-browser.html
you get the default, which is a torus.
For the reason why your modification does not work, we need more information about how you performed the modif (what did you remove, where did you add).
(Edit) in the fiddle, after doing your modification, do not forget to remove the line
var options = chooseFromHash( mesh );
this is where your script invokes the function in geometry.js that will set the mesh according to the hash in the URL

Related

Three JS - How do I change from Lambert to Phong on a material at runtime?

I tried setting "type" and then setting "needsUpdate", but it didn't change the type. I know I could make a new material, and then change every mesh that uses that material to use the new material, but I was hoping there was a way I could do it without iterating through every mesh.
You need to create a new material and have the mesh point to it.
mesh.material = new THREE.MeshPhongMaterial({ color: 0xffffff });
Check this fiddle: https://jsfiddle.net/29Lqeadx/.

THREE JS converting to BufferGeometry from Geometry not working when loading PLY file

I am loading a very complex 3D model from a PLY file (over 60Mb). In my project I need to use the orbit-control to move around the object. Obviously due to the large file the operation is painfully slow in some couputers. In order to speed up things a bit I am trying to convert my geometry into a Buffer geometry with the following lines of code:
this.loader.load('assets/data/GuyFawkesMask.ply', function (geometry) {
var bufferGeometry = new THREE.BufferGeometry().fromGeometry( geometry );
console.log(bufferGeometry);
// Create object
let object =
new THREE.Mesh(bufferGeometry,
new THREE.MeshPhongMaterial(
{
color: 0xFFFFFF,
//vertexColors: THREE.VertexColors,
shading: THREE.FlatShading,
shininess: 0
})
);
_this.add(object);
});
But I am getting the following error:
TypeError: Cannot read property '0' of undefined
at DirectGeometry.fromGeometry (three.module.js:12219)
at BufferGeometry.fromGeometry (three.module.js:14307)
at threed-viewer.component.ts:379
at index.js:52
at XMLHttpRequest. (three.module.js:29263)
at ZoneDelegate.webpackJsonp.818.ZoneDelegate.invokeTask (zone.js:367)
at Object.onInvokeTask (ng_zone.js:264)
at ZoneDelegate.webpackJsonp.818.ZoneDelegate.invokeTask (zone.js:366)
at Zone.webpackJsonp.818.Zone.runTask (zone.js:166)
at XMLHttpRequest.ZoneTask.invoke (zone.js:420)
Any idea?
Thank you,
Dino
Just posting prisoner849 comment (as an answer) for future reference:
If I get it right, looking into the source code of PLYLoader.js, the
geometry, which the callback function returns, is already of
THREE.BufferGeometry()

How do you set which side a decal displays on a THREE JS mesh?

I am trying to apply a decal to the outside of a mesh object using DecalGeometry. However, the decal appears on the inside of the mesh. I've tried rotation and position settings within the DecalGeometry, but can't seem to affect which side of the mesh the decal appears on. FWIW, the mesh is a custom OBJ model. My code is a bit extensive to post here, but you can view the issue here. I have red BoundingBoxHelpers to help visualize the placement.
The materials object has a parameter which allows you to designate the side(s) of the mesh on which it will display (thanks #j-t for posting this question Prevent decal from showing on inside of mesh. My working code looks like this...
var decalMaterial = new THREE.MeshPhongMaterial( {
map: decalNormal,
transparent: true,
depthTest: true,
depthWrite: false,
polygonOffset: true,
polygonOffsetFactor: - 4,
side: THREE.DoubleSide
});

Applying a material to an imported model [three.js]

Part of a project that I'm working on requires that I pull in an array of base64 images, then pull in imported models via THREE.JSONLoader(). If I keep these two types of assets apart, they both load without issue. However, if I try to apply the image as a material to the model, I get an error.
WARNING: Output of vertex shader 'vWorldPosition' not read by fragment shader
I realize that much of the time when you load in geometry, you need to run geometry.computeTangets(), but that isn't working. I thought perhaps there's another computation that might need to run prior to creating a mesh with the geometry and the material. Here's what I have:
var material = new THREE.MeshPhongMaterial({
map: THREE.ImageUtils.loadTexture(data.images[0]),
shininess: 4.0,
});
var loader = new THREE.JSONLoader();
loader.load("app/museum/geometry.json", function (geometry) {
geometry.computeTangents();
mesh = new THREE.Mesh(geometry, material);
mesh.scale.set(100, 100, 100);
mesh.position.y = 150;
mesh.position.x = 0;
scene.add(mesh);
});
I assume there's an additional setting or method that needs to be called, or perhaps there are attributes in the geometry.json that I need to set manually?

Three.js - Is FlatShading implemented for BufferGeometry

It seems that setting THREE.FlatShading for a material doesn't work for BufferGeometry. Is it implemented?
I'm creating BufferGeometry with CTMLoader (useBuffers = true) and applying either MeshLambertMaterial or MeshNormalMaterial with shading: THREE.FlatShading.
Three.js still renders everything as SmoothShading.
If I switch to ClassicGeometry (useBuffers = false), everything works as expected. Unfortunately, that would not work for us since our models are huge and that was exactly the reason to use BufferGeometry.
Is it just not implemented or is it very difficult/time-consuming/not-possible to implement?
Thank you in advance for any hints or suggestions. I'm using the latest r58 version.
P.S.
I found a recent Ryan Rix' post on the same topic http://rix.si/2013/04/15/threejs-ctm-and-you/ where he had to switch to ClassicGeometry to make it work.
In three.js r73 flat shading is working with THREE.MeshPhongMaterial for sure. You can use it like this:
geometry = new THREE.BufferGeometry();
//... make your geometry
material = new THREE.MeshPhongMaterial({
color: 0xff0000,
shading: THREE.FlatShading
});
mesh = new THREE.Mesh( geometry, material );
This doesn't work for THREE.MeshLambertMaterial yet. But they are working on it. Check the related issue here on GitHUB.
flatShading does work in MeshPhongMaterial or any other, the property for
flatShading is boolean
flatShading : Boolean
Define whether the material is rendered with flat shading. Default is false.
const PlaneMaterial = new THREE.MeshPhongMaterial({color:'blue',
side:THREE.DoubleSide,
flatShading:true})
Code Snipet

Resources