Make a Global Scope of a mesh using Three.js - javascript
I am making my first steps coding with JavaScript and playing with Three.js too.
In my code I made this function:
var loader = new THREE.BinaryLoader();
loader.load( "sources/obj/mmlogo/mm_logo.js", function ( geometry ) {
uniforms = {
color: {
type: "c",
value: new THREE.Color(0x000000),
},
envMap: {
type: "t",
value: reflectionCube
},
fresnelBias: {
type: "f",
value: 0.1
},
fresnelScale: {
type: "f",
value: 1.0
},
fresnelPower: {
type: 'f',
value: 2.0
}
};
material = new THREE.ShaderMaterial( {
uniforms : uniforms,
vertexShader : vertexShader,
fragmentShader : fragmentShader,
wireframe: false,
side: THREE.DoubleSide,
});
monogram = new THREE.Mesh( geometry, material );
monogram.scale.set( 1, 1, 1 );
monogram.position.z = -9;
scene.add( monogram );
});
and then I made this render function:
function render() {
frame += 0.1/3;
monogram.scale.z += Math.sin(frame)/600;
TWEEN.update();
targetX = mouseX * .0005;
targetY = mouseY * .0005;
if ( monogram ) {
monogram.rotation.y += 0.05 * ( targetX - monogram.rotation.y );
monogram.rotation.x += 0.05 * ( targetY - monogram.rotation.x );
}
renderer.render( scene, camera );
}
I can see everything and everything works ok. But my console says that there is an error: Uncaught ReferenceError: monogram is not defined.
I think that I have to make a Global Scope of monogram. So I wrote var before monogram and it doesnt work, then I wrote
monogram = new THREE.Mesh( geometry, material );
monogram.scale.set( 1, 1, 1 );
monogram.position.z = -9;
scene.add( monogram );
outside my function and it doesnt work.
Do you have some suggestion? My app works, even if the console says that there is n error, I think that is better if my console says that everything is ok.
Related
How to change Shader color in ThreeJS
I'm new to Three Js and i do not know how to change the color of my material when i press a button on the html page. Do you have any suggestion? I'll attach here the code here is how i declare my material: var color2= new THREE.Color(0xff0000) var customMaterial = new THREE.ShaderMaterial( { uniforms: { p: { type: "f", value: 2 }, glowColor: { type: "c", value: color2 }, }, vertexShader: $('#vertexShader').text, fragmentShader: $('#fragmentShader').text, side: THREE.DoubleSide, blending: THREE.AdditiveBlending, transparent: true, depthWrite: false }); here is how i update my color: function render() { renderer.render(scene, camera); document.getElementById("colore").onclick= function(){ console.log("prova caramella"); var customMaterial = new THREE.ShaderMaterial( { uniforms: { p: { type: "f", value: 2 }, glowColor: { type: "c", value: new THREE.Color(0x00ff00) }, }, vertexShader: $('#vertexShader').text, fragmentShader: $('#fragmentShader').text, side: THREE.DoubleSide, blending: THREE.AdditiveBlending, transparent: true, depthWrite: false }); customMaterial.needsUpdate = true } and lastly this is how i link the material to my 3d model: function petali2(){ var loaderpetali = new THREE.ColladaLoader(); loaderpetali.load('petali3.dae', function (collada) { petali = collada.scene; petali.traverse( function ( child ) { if (child instanceof THREE.Mesh) { console.log(child); child.material = customMaterial; } } ); petali.scale.x = 2; petali.scale.y = 2; petali.scale.z = 2; //flower = dae; scene.add(petali); }); }
When updating the color, it's sufficient to do this: customMaterial.uniforms.glowColor.value.set( 0x00ff00 ); There is no need to create a new material. Besides, when using a latest version of three.js, it's not necessary to define the type for a uniform. The type is automatically derived from the compiled shader. On app level, it's sufficient to do. uniforms: { p: { value: 2 }, glowColor: { value: new THREE.Color(0x00ff00) }, },
THREE.js, I don't know why not rendering obj files
I'm making obj loader in react view button clicked, I want to see obj file in modal component.This object loader component get url to modal component. console.log is correct.This loader is get url other component. Group {uuid: "0C86CC1D-E795-4191-A62A-72DF4A433CEB", name: "", type: "Group", parent: null, children: Array(8), …} castShadow: falsechildren: (8) [Mesh, Mesh, Mesh, Mesh, Mesh, Mesh, Mesh, Mesh]frustumCulled: truelayers: Layers {mask: 1}materialLibraries: ["patient.mtl"]matrix: Matrix4 {elements: Array(16)}matrixAutoUpdate: truematrixWorld: Matrix4 {elements: Array(16)}matrixWorldNeedsUpdate: falsename: ""parent: Scene {uuid: "873E8718-F1B0-47B5-AC77-DC1B334B3637", name: "", type: "Scene", parent: null, children: Array(5), …}position: Vector3 {x: 0, y: 0, z: 0}quaternion: Quaternion {_x: 0, _y: 0, _z: 0, _w: 1, _onChangeCallback: ƒ}receiveShadow: falserenderOrder: 0rotation: Euler {_x: 0, _y: 0, _z: 0, _order: "XYZ", _onChangeCallback: ƒ}scale: Vector3 {x: 0.07, y: 0.07, z: 0.07}type: "Group"up: Vector3 {x: 0, y: 1, z: 0}userData: {}uuid: "0C86CC1D-E795-4191-A62A-72DF4A433CEB"visible: trueeulerOrder: (...)id: 18modelViewMatrix: Matrix4 {elements: Array(16)}normalMatrix: Matrix3 {elements: Array(9)} useQuaternion: (...)proto: Object3D (8) [Mesh, Mesh, Mesh, Mesh, Mesh, Mesh, Mesh, Mesh] Scene {uuid: "873E8718-F1B0-47B5-AC77-DC1B334B3637", name: "", type: "Scene", parent: null, children: Array(5), …} CODE import React, { Component } from "react"; import * as THREE from "three"; import OBJLoader from "three-obj-loader"; import OrbitControls from "three-orbitcontrols"; OBJLoader(THREE); let scene; class ObjectLoader extends Component { componentDidMount() { const width = this.mount.clientWidth; const height = this.mount.clientHeight; scene = new THREE.Scene(); this.camera = new THREE.PerspectiveCamera(75, width / height, 1, 2000); this.camera.position.z = 250; this.renderer = new THREE.WebGLRenderer({ antialias: true }); this.renderer.setClearColor("#263238"); this.renderer.setSize(width, height); this.mount.appendChild(this.renderer.domElement); const geometry = new THREE.BoxGeometry(5, 5, 5); const material = new THREE.MeshBasicMaterial({ color: "#0F0", wireframe: true }); this.cube = new THREE.Mesh(geometry, material); scene.add(this.cube); const controls = new OrbitControls(this.camera, this.renderer.domElement); //LIGHTS var lights = []; lights[0] = new THREE.PointLight(0x304ffe, 1, 0); lights[1] = new THREE.PointLight(0xffffff, 1, 0); lights[2] = new THREE.PointLight(0xffffff, 1, 0); lights[0].position.set(0, 200, 0); lights[1].position.set(100, 200, 100); lights[2].position.set(-100, -200, -100); scene.add(lights[0]); scene.add(lights[1]); scene.add(lights[2]); // load Object loadObj(this.props.url); } componentWillUnmount() { this.stop(); this.mount.removeChild(this.renderer.domElement); } start = () => { if (!this.frameId) { this.frameId = requestAnimationFrame(this.animate); } }; stop = () => { cancelAnimationFrame(this.frameId); }; animate = () => { this.renderScene(); this.frameId = window.requestAnimationFrame(this.animate); }; renderScene = () => { if (this.renderer) this.renderer.render(scene, this.camera); }; onLoad = () => { this.renderScene(); //start animation this.start(); }; onProgress = xhr => { console.log((xhr.loaded / xhr.total) * 100 + "% loaded"); }; // Function called when download errors onError = error => { console.log("An error happened" + error); }; render() { return ( <div style={{ width: "500px", height: "500px" }} ref={mount => { this.mount = mount; }} /> ); } } function loadObj(url) { const objLoader = new THREE.OBJLoader(); objLoader.load( url, function(object) { console.log(object, object.children); let mesh = object; scene.add(object); console.log(scene); mesh.position.set(0, 0, 0); mesh.scale.set(0.07, 0.07, 0.07); }, function(xhr) { console.log((xhr.loaded / xhr.total) * 100 + "% loaded"); }, // called when loading has errors function(error) { console.log("An error happened" + error); }); } export default ObjectLoader;
How can I create a custom THREE.MeshStandardMaterial?
I'm looking to create a material with three.js identical to MeshStandardMaterial. I want to do this because I need all of its features except with small changes to the GLSL code. I attempted to recreate MeshStandardMaterial using ShaderMaterial. WAFFLE.StandardMaterial = function( parameters ) { parameters.uniforms = THREE.UniformsUtils.merge( [ THREE.UniformsLib.common, THREE.UniformsLib.aomap, THREE.UniformsLib.lightmap, THREE.UniformsLib.emissivemap, THREE.UniformsLib.bumpmap, THREE.UniformsLib.normalmap, THREE.UniformsLib.displacementmap, THREE.UniformsLib.roughnessmap, THREE.UniformsLib.metalnessmap, THREE.UniformsLib.fog, THREE.UniformsLib.lights, { emissive: { value: new THREE.Color( 0x000000 ) }, roughness: { value: 0.5 }, metalness: { value: 0 }, envMapIntensity: { value: 1 } // temporary } ] ); parameters.vertexShader = THREE.ShaderChunk.meshphysical_vert; parameters.fragmentShader = THREE.ShaderChunk.meshphysical_frag; THREE.ShaderMaterial.call( this, parameters ); } WAFFLE.StandardMaterial.prototype = Object.create( THREE.ShaderMaterial.prototype ); WAFFLE.StandardMaterial.prototype.constructor = WAFFLE.StandardMaterial; I haven't been successful thus far. How can I recreate MeshStandardMaterial?
How Repeat ThreeJS Matcap use fragmentShader Texture
here is vertex and fragmentshader material : material = new THREE.ShaderMaterial( { uniforms: { textureMap: { type: 't', value: THREE.ImageUtils.loadTexture( 'img/matcap/green.jpg' ) }, normalMap: { type: 't', value: THREE.ImageUtils.loadTexture( 'img/normalmap/stamp.jpg' ) }, normalScale: { type: 'f', value: 0.5 }, texScale: { type: 'f', value: 5 }, useSSS: { type: 'f', value: 10 }, useScreen: { type: 'f', value: 0 }, color: { type: 'c', value: new THREE.Color( 0, 0, 0 ) } }, vertexShader: document.getElementById( 'vertexShader' ).textContent, fragmentShader: document.getElementById( 'fragmentShader' ).textContent, side: THREE.DoubleSide } ); I want repeat texture use like this material.uniforms.textureMap.value.wrapS = material.uniforms.textureMap.value.wrapT = THREE.ClampToEdgeWrapping; material.uniforms.normalMap.value.wrapS = material.uniforms.normalMap.value.wrapT = THREE.RepeatWrapping; material.uniforms.normalMap.value.repeat.set( 20, 20 ); but not work in three.js why? how fix it thanks all friends!
By default the texture are Clamp To Edge means no wrapping to zero. Your main texture is Clamp TO Edge repeat and normal texture is Repeat Wrapping probably you normal map texture quality is not so bright to make a difference try to revert the thing or texture ( means make some bright normal map texture or dull texture map any). your approach is correct it seems. One more thing which you can do to increase readability: var textureMap = THREE.ImageUtils.loadTexture( 'img/matcap/green.jpg' ); var normalMap = THREE.ImageUtils.loadTexture( 'img/normalmap/stamp.jpg' ) textureMap.repeat.set(20,20); normalMap.repeat.set(10,10); //then shader code
Three.js - include mesh data in code
I have this Three.js code with JSON loader loading mesh from file /models/mountain.json: var Three = new function () { this.scene = new THREE.Scene() this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000) this.camera.position.set(20, 52, 20); this.camera.rotation.order = 'YXZ'; this.camera.rotation.y = -Math.PI / 4; this.camera.rotation.x = Math.atan(-1 / Math.sqrt(2)); this.camera.scale.addScalar(1); this.renderer = new THREE.WebGLRenderer() this.renderer.setSize(window.innerWidth, window.innerHeight); var ground = new THREE.Mesh( new THREE.PlaneBufferGeometry(436, 624), new THREE.MeshLambertMaterial({color: '#808080'})); ground.rotation.x = -Math.PI / 2; //-90 degrees around the x axis this.scene.add(ground); var light = new THREE.PointLight(0xFFFFDD); light.position.set(-1000, 1000, 1000); this.scene.add(light); var loader = new THREE.JSONLoader(); this.loadMountain = function (x, y) { loader.load('/models/mountain.json', Three.getGeomHandler('#808080', x, y, 1)) } this.loadFields = function () { for (var i=0;i<4000;i++) { Three.loadMountain(x, y) } } this.getGeomHandler = function (color, x, y, scale) { return function (geometry) { var mesh = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({color: color})); mesh.scale.set(scale, scale, scale); mesh.position.set(x, 0, y); Three.scene.add(mesh); }; } this.init = function () { $('body').append(Three.renderer.domElement); Three.loadFields() Three.render(); } this.render = function () { requestAnimationFrame(Three.render); Three.renderer.render(Three.scene, Three.camera); }; } $(document).ready(function () { Three.init(); }); and this is /models/mountain.json content: { "metadata": { "formatVersion" : 3.1, "generatedBy" : "Blender 2.7 Exporter", "vertices" : 39, "faces" : 62, "normals" : 36, "colors" : 0, "uvs" : [], "materials" : 1, "morphTargets" : 0, "bones" : 0 }, "scale" : 1.000000, "vertices" : [2.47941e-07,-1.13504e-07,-2.59668,-2.41031,-6.2081e-08,-1.42025,-2.2107,4.55942e-08,1.04307,2.16045,1.84802,0.183901,-0.427399,1.11956e-07,2.56126,1.23588,9.98242e-08,2.28371,2.50387,4.55942e-08,1.04307,2.58781,9.37308e-09,0.214431,2.17385,-0.0483214,-1.42025,1.40026,-0.0483214,-1.74566,1.50645e-07,2.13114,-1.9421,-0.6306,2.13114,-1.52968,-1.04238,2.48498,-1.06715,-1.23632,3,-0.856474,-1.5574,2.62306,-0.476759,-1.68478,2.74775,0.160378,-1.20001,3,0.780135,-1.14654,3,1.41015,-0.31966,3,1.91562,0.31966,2.48498,1.46763,0.92434,3,1.70803,0.754272,2.73835,0.751422,1.90443,2.61032,0.780134,1.52632,2.76301,0.160377,1.78144,2.69402,-0.47676,1.9564,3,-1.06223,0.807846,2.13114,-1.68984,1.32727,3.09213,-1.10549,1.13568,1.38919,-1.21096,1.98255,0.969716,-1.07503,0.529022,2.81989,0.43993,0.969891,3.32801,-1.43745,-0.39848,2.2361,-1.12285,-1.00579,1.31316,2.27174,-0.789081,1.31316,2.34614,0.888122,0.684588,2.17543,0.568656,2.07869,1.615,2.13863,1.49103,1.32889,2.52981,0.924307,0.978923], "faces" : [34,0,11,10,0,0,1,2,34,1,13,12,0,3,4,5,34,0,12,11,0,0,5,1,34,0,1,12,0,0,3,5,34,38,3,37,0,6,7,8,34,9,31,28,0,9,10,11,34,0,10,26,0,0,2,12,34,9,26,31,0,9,12,10,34,9,0,26,0,9,0,12,35,18,17,33,34,0,13,14,15,16,35,37,3,23,22,0,8,7,17,18,34,29,27,25,0,19,20,21,34,28,31,27,0,11,10,20,34,29,28,27,0,19,11,20,34,12,19,20,0,5,22,23,34,5,6,20,0,24,25,23,34,6,38,37,0,25,6,8,34,37,22,21,0,8,18,26,34,30,27,31,0,26,20,10,34,6,37,20,0,25,8,23,34,30,31,32,0,26,10,27,34,37,21,20,0,8,26,23,34,30,32,26,0,26,27,12,34,21,30,20,0,26,26,23,34,11,12,20,0,1,5,23,34,26,10,11,0,12,2,1,34,30,11,20,0,26,1,23,34,30,26,11,0,26,12,1,34,20,35,5,0,23,28,24,34,20,19,36,0,23,22,28,34,20,36,35,0,23,28,28,35,6,7,3,38,0,25,29,7,6,34,7,23,3,0,29,17,7,34,29,25,24,0,19,21,30,34,7,24,23,0,29,30,17,34,7,8,29,0,29,31,19,34,7,29,24,0,29,19,30,34,18,36,19,0,13,28,22,34,4,5,35,0,32,24,28,34,18,35,36,0,13,28,28,34,18,34,4,0,13,16,32,34,18,4,35,0,13,32,28,35,13,14,15,16,0,4,33,33,34,34,30,25,27,0,26,21,20,34,23,24,25,0,17,30,21,34,21,22,23,0,26,18,17,34,30,21,25,0,26,26,21,34,21,23,25,0,26,17,21,35,8,9,28,29,0,31,9,11,19,34,26,32,31,0,12,27,10,34,2,16,15,0,35,34,33,34,14,13,1,0,33,4,3,34,14,2,15,0,33,35,33,34,14,1,2,0,33,3,35,34,2,17,16,0,35,14,34,34,4,34,33,0,32,16,15,34,2,33,17,0,35,15,14,34,2,4,33,0,35,32,15,34,16,12,13,0,34,5,4,34,18,19,12,0,13,22,5,34,16,17,18,0,34,14,13,34,16,18,12,0,34,13,5], "uvs" : [], "normals" : [0.094028,0.298624,-0.949705,-0.162755,0.939238,-0.302133,0.228248,0.832942,-0.504044,-0.822016,0.351848,-0.447707,-0.253456,0.911466,-0.323923,-0.004059,0.913785,-0.40614,0.788598,0.576983,0.21247,0.952086,0.29432,-0.082797,0.625996,0.719138,0.301553,0.474441,0.29017,-0.83105,0.255501,0.796655,-0.547746,0.441328,0.166265,-0.881802,0.221656,0.483047,-0.847041,0.192999,0.761406,0.618824,-0.352977,0.778008,0.5197,-0.653584,0.252663,0.713401,-0.29136,0.293313,0.91052,0.688314,0.722556,0.063967,0.612629,0.761834,0.210364,0.718711,0.280313,-0.63625,0.370495,0.893033,-0.255287,0.629627,0.578692,-0.518326,0.229896,0.680258,0.695944,-0.064241,0.589251,0.805353,0.205145,0.606586,0.768059,0.734519,0.631458,0.24839,0.211341,0.910367,0.355693,-0.135533,0.925748,-0.352916,-0.03061,0.231269,0.972381,0.975982,0.184362,-0.11594,0.694266,0.717338,0.058412,0.712027,0.350871,-0.608173,-0.201483,0.259865,0.944365,-0.820185,0.572069,-0.001556,-0.322733,0.944334,0.063509,-0.922117,0.223151,0.315958], "skinIndices" : [], "skinWeights" : [], "morphTargets" : [], "bones" : [], "animations" : [], "colors" : [], "materials" : [ { "DbgColor": 15658734, "DbgIndex": 0, "DbgName": "default", "vertexColors": false } ] } Is it possible to use this content in code as a variable and add it to scane?
Here is the pattern to follow if you want to load a model by parsing a JSON data structure. Modify your mountain.json file and give your data structure a name. var mountain = { "metadata": { "formatVersion" : 3.1, "generatedBy" : "Blender 2.7 Exporter", ... etc ... } Include the following code in your source: <script src="mountain.js"></script> Now you can load your model like so: var loader = new THREE.JSONLoader(); var model = loader.parse( mountain ); mesh = new THREE.Mesh( model.geometry, model.materials[ 0 ] ); scene.add( mesh ); three.js r.70