THREEJS - OBJMTLLoader and Bump Map - three.js

I'm loading an OBJ with an MTL which references a diffuse map and a bump. The map_Kd (diffuse map) is reading and loading in the renderer, but the map_Bump (bump map) is not. When I log the material to the console, the bumpmap property is null. Does OBJ MTL Loader work with bump maps?

I looked into MTLLoader.js and found that bump maps are not added from the mtl file. I think I've fixed this:
In the file, there's a section for diffuse maps:
case 'map_kd':
// Diffuse texture map
params[ 'map' ] = this.loadTexture( this.baseUrl + value );
params[ 'map' ].wrapS = this.wrap;
params[ 'map' ].wrapT = this.wrap;
break;
Immediately after that, I added this:
case 'map_bump':
// Diffuse bump map
params[ 'bumpMap' ] = this.loadTexture( this.baseUrl + value );
params[ 'bumpMap' ].wrapS = this.wrap;
params[ 'bumpMap' ].wrapT = this.wrap;
break;
This is working for my example. If any developers see pitfalls with this modification, please let me know. Thanks.

Related

How can i render the PMREM environment map when copying MeshStandardMaterial into a ShaderMaterial

I am trying to build the MeshStandardMaterial by using a ShaderMaterial. I'm keeping most of the #include <logic> statements, which makes it slightly difficult to put breakpoints.
I'd like to know if there is a straightforward way to render the PMREM cubemap, in this particular material template and have it show up the way it's supposed to.
I'm roughly using:
material.defines.USE_ENVMAP = ''
material.defines.ENVMAP_MODE_REFLECTION = ''
material.defines.ENVMAP_TYPE_CUBE_UV = ''
material.defines.ENVMAP_BLENDING_MULTIPLY = ''
material.defines.TEXTURE_LOD_EXT = ''
material.defines.USE_UV = ''
material.extensions.derivatives = true
material.extensions.shaderTextureLOD = true
Which,as far as i can tell, are all of the defines that appear when adding a texture to material.envmap. The shader compiles, the PMREM texture is being generated, and can be read in the shader (gl_FragColor = vec4( texture2D( envmap, vUv ).xyz, 1.) works for example). These are the uniforms i cloned:
{
envmap: UniformsUtils.clone(UniformsLib.envmap),
fog: UniformsUtils.clone(UniformsLib.fog),
lights: UniformsUtils.clone(UniformsLib.lights),
displacementmap: UniformsUtils.clone(UniformsLib.displacementmap)
}
The maxMipmap uniform seems to have a value of 0 when MeshStandardMaterial is used, i'm not sure what else is being used.
I get absolutely no effect from placing a texture in material.uniforms.envmap.value and using these defines. If i turn off the light in the scene, my object renders as black, no reflections.
This doesn't seem like it requires that many inputs but i get 0. out of it:
radiance += getLightProbeIndirectRadiance( /*specularLightProbe,*/ geometry.viewDir, geometry.normal, material.specularRoughness, maxMipLevel );
For my case it was a missing uniform:
https://github.com/mrdoob/three.js/blob/dev/src/renderers/shaders/ShaderLib.js#L99
envMapIntensity: { value: 1 } // temporary
It's not part of the envmap.

Custom UVgenerator Three.js for extrudedgeometry

I want to use a texture on the surface of my extruded geometry. I have been researching custom UVgenerators for a while now, and have found these related questions:
1.) How to apply a texture to THREE.ExtrudeGeometry?
2.) Loaded texture appears blurred, or like a single color. How to make the texture crisp and sharp
However, the method proposed to divide my geometry points by 1000 and to mesh.scale.set(1000,1000,1) doesn't work because my geometry is no longer in the correct place. I would prefer to specify the UV Mapping. One answer says to implement a custom uvgenerator based on the source code, but I am stuck & can't figure out what to do.
This is my geometry creation, the material is 512x512px, how can I map a texture onto the top?:
pointList=[[0,0,0],
[0,1000,0],
[750,1000,0],
[750,750,0],
[1000,750,0],
[1000,0,0]]
for (i=0;i < pointList.length; i++) {
point = pointList[i];
x = point[0];
y = point[1];
myPoints.push( new THREE.Vector2 (x,y) );
}
myShape = new THREE.Shape( myPoints );
extrusionSettings = {
amount:height
};
myGeometry = new THREE.ExtrudeGeometry( myShape, extrusionSettings );
resultshape = new THREE.Mesh( myGeometry, material );
You can specify custom UVs for your ExtrudeGeometry by specifying your own UVGenerator, one of the properties of extrusionSettings.
To specify your custom UV generator, you can use as a template THREE.ExtrudeGeometry.WorldUVGenerator, which can be found in src/extras/geometries/ExtrudeGeometry.js.
There is a simpler solution that may work for you, however.
Instead of a custom UV generator, you can take advantage of the offset and repeat properties of your texture. Use the following pattern:
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set( 1 / 500, 1 / 500 );
texture.offset.set( 0.1, 0.5 );
three.js r.68

Three.js specific render-time uniforms

I want to implement per-object motion-blur effect based on calculating previous pixel position inside shaders.
This technic's first step is to build velocity map of moving objects. This step requirements is to have as uniform variables projection and model view matrices of current frame and the same matrices of previous frame.
How could I include those matrices to uniforms for some special shader? I supposed to have solution in some way like:
uniforms = {
some_uniform_var : {type: "m4", value: initialMatrix, getter: function(){
// `this` points to object
return this.worldMatrix
}}
}
But now in THREE.js this is not available. We could make some sort of monkey patching, but I cannot find best way to do it.
Any suggestions?
The current solvation to this problems consist of several parts. I'm using EffectComposer to make several passes of rendered scene, one of then - VelocityPass. It takes current and previous model-view matrix and projection matrix and produces two positions. Both of them then used to calculate speed of a point.
Shader looks like this
"void main() {",
"vec2 a = (pos.xy / pos.w) * 0.5 + 0.5;",
"vec2 b = (prevPos.xy / prevPos.w) * 0.5 + 0.5;",
"vec2 oVelocity = a - b;",
"gl_FragColor = vec4(oVelocity, 0.0, 1.);",
"}"
There're several issues of this decision.
Three.js has certain point where it injects matrices to object-related shaders. The very ending of SetProgram closure, which lives in WebGLRenderer. That's why I took the whole renderer file, renamed renderer to THREE.MySuperDuperWebGLRenderer and added couple lines of code in it:
A closure to access closures, defined in userspace:
function materialPerObjectSetup(material, object){
if( material.customUniformUpdate ){
material.customUniformUpdate( object, material, _gl ); // Yes, I had to pass it...
}
}
And calling of it in renderBuffer and renderBufferDirect;
var program = setProgram( camera, lights, fog, material, object );
materialPerObjectSetup(material, object);
Now - the userspace part:
velocityMat = new THREE.ShaderMaterial( THREE.VelocityShader );
velocityMat.customUniformUpdate = function(obj, mat, _gl){
// console.log("gotcha");
var new_m = obj.matrixWorld;
var p_uniforms = mat.program.uniforms;
var mvMatrix = camera.matrixWorldInverse.clone().multiplyMatrices(camera.matrixWorldInverse, obj._oldMatrix );
_gl.uniformMatrix4fv( p_uniforms.prevModelViewMatrix, false, mvMatrix.elements );
_gl.uniformMatrix4fv( p_uniforms.prevProjectionMatrix, false, camera.projectionMatrix.elements );
obj._pass_complete = true; // Необходимо сохранять состояние старой матрицы пока не отрисуется этот пасс.
// А то матрицы обновляются каждый рендеринг сцены.
}
_pass_complete needed when we rerendering scene several times - each time matrix recalculated. This trick help us save previous matrix untill we use it.
_gl.uniformMatrix4fv is needed, because three.js serves universes one time before rendering. No matter how much objects we have - other method will pass to the shader modelViewMatrix of the last one. This happens because I want to draw this scene fully using VelocityShader. There's no other way to say to Renderer to use some alternative material for objects.
And as final point of this explaination I putting here a trick to manage previous matrix of an object:
THREE.Mesh.prototype._updateMatrixWorld = rotatedObject.updateMatrixWorld;
THREE.Mesh.prototype._pass_complete = true;
Object.defineProperty(THREE.Mesh.prototype, "updateMatrixWorld", {get: function(){
if(this._pass_complete){
this._oldMatrix = this.matrixWorld.clone();
this._pass_complete = false;
}
this._updateMatrixWorld();
return (function(){
});
}})
I believe, that there's could be a nicer solution. But sometimes I need to act in rush. And such kind of monkey things could happen.

Three.Js Bump maps and UV Layout

js Peeps
I have an OBJ model with a UV map that is not rendering the bump map correctly.
As you can see from the images the UV map checker texture shows a smooth flat surface. Unfortunately when the bump map is applied there appears to be tears across the bump map texture. (It is just a basic repeating texture which works fine for a different OBJ)
Has anyone else experienced this effect?
Many Thanks
![1]: http://imgur.com/pLBxWtk "Rendered bump map"
![2]: http://imgur.com/MDfHxiu "UV Map test"
Here is the bump coffeescropt map code:
#BumpMap
mapHeight = THREE.ImageUtils.loadTexture( "/images/3d/bump.jpg" )
mapHeight.anisotropy = 4
mapHeight.repeat.set( 0.998, 0.998 )
mapHeight.offset.set( 0.001, 0.001 )
mapHeight.wrapS = mapHeight.wrapT = THREE.RepeatWrapping
mapHeight.format = THREE.RGBFormat
It has to do with a UV map being recalculated after a boolean operation

Physijs Load model three.js collisions don't work

When I load my model(map) with JSONLoader I have a problem with collisions.
If I load with BoxMesh it's work but the geometry collisions is like a cube, and my model is not a cube, the middle of my model is empty.
And I put an other object (cube) on the top of my map the object stop on the top of this map not inside.
After search, I have load my model with Convex, and the object ont the top , fall on the plane of my map but I think the size (40) is not load correctly because if I move the object very little he fall in the space.
I load my model like this:
var loader = new THREE.JSONLoader();
loader.load( "essai/lobby3.js", function( lobby_geometry, lobby_materials ) {
console.log(lobby_geometry);
var ground_material = Physijs.createMaterial(
new THREE.MeshFaceMaterial(lobby_materials),
.8, // high friction
0 // low restitution
);
mesh = new Physijs.Mesh ( //I try with BoxMesh / Convex / Concav
lobby_geometry,
ground_material,
0
);
mesh.scale.set(40,40,40);
scene.add(mesh);
});
I don't know if it's very easy to understand the problem.
BoxMesh: Here the object is stop.
Convex: Don't detect collisions
I upload my tests, I think maybe is better to undestand :
http://www.hebergeurfichier.com/download/a97e3ae31c36dfe98525213cde90165f.html
PS: I create my models with blender and export in three.js extension.

Resources