Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for MTL map_Ns (shininess map) #9339

Closed
4 of 12 tasks
daveo1001 opened this issue Jul 15, 2016 · 23 comments
Closed
4 of 12 tasks

Support for MTL map_Ns (shininess map) #9339

daveo1001 opened this issue Jul 15, 2016 · 23 comments

Comments

@daveo1001
Copy link
Contributor

daveo1001 commented Jul 15, 2016

Currently/To the best of my knowledge the only shininess setting for phong material is shininess (mtl Ns) but mtl supports a shininess map (map_Ns). I'm sure it's a pretty big deal but I'd be eternally grateful if this feature was added.

Three.js version
  • Dev
  • r79
  • ...
Browser
  • All of them
  • Chrome
  • Firefox
  • Internet Explorer
OS
  • All of them
  • Windows
  • Linux
  • Android
  • IOS
@mrdoob
Copy link
Owner

mrdoob commented Jul 16, 2016

We do not support shininess material on MeshPhongMaterial. We could considering adding it though.

@WestLangley
Copy link
Collaborator

MeshPhongMaterial.specularMap, which takes values in [ 0, 1 ], attenuates the specular component on a per-pixel-basis. When using it, you may have to set a fairly high MeshPhongMaterial.shininess value to begin with.

Perhaps that is a work-around for you.

@bhouston
Copy link
Contributor

Ah, I see the issue, "material.specularStrength" is applied to the whole of the Phong Specular BRDF instead of just applied to the shininess parameter. I'd suggest that we replace specularStrengthn with shinininessMap that modulates the shininess instead. I think that is actually much more useful and more physically correct.

@WestLangley
Copy link
Collaborator

@bhouston Our implementation of MeshPhongMaterial is not a physically correct model in any respect. Personally, I do not think it matters. I would focus on the physical materials, instead.

But if you want to change the model, I would not oppose. The thing to do would be to add shininessMap, which would be modulated by shininess. Leave specularMap, alone for backward-compatibility or remove it.

@mrdoob
Copy link
Owner

mrdoob commented Jul 16, 2016

But if you want to change the model, I would not oppose. The thing to do would be to add shininessMap, which would be modulated by shininess. Leave specularMap, alone for backward-compatibility or remove it.

👍

@bhouston
Copy link
Contributor

@WestLangley wrote:

@bhouston Our implementation of MeshPhongMaterial is not a physically correct model in any respect.

The ThreeJS implementation of BlinnPhong is not physically correct, that is true. Other renders do have much more physically correct implementations -- V-Ray and PRMan have really good implementations of BlinnPhong that are essentially as physically correct as MeshSTandardMAterial/MeshPhysicalMaterial -- they differ only in terms of parameterization.

The reason why ThreeJS's MeshPhongMaterial are so bad is because of three issues with our implementation:

(1) We are not energy conserving. Energy reflected by specular layer should not be made available to the diffuse layer. If specular is 1, 1, 1 (which means the surface is metallic and fully reflective) then the light getting to the diffuse layer should be 0,0,0. (This energy conservation is part of MeshStandardMaterial in the way that increasing metalness reduces the intensity of the diffuse layer.)

(2) ShininessMap should modulate shininess.

(3) SpecularMap should be a color map that modulates specularColor.

This would be useful to have right because then ThreeJS can load MTL, FBX and other BlinnPhong model using files with as full fidelity as other professional rendering packages.

@bhouston
Copy link
Contributor

Just as a point of reference in defense of properly implemented Blinn-Phong, V-Ray uses Blinn-Phong almost exclusively and its stuff looks amazing:

https://www.google.ca/search?q=v-ray+architecture&source=lnms&tbm=isch

@WestLangley
Copy link
Collaborator

@bhouston I agree, your suggestions make perfect sense. I wonder why it wasn't implemented that way in the first place...

@bhouston
Copy link
Contributor

bhouston commented Jul 17, 2016

There was a previous attempt to implement energy conservation in BlinnPhong -- I think it was relatively correct as it followed roughly how professional renderers do it. It is important to note that one doesn't have to use a Fresnel term in the energy conservation as it isn't done this way in Standard/Physical either when blending towards metallic just linearly decreases available light at the diffuse layer.

b101729#diff-3d33ad8ea54d86cc060ca7b09c39d896R11

@daveo1001
Copy link
Contributor Author

@mrdoob I didn't think so. I would like it very much if you did consider it.
@WestLangley I'm already using the specular.map and it is enough to get by with what I'm doing but having a map for shininess to go with it would really make my day.
@bhouston you're way smarter than me. keep it up!

@WestLangley
Copy link
Collaborator

This is turning out to be an enormous change. Here is some code for reference.

float specularStrength;
#ifdef USE_SPECULARMAP
	vec4 texelSpecular = texture2D( specularMap, vUv );
	specularStrength = texelSpecular.r;
#else
	specularStrength = 1.0;
#endif

#ifdef ENVMAP_BLENDING_MULTIPLY
	outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );
#elif defined( ENVMAP_BLENDING_MIX )
	outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );
#elif defined( ENVMAP_BLENDING_ADD )
	outgoingLight += envColor.xyz * specularStrength * reflectivity;
#endif

Objective

  1. Use specularMap to modulate MeshPhongMaterial.specular, assume specularMap is RGB-valued, not grayscale. (easy)
  2. Add shininessMap to modulate MeshPhongMaterial.shininess. shininessMap is grayscale. (also easy)

Consequences

  1. The leaves no per-pixel map to modulate reflectivity. We could add a reflectivityMap, too, but the ENVMAP_BLENDING modes are such a hack, I hate to go down that path. Why create such hacks when we have MeshStandard/PhysicalMaterial available?
  2. MeshBasicMaterial and MeshLambertMaterial support specularMap, and would either need to have that property renamed to reflectivityMap or -- my preference -- remove the support for per-pixel reflectivity from those two materials -- and MeshPhongMaterial, too, for that matter.
  3. Whatever we do, there are huge ramifications for the loaders.

Previously, we have wondered why we are supporting MeshPhongMaterial when we have the properly-designed MeshStandardMaterial to replace it. I think that is a good question.

@pailhead
Copy link
Contributor

pailhead commented Jul 7, 2017

#else
	specularStrength = 1.0;
#endif

should not be constant, as with other parameters there should be a float available to override the texture. If one has the ability to use a texture containing values in the 0-1 range, why is the alternative locked to 1? Why not 0, or .5346?

@donmccurdy
Copy link
Collaborator

donmccurdy commented Jul 11, 2017

This feature is under consideration for the glTF 2.0 Blinn-Phong extension (see discussion), so I will be interested in what is decided here as well. It was mentioned by @bhouston that our MeshPhong model is spec-gloss — is it possible to implement this with the PBR spec-gloss material already checked into GLTF2Loader?

/cc @takahirox

@donmccurdy
Copy link
Collaborator

donmccurdy commented Sep 10, 2017

Previously, we have wondered why we are supporting MeshPhongMaterial when we have the properly-designed MeshStandardMaterial to replace it. I think that is a good question.

IMO, there is still need for more performance-tuned materials on mobile devices e.g. Cardboard/Daydream/GearVR.

The leaves no per-pixel map to modulate reflectivity. We could add a reflectivityMap, too, but the ENVMAP_BLENDING modes are such a hack, I hate to go down that path. Why create such hacks when we have MeshStandard/PhysicalMaterial available?

I don't think I follow... Is there something about this proposal that makes reflectivityMap necessary? Or are you mentioning it to round out remaining foo/fooMap pairs?

@bhouston
Copy link
Contributor

@donmccurdy The implementation of "BlinnPhong" in Three.JS is fairly wrong compared to the correct implementation in V-Ray and other top quality renderers. I describe the real issues here and how to address them:

#9339 (comment)

My recommendations are not that hard to implement and but it is a breaking change for a bunch of people who are already suing the incorrect BlinnPhong.

@WestLangley
Copy link
Collaborator

IMO, there is still need for more performance-tuned materials on mobile devices

I don't expect Phong will suffice for that purpose.

I don't think I follow... Is there something about this proposal that makes reflectivityMap necessary? Or are you mentioning it to round out remaining foo/fooMap pairs?

What we are currently calling specularMap would be changed from a single-channel map to a 3-channel map used for a different purpose. So, we either have to remove the current specular map functionality completely (from Basic and Lambert) or rename the former specularMap to something else -- like reflectivityMap.

I mentioned it because these are breaking changes.

@bhouston
Copy link
Contributor

IMO, there is still need for more performance-tuned materials on mobile devices

Properly implemented BlinnPhong should be computationally equivalent to properly implemented Physical materials within some small margin of error.

@donmccurdy
Copy link
Collaborator

I don't expect Phong will suffice for that purpose.

Properly implemented BlinnPhong should be computationally equivalent to properly implemented Physical materials within some small margin of error.

Thanks @WestLangley @bhouston! In that case I don't have an opinion about maintaining MeshPhongMaterial alongside MeshStandardMaterial. Unlit shading is probably what I need to be looking at; I'd like to get that definition updated for glTF2.0. I will retire from this thread. 😬

@WestLangley
Copy link
Collaborator

For the record, I implemented .shininessMap for MeshPhongMaterial and ultimately abandoned it. It was difficult for me to get predictable results modulating .shininess with a per-pixel map.

The primary reason is .shininess is unbounded, and not a measure of "perceptual shininess". Hot spots are often over-bright to begin with, and modulating shininess can still result in an over-bright hot spot, with little perceptible visual difference. MeshStandardMaterial has a much better parameterization; .roughness is, in fact, "perceptual roughness".

Regarding an RGB.specularMap, I now see little benefit to adding this. Such a feature may be useful in modeling metals, but MeshPhongMaterial does not do a good job of representing metals, anyway. MeshStandardMaterial, on the other hand, does. Consequently, I have abandoned adding an RGB .specularMap to MeshPhongMaterial.

My recommendation at this point is to leave MeshPhongMaterial as-is. Sophisticated users can use MeshStandardMaterial.

@WestLangley
Copy link
Collaborator

WestLangley commented Apr 26, 2018

I still would be in favor of renaming the current grayscale .specularMap to .reflectivityMap, as it modulates the .reflectivity property in the MeshBasic/Lambert/Phong materials.

Note, we use the property .specularMap elsewhere. An RGB .specularMap is used in the glTF Specular-Glossiness extension, where it modulates .specular, the specular reflectance of the material.

@bhouston
Copy link
Contributor

I would suggest studying V-Ray, Blender's Cycles and Unity to figure out what they do and then take the average solution in terms of how things are modulated and what things are called.

This would achieve the most compatibility possible as these are the tools that I think have the most widely accepted Blinn-Phong shading models.

@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 18, 2020

Closing in favor of #7290 which tracks the mentioned changes to specularMap and reflectivityMap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants