Three.js cannot recognize OBJ format files exported with NURBS? - javascript

Obj files exported by rhino software,How to Convert Mesh Surface into Surface in three.js
I tried flatShading and smoothShading, but it didn't work.
The following figure is the vertex normal
The following is a reflection map added.
var objLoader = new THREE.OBJLoader();
objLoader.setPath('models/obj/');
objLoader.load('ball2.obj', function (object) {
var materials = new THREE.MeshBasicMaterial({
color: 0xF3FFE2,
specular: 0xffffff,
// shininess: 2,
// shading:THREE.SmoothShading
// flatShading: true
// smoothShading:true,
envMap: scene.background
});
object.children.forEach(function (child) {
child.material = materials;
child.geometry.computeFaceNormals();
child.geometry.computeVertexNormals();
});
object.scale.set(15, 15, 15);
scene.add(object);
});
my modul https://gist.github.com/grayFinger/308a07877d3deb10ad0694f1ffa3c383
Please answer for me.What The effect I want is
.

Related

Change color of three.js mesh using gui.dat

I have a three.js mesh loaded from an STL file:
var loader = new THREE.STLLoader();
var materialmodel = new THREE.MeshPhongMaterial(
{
color: 0xFF0000,
specular: 0x222222,
shininess: 75
}
);
function model()
{
loader.load( 'models/stl/binary/model.stl', function ( geometry ) {
var meshMaterial = materialmodel;
var model = new THREE.Mesh( geometry, meshMaterial );
model.scale.set( 0.02, 0.02, 0.02 );
model.castShadow = true;
model.receiveShadow = true;
model.geometry.center();
scene.add(model);
render();
} );
}
model();
When I call the model function in my page, the model renders as expected.
I want to use dat.gui to as a lightweight interface for on the fly changes.
My first experiment is changing the color of the model.
The code I'm using is this:
var params = {
modelcolor: 0xff0000, //RED
};
var gui = new dat.GUI();
var folder = gui.addFolder( 'Model Colour' );
folder.addColor( params, 'modelcolor' )
.name('Model Color')
.listen()
.onChange( function() { materialmodel.MeshPhongMaterial.color.set( params.modelcolor); } );
folder.open();
DAT.GUIs color picker appears fine, and I can select a color from the picker and the new hex value will display.
However, the model/mesh itself doesn't update with the newly selected colour.
I'm wondering if it's something to do with how I'm changing the color materialmodel.MeshPhongMaterial.color.set( params.modelcolor); (I've tried different ways of doing this with no luck).
I've seen a post here (one of the answers) where they're doing this using model.material.color.set(params.color) in their example. My owen material properties are defined in a variable using a THREE.MeshPhongMaterial.....
Assuming this is where I've gone wrong, how can I change the color dynamically of a nested prroperty buried in a variable like this?
I didn't get why did you use .listen(), possibly there's a certain reason.
In .onUpdate function you're using materialmodel, which is a material itself, and then you're setting .MeshPhongMaterial property that doesn't exist. Looks like you simply overlooked it.
Here is a working example:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 10);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.setScalar(10);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.5));
var materialmodel = new THREE.MeshPhongMaterial({
color: 0xFF0000,
specular: 0x222222,
shininess: 75
});
var geometrymodel = new THREE.SphereBufferGeometry(5, 32, 16);
var model = new THREE.Mesh(geometrymodel, materialmodel);
scene.add(model);
var params = {
modelcolor: "#ff0000"
};
var gui = new dat.GUI();
var folder = gui.addFolder('Model Colour');
folder.addColor(params, 'modelcolor')
.name('Model Color')
.onChange(function() {
materialmodel.color.set(params.modelcolor);
});
folder.open();
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.2/dat.gui.min.js"></script>

Shadows not received on faces in ThreeJS Object Group

I have a problem with shadows not being received on the faces in an Object3D group.
The shadows are being cast from the objects and received by the ground, but the shadows are not received by each other when they should.
I've searched around but I can't seem to find a similar problem which leads me to believe I'm setting something up incorrectly.
Would anyone be able to take a look? I've put a working example in the below JSfiddle. I think it might be an issue with the way I'm setting up the faces.
https://jsfiddle.net/shanemccster/848k1qxh/
var makeobject = function(width, height, depth){
logger('makeobject fired');
var geometry = new THREE.BoxGeometry( width, height, depth );
var materials = [
new THREE.MeshLambertMaterial({ color: 0xffffff }),
new THREE.MeshLambertMaterial({ color: 0xffcc00 }),
new THREE.MeshLambertMaterial({ color: 0xffffff }),
new THREE.MeshLambertMaterial({ color: 0xffcc00 }),
new THREE.MeshLambertMaterial({ color: 0xffffff }),
new THREE.MeshLambertMaterial({ color: 0xffcc00 })
];
var texture = new THREE.MeshFaceMaterial( materials );
texture.minFilter = THREE.LinearFilter;
var theObject = new THREE.Mesh(geometry,texture);
theObject.recieveShadow = true;
theObject.castShadow = true;
return theObject;
}
You need to set the receiveShadow flag on your meshes. Look at the documentation of Object3D which is the parent of Mesh.
https://jsfiddle.net/woa7kzz1/

How to merge three.js meshes into one Mesh?

Is it possible in Three.js to merge two or more meshes, with different materials?
The solutions I've found, merges geometry only, or just puts the Meshes into one Object3D or Group.
Yes: Kind-of (see the comments attached to the question and this answer post):
var blueMaterial = new THREE.MeshPhongMaterial( {color: 0x0000FF } );
var redMaterial = new THREE.MeshPhongMaterial({ color:0xFF0000 });
var meshFaceMaterial = new THREE.MeshFaceMaterial( [ blueMaterial, redMaterial ] );
var boxGeometry = new THREE.BoxGeometry( 10, 10, 10 );
for ( var face in boxGeometry.faces ) {
boxGeometry.faces[ face ].materialIndex = 0;
}
var sphereGeometry = new THREE.SphereGeometry( 5, 16, 16 );
sphereGeometry.applyMatrix( new THREE.Matrix4().makeTranslation(0, 5, 0) );
var mergeGeometry = new THREE.Geometry();
mergeGeometry.merge( boxGeometry, boxGeometry.matrix );
mergeGeometry.merge( sphereGeometry, sphereGeometry.matrix, 1 );
var mesh = new THREE.Mesh( mergeGeometry, meshFaceMaterial );
scene.add( mesh );
I went with a cube and a sphere because a box for example wants to know a material id for each of its faces.
http://jsfiddle.net/v49ntxfo/

Issues of using "THREE.BufferGeometry()" in the more recent three.js (r71): no mesh in the scene, glDrawArrays and vertexAttribPointer related errors

I tried the example from the website: http://www.aptagraphis.com/3ds_samples/ship/, and it works fine. However, they use the 63th revison of three.js. When I use more recent the 71th revision of three.js, the mesh does not appear on the scene, and console outputs the errors like:
three_r71.js:20261 WebGL: INVALID_OPERATION: vertexAttribPointer: no bound ARRAY_BUFFER
5index.html:1 [.WebGLRenderingContext-05EBE9A0]GL ERROR :GL_INVALID_OPERATION : glDrawArrays: attempt to access out of range vertices in attribute 0
The simplified and extracted code which causes the issues:
function create_geometry (scene) {
var material;
var geometry;
geometry = new THREE.BufferGeometry();
geometry.attributes = {
position: {
itemSize: 3,
array: new Float32Array([
38.584, 3086.240, -1251.993,
38.584, 2854.030, -665.175,
-41.416, 2854.030, -665.175,
38.584, 2251.488, -505.608
])
},
normal: {
itemSize: 3,
array: new Float32Array([
0.000, -0.930, -0.368,
0.000, -0.930, -0.368,
38.584, 1726.241, -311.993,
1.000, 0.000, 0.000
])
},
uv: {
itemSize: 2,
array: new Float32Array([
0.624, 0.344,
0.085, 0.380,
0.085, 0.656,
0.624, 0.344
])
}
};
material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
}
Adding "geometry.computeTangents();" did not solve anything.
Which upgrades did cause that error? How to avoid it using three.js (r71)?

How can I get the createMultiMaterialObject in THREE.js to work properly in r62?

I simply cannot make createMultiMaterialObject to work like I assume it's intended to work.
I want a wireframe material being displayed on top of a solid material. All the multimaterial does is display the first material defined in the array.
Heres the code:
var geometry = new THREE.PlaneGeometry( this.model.density.width, this.model.density.height, this.model.density.x, this.model.density.y);
var mat1 = new THREE.MeshBasicMaterial( { color: 0xd02000, transparent: true } )
var blackLines = new THREE.MeshBasicMaterial( { color: 0xffffff, transparent:true, wireframe: true, wireframeLinewidth: 1 } );
var materials = [mat1, blackLines ];
this.plane = THREE.SceneUtils.createMultiMaterialObject( geometry, materials );
In the image below, the red 'ground' is the mesh that is supposed to have the multimaterial, although only one will ever show up (in this case a red MeshBasicMaterial).

Categories