var groundMaterial = new THREE.MeshPhongMaterial( { color: 0xff43fee, specular: 0x360000 ,} );
groundMesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2000, 2000 ), groundMaterial );
groundMesh.rotation.x = - Math.PI / 2;
scene.add( groundMesh );
I want to add grass texture down but not getting any possible solution this code is taken from https://github.com/schteppe/gpu-physics.js this following github repo.
You need to create a Texture and send it as map property in the MechPhongMaterial constructor
Related
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>
I am trying to make a skybox, and every tutorial I have tried will not work. I thought I could make an array and pass it as a param for the material like I saw in an earlier example, but the method has apparently changed to TextureLoader() since then. Below is my code:
// Adds a skybox around the content
var skyBoxMaterials = [
new THREE.MeshBasicMaterial( { map: new THREE.TextureLoader( 'images/skybox/sky1.jpg') }),
new THREE.MeshBasicMaterial( { map: new THREE.TextureLoader( 'images/skybox/sky2.jpg') }),
new THREE.MeshBasicMaterial( { map: new THREE.TextureLoader( 'images/skybox/sky3.jpg') }),
new THREE.MeshBasicMaterial( { map: new THREE.TextureLoader( 'images/skybox/sky4.jpg') }),
new THREE.MeshBasicMaterial( { map: new THREE.TextureLoader( 'images/skybox/sky5.jpg') }),
new THREE.MeshBasicMaterial( { map: new THREE.TextureLoader( 'images/skybox/sky6.jpg') }),
];
var skyBoxGeom = new THREE.CubeGeometry( 10000, 10000, 10000, 1, 1, 1);
skyBox = new THREE.Mesh( skyBoxGeom, skyBoxMaterials );
skyBox.position.set(0, 25.1, 0);
scene.add( skyBox );
When I run it currently, I get the error "Uncaught TypeError: Cannot read property 'x' of undefined" in the console infinitely looping until the server is killed. I could not find the exact answer in the examples, docs, or in another question, here. Any suggestions?
UPDATE: After some more digging, I finally found the example I needed in the docs under cubeGeometry, but it still does not render. My code is below:
// Adds a skybox around the content
var loader = new THREE.CubeTextureLoader();
loader.setPath( 'images/skybox/' );
var textureCube = loader.load( [
'sky1.jpg', 'sky2.jpg',
'sky3.jpg', 'sky4.jpg',
'sky5.jpg', 'sky6.jpg'
] );
var skyMaterials = new THREE.MeshBasicMaterial( { color: 0xffffff, envMap:
textureCube } );
var skyBoxGeom = new THREE.CubeGeometry( 10000, 10000, 10000, 1, 1, 1);
skyBox = new THREE.Mesh( skyBoxGeom, skyMaterials );
skyBox.position.set(0, 25.1, 0);
scene.add( skyBox );
I do not have any error messages in the console, but the cube is not rendering at all. The other objects in the scene render normally.
You can use .background property of THREE.Scene() straight, as it accepts cube textures.
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.set( 0, 0, 300 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var controls = new THREE.OrbitControls( camera, renderer.domElement );
var loader = new THREE.CubeTextureLoader();
loader.setCrossOrigin( "" );
loader.setPath( 'https://threejs.org/examples/textures/cube/skybox/' );
var cubeTexture = loader.load( [
'px.jpg', 'nx.jpg',
'py.jpg', 'ny.jpg',
'pz.jpg', 'nz.jpg'
] );
scene.background = cubeTexture;
render();
function render() {
requestAnimationFrame(render);
renderer.render( scene, camera );
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
Have you downloaded the Three.js Master file? It has all the examples in working order. So all the examples you see on the Examples Page are there along with support files, textures assets etc. This way, you can start your project with a working example and build from there. You will need to run them from your local server (from your post, I gather you already know this).
There are a few examples that may help you like Panorama Cube. In the examples directory of the download, you will find a file called 'webgl_panorama_cube.html' that will be your local copy of this example.
I have a binary STL colored file. I can see the color using the online mesh viewer http://www.viewstl.com/.
I am using the below standard approach to load and visualize the stl file, and it works well. However, the intrisic colors do not appear correctly and are too sensivite to light changes.
Detector.addGetWebGLMessage();
scene = new THREE.Scene();
var aspect = window.innerWidth / window.innerHeight;
var d = 100;
camera = new THREE.OrthographicCamera( - d * aspect, d, d * aspect,- d, 1, 1000 );
camera.position.set( 0, 0, 200 );
camera.lookAt( scene.position );
scene.add( camera );
var light = new THREE.AmbientLight( 0x404040 ); // soft white light
scene.add( light );
var directionalLight = new THREE.DirectionalLight( 0xffffff );
directionalLight.position.x = 0;
directionalLight.position.y = 0;
directionalLight.position.z = 1;
directionalLight.position.normalize();
scene.add( directionalLight );
var loader = new THREE.STLLoader();
var material = new THREE.MeshPhongMaterial( { color: 0xAAAAAA, specular: 0x111111, shininess: 0 } );
// Colored binary STL
var stlfile = "myBinarySTLColoredFile.stl"
loader.load( stlfile, function ( geometry ) {
var meshMaterial = material;
if (geometry.hasColors) {
meshMaterial = new THREE.MeshPhongMaterial({ opacity: geometry.alpha, vertexColors: THREE.VertexColors });
}
mesh = new THREE.Mesh( geometry, meshMaterial );
scene.add(
mesh.position.set(-100, -100, 0);
});
renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true } );
renderer.setSize(....);
var container = document.getElementById('`enter code here`flex2');
Question: How to visualize the color enclosed in the STL file ?
Thanks
I finally succeed to render correctly the colored object.
I use PLYLoader instead of STLLoader.
Apparently, three.js STL api do not manage the color.
There is no right answer. The color will depend on the light.
See the clear thread Realistic lighting (sunlight) with Three.js?
To get the original colors and no directional lighting, remove the directional light and crank the ambient light up to full brightness:
...
scene.add( camera );
var light = new THREE.AmbientLight( 0xFFFFFF ); // Full-bright white light
scene.add( light );
var loader = new THREE.STLLoader();
...
If that doesn't give you the desired result, please add screenshots of the actual and desired visual look to your question.
This is an old question, but for anyone else who comes across it, I don't think the accepted answer about using the PLYLoader instead of the STLLloader is correct, the STLLoader appears to support embedded color in binary STLs just fine in the example.
One possible cause of the OP's issue using THREE.VertexColors in THREE.MeshPhongMaterial({ opacity: geometry.alpha, vertexColors: THREE.VertexColors }) instead of true as in the docs/example.
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/
I'm trying to subtract "holes" in platforms using ThreeCSG. I want the holes to be subtracted in specific locations on the larger platform.
var geometry = new THREE.CubeGeometry( 500, 10, 500 );
var hole_geometry = new THREE.CubeGeometry( 50, 11, 50 );
var material = Physijs.createMaterial( new THREE.MeshLambertMaterial( { color: 0xEEEEEE } ), 0.2, 0.8 );
var hole_material = Physijs.createMaterial( new THREE.MeshLambertMaterial( { color: 0x000000, side: THREE.DoubleSide } ), 0.2, 0.8 );
var platform = { platform: null, hole: null };
// platform
platform.platform = new Physijs.BoxMesh(geometry, material, 0);
platform.platform.position.y = -i*300;
var platformBSP = new ThreeBSP( platform.platform );
// hole
platform.hole = new Physijs.BoxMesh(hole_geometry, hole_material, 0);
platform.hole.position.y = -i*300;
platform.hole.position.x = Math.floor(Math.random()*(251))*(Math.random() < 0.5 ? -1 : 1);
platform.hole.position.z = Math.floor(Math.random()*(251))*(Math.random() < 0.5 ? -1 : 1);
var holeBSP = new ThreeBSP( platform.hole );
platformBSP = platformBSP.subtract(holeBSP);
platform.platform = platformBSP.toMesh(material);
platform.platform.position.y = -i*300;
scene.add( platform_array[i].platform );
scene.add( platform_array[i].hole );
My problem is whenever the hole is converted from Threejs to ThreeCSG is doesn't take the position into account so every hole created in a platform is dead center instead of a random place.
I can't seem to find any documentation on how to reposition the "hole" after it is converted to a ThreeCSG object.
The technique used in the ThreeCSG source is to transform the geometry into a mesh, then to translate the mesh, and then to make a BSP from the translated mesh. See the 2nd line here:
var cube_geometry = new THREE.CubeGeometry( 3, 3, 3 );
var cube_mesh = new THREE.Mesh( cube_geometry );
cube_mesh.position.x = -7;
var cube_bsp = new ThreeBSP( cube_mesh );
var sphere_geometry = new THREE.SphereGeometry( 1.8, 32, 32 );
var sphere_mesh = new THREE.Mesh( sphere_geometry );
sphere_mesh.position.x = -7;
var sphere_bsp = new ThreeBSP( sphere_mesh );
var subtract_bsp = cube_bsp.subtract( sphere_bsp );
var result = subtract_bsp.toMesh( new THREE.MeshLambertMaterial({ shading: THREE.SmoothShading, map: THREE.ImageUtils.loadTexture('texture.png') }) );
result.geometry.computeVertexNormals();
scene.add( result );
In order to set your mesh in the correct place before cutting, you can perform a matrix transform on the geometry itself.
platform.platform = new Physijs.BoxMesh(geometry, material, 0);
platform.platform.geometry.applyMatrix( new THREE.Matrix4().makeTranslation( 0, -i * 300, 0 ) );
It's possible a bug is preventing THREEBSP to use the position attribute (does Physijs mess with this? I have never used it).