mrdoob / three.js

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

displacementMap does not update normals #19677

Open MHebes opened 4 years ago

MHebes commented 4 years ago
Description of the problem

Adding a displacementMap to a MeshPhongMaterial without flatShading will offset the vertices correctly but will not correctly change the normals. The result is an object that has the right shape, but the wrong lighting.

Fiddle demonstrating the problem (be sure to minimize that getimage() base64 method, I couldn't get images to work on fiddle).

Three.js version

r117

Browser

Chrome and Edge at least

OS

Windows at least

mrdoob commented 4 years ago

One workaround is to combine it with material.bumpMap but the result is ugly...

But you raise a good point. The renderer currently "computes" the normals when using flatShading so it's fair to expect a similar behaviour when not using flatShading...

WestLangley commented 4 years ago

so it's fair to expect a similar behaviour

I do not think so. I do not think it is even possible in general.

It is fair to expect the user to specify a baked normal map along with the displacement map. See https://threejs.org/examples/webgl_materials_displacementmap.html.

//

If the original geometry is planar, and the displacement is computed analytically in the vertex shader as a function of position, the vertex normal can also be computed or estimated in the vertex shader.

That may be a workaround for the OP.

mrdoob commented 4 years ago

If the original geometry is planar, and the displacement is computed analytically in the vertex shader as a function of position, the vertex normal can also be computed or estimated in the vertex shader.

That may be a workaround for the OP.

Yes, that's what I was thinking.

looeee commented 4 years ago

It is fair to expect the user to specify a baked normal map along with the displacement map.

It would be helpful to document this.

Mugen87 commented 4 years ago

Not sure about that. It was discussed several times that the documentation should not have a tutorial-like character.

If a user decides to use a displacement map, one can assume that the user has a certain knowledge about this type of texture. For example that it makes sense to use it with an appropriate normal map. Tools like GPU MeshMapper or ShaderMap let you generate both type of textures in one workflow.

looeee commented 4 years ago

It was discussed several times that the documentation should not have a tutorial-like character.

The purpose of the documentation should be to inform and reduce frustration, especially for beginners. This would be a single sentence like "Normals are not displaced when using a displacement map so it's often used alongside a normal map or bumpmap". There are many similar notes like this in the docs. Even if you don't care about the users, these are likely to save dev time by preventing issues like this being opened, or similar help requests being made on the forum.

one can assume that the user has a certain knowledge

I don't think we should make assumptions that only experts use this library.

Mugen87 commented 4 years ago

The purpose of the documentation should be to inform and reduce frustration, especially for beginners.

In other issues or PRs, it was stated that the documentation should just document the API. The discussed information about displacement maps belong to the manual, imo