mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
102.64k stars 35.37k forks source link

normalmap nor appearing on other meshes #605

Closed bingomanatee closed 12 years ago

bingomanatee commented 13 years ago

in the webgl_materials_normalmap.html demo I changed createScene to:

function createScene(geometry, scale, material1, material2) {

    geometry.computeTangents();

    mesh1 = new THREE.Mesh(geometry, material1);
    mesh1.position.x = - scale * 12;
    mesh1.scale.x = mesh1.scale.y = mesh1.scale.z = scale;
    scene.addObject(mesh1);

    mesh2 = new THREE.Mesh(geometry, material2);
    mesh2.position.x = scale * 12;
    mesh2.scale.x = mesh2.scale.y = mesh2.scale.z = scale;
    scene.addObject(mesh2);

    var sphere = new THREE.SphereGeometry(100, 16, 8);
    var sph = new THREE.Mesh(sphere, material1);
    sph.position.x = 0;

    scene.addObject(sph);

    var pp = new THREE.PlaneGeometry(500, 500, 10, 10);
    mesh3 = new THREE.Mesh(pp, material1);
    mesh3.position.y = -200;
    scene.addObject(mesh3);

    var sphere2 = new THREE.SphereGeometry(90, 16, 8);
    var sph2 = new THREE.Mesh(sphere, material2);
    sph2.position.y = -10;
   // sph2.rotation.x = Math.PI;

    scene.addObject(sph2);

    loader.statusDomElement.style.display = "none";

}

and the sphere and plane with material2 do not appear. Are there structural requirements for normal maps/displacement to work or not work?

alteredq commented 13 years ago

All geometries must have explicitly computed tangents.

If I remember well, PlaneGeometry used to have some troubles with tangents. For some reason plane exported from Blender worked, but procedurally generated plane didn't. SphereGeometry should work.

oosmoxiecode commented 13 years ago

I messed with the normal-map stuff from that example recently. I tried making a ground and got it to work with a PlaneGeometry, think i just ran computeTangents on it.

Although I ran into a bunch of other stuff. Like some problem when using fog, got some default white fog very close. Also the texture.repeat and texture.offset didn´t work, had to mess with the uvs to get it to repeat. Also shadowMap didn´t affect it. Guess it´s not meant for everyday use :) Would be nice though.

alteredq commented 13 years ago

Yup, normal map shader is special, it doesn't have all the features from standard materials.

Fog should work though, if you set fog: true in ShaderMaterial constructor parameters.

I'll need to check if I can add some more features, there is less maneuvering space in normal map shader, parameters from max limits are being consumed by normal mapping.

bingomanatee commented 13 years ago

PlaneGeometry does have a computeFaceNormals() method -- is this different than computeTangents()?

alteredq commented 13 years ago

Yes, tangents are perpendicular to normals.

http://en.wikipedia.org/wiki/Tangent

bingomanatee commented 13 years ago

alright - so I guess to get PlaneGeometry to work I have to figure out my own computeTangents. :D thanks.

alteredq commented 13 years ago

Well, @oosmoxiecode reported that he got it working just with generic geometry.computeTangents() so it may be worth trying this first.

oosmoxiecode commented 13 years ago

@bingomanatee Yes, checked my testfile now, you should be able to some thing like:

var plane = new THREE.PlaneGeometry( 1000, 1000 );
plane.computeVertexNormals();
plane.computeTangents();

See if it helps!

@alteredq Ah, didn´t have fog:true, that explains that, thanks! :) You mean you run into the maxparams limits? That´s a shame..

alteredq commented 13 years ago

@alteredq Ah, didn´t have fog:true, that explains that, thanks! :) You mean you run into the maxparams limits? That´s a shame..

Yes, already now I think you can have just 2 point lights instead of 4 for regular Phong (on ANGLE).

jbaicoianu commented 13 years ago

I've been experimenting with reimplementing the normal shader using the ShaderChunk system in my own branch, since the one in ShaderLib wasn't being affected by the shadow map (or is that just a parameter I need to pass in, similar to fog: true?)

I was planning on submitting a pull request for this change but wasn't aware of the limitations when running within ANGLE. Are the parameter limits reason enough to keep the normal shader as its own special-case texture type, or does the ShaderChunk system alleviate the problem due to the fact that unused features are disabled by the various #ifdef blocks?

I've also fixed a problem with the blender export script incorrectly marking normal maps as lightmaps in the .js file, if that hasn't already been patched in the dev branch I can submit that as well.

alteredq commented 13 years ago

Hmmm, normal map shader uses 5 varyings (plus one for each point light), also there is a chance fog uses extra one "behind the scene" by ANGLE (to emulate gl_FragCoord).

We have 10 available varying in ANGLE, so it should give us 4 minus number of point lights varyings to use for something else.

Shadow maps are one varying per light, vertex colors and reflection/refraction are one varying each.

So I guess it should be possible to beef up a bit normal map shader (2 lights + 1 shadow + reflection would be nice).

I'll need to experiment, I remember before it was barfing just on 3 lights, while it seems now it should work with up to 4.

alteredq commented 13 years ago

There is something really weird going on with normal map shader on Chrome ANGLE - it doesn't work with 2 of each type of lights (directional / point separately), but it works with 1,3,4 lights.

If you don't use normal-map derived normal, exactly the same code works fine (with vertex normals).

If it didn't work with more lights, I would suspect it's shader code complexity thing / running out of parameters.

If it didn't work with vertex normals, it could have been some uniforms problem.

On Chrome OpenGL and Firefox ANGLE everything works as expected.

I'm puzzled.

bingomanatee commented 13 years ago

Does anyone know what the implications of the bias/scale are for the displacement map?

alteredq commented 13 years ago

So, ignoring 2 lights weirdness, I've got shadow maps and texture offset / repeat working.

With reflections though I hit another problem - on OpenGL it somehow works (not sure about correctness, but looks acceptable), on ANGLE whole shader just silently fails (like with 2 lights, no errors, just zero output to the screen, this time also in Firefox).

Does anyone know what the implications of the bias/scale are for the displacement map?

https://github.com/mrdoob/three.js/blob/master/src/extras/ShaderUtils.js#L366

Scale makes displacement magnitude larger / smaller, bias shifts it up / down.

bingomanatee commented 13 years ago

right - so is displacement by default always outward? if I'm reading the code it looks like it is - so for instance if I wanted displacement to range from 0 ... 512 pixels I'd have scale 2, bias 0?

alteredq commented 13 years ago

Displacement is in the direction of surface normal. Texture colors are from 0 to 1, so you need to set scale to 512 if you want to displacement from 0 .. 512 units.

alteredq commented 13 years ago

Turns out I made a mess with texture units. Reflections now work:

https://github.com/alteredq/three.js/commit/84ed1835ca434725e27a0b8855bbc1fc8b4017d9

oosmoxiecode commented 13 years ago

@alteredq I been playing around with this normal map shader a little now. It´s really fun :) Thanks for this! :)

I tried combining it with your noise examples to make something that should look like a water-surface. Something like this: http://oos.moxiecode.com/js_webgl/water_noise/index.html

However I ran into some issue with the cubeMap reflection, you can see it if you look down. Or here´s an example that illustrates it better: http://oos.moxiecode.com/js_webgl/water_noise/index_normal.html

Compared with a regular phong-material: http://oos.moxiecode.com/js_webgl/water_noise/index_phong.html

Any idea what´s going on there? I checked the "webgl_materials_normalmap.html"-example and there the cubeMap reflection looks right. So it´s totally possible that I´ve messed something else while poking around here. Using a r46dev-build from a couple of nights ago btw.

alteredq commented 13 years ago

Probably normal map shader is not correct.

Regular Phong material does reflection in world space coordinate system (in vertex shader) ; for normal map shader I just fudged reflection with whatever was already available in its fragment shader.

To do it right we would need somehow transform view vector and normal-mapped normal in fragment shader to world space.