-
-
Notifications
You must be signed in to change notification settings - Fork 35.5k
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
Reflectivity through specular color #7419
Reflectivity through specular color #7419
Conversation
@WestLangley thoughts? |
Not when trying to use |
/ping @tschw |
Although combining several physical models, Burley's model as a whole is an empirical model. So Also that
But you didn't ping me for a review, right? How can I help? |
The review was a bonus. Thanks for that! 😊 I was pinging you because sounds like @WestLangley is still seeing the brokenness #7455 was meant to fix in examples using |
That one shows a car with matte paint and it looks really nice 👍 The ground plane is black. Is it supposed to look different? |
That material shouldn't be affected by #7455 in any way, which fixed flickering Lamberts. I guess the example looks fine for me. Flicker again? Any diagnostics about uninitialized variables? Try different browsers - I only got the warning with Firefox. Switching on privileged extensions in |
Somewhat weird? Well, you are entitled to your opinion.
There is a lot of history that went into the initial PR #7381. The metal model for Most users do not understand what the diffuse reflectance of the material, and the spectral reflectance of the material are. Consequently, you will see -- even in the three.js examples -- something like The decision to use the metalness workflow was a decision I made #7381. Now, there is just Prior to the recent PRs, |
OK, I can see why you want that parameter. With "weird" I was referring to the color normalization code to derive the reflectivity (doing a very rough approximation of luminance and using it to scale the color, IIRC).
For me it looks as if it's still working quite nicely.
Maybe it's simpler when I say what I am not seeing: There are no errors on the log :-). Something driver-specific? What's it complaining about? |
It's working here too. What errors are you getting? The floor shouldn't be so dark though... |
Yay! : - ) Not for me though...
The addition of reflectivity into this formula was a modification by @bhouston. |
I had pulled it out separately in the defines. I can fix it Wednesday when Best regards,
|
Then I guess I meant the "spectral reflectance" (note the "ance") a.k.a. "L0_lambdawhatevar" or specular "color" earlier :-). Both terms even have distinct definitions - crazy physicists... I see you also use |
@tschw Your input on the models is definitely welcome. At this point, I am not sure which version you are referring to. I am currently dead-in-the-water, as the dev-build shaders are now invalid for me, and I have not had time to track down the problem. Regarding the I have no problem changing the model. Well, as long as there is a compelling argument for doing so. :-) |
I used I also multiplied it with the Smith geometry term (again, based on the reflection angle, not the one from the specular) to account for roughness. Read it in some paper and it gave a visual improvement, but I also had to apply some clamping to avoid artifacts, so I'm not sure whether I have gotten that part correctly correct. |
Reverted the formula. You shouldn't see errors now? |
I see no errors. Thanks! Note to self: I think the pesky warning
can be removed by grepping for
and replacing with
|
@WestLangley confirmed and fixed! |
@mrdoob Sweet. Thanks! |
BTW both specularColor and reflectivity are both what one can call F0, the fresnel reflection when the surface normal is aligned with the viewing normal. It is actually a alternative representation for a material's IOR -- you can convert between specularColor/reflectivity and IOR easily -- I've linked to such code in the past. Reflectivity, being a single float, is appropriate for dielectric Fresnel (plastics, glass, etc), because dielectrics only do untinted reflections. For conductive Fresnel (matels) you want to be able to tint the reflected color and the MeshPhysicalMaterial does this by tinting reflecitivy by color as you increase the metalness. It doesn't make sense to have both specularColor and reflectivity because we are defining the same thing twice. I choose SpecularColor for my implementation of Physical Materials in Clara.io. But in the Disney PBR model, they choose Reflectivity. I am okay with either, but not both -- because then it just gets confusing. Reflecitivity/SpecularColor should be the driver of cubemap reflections as well -- the separation of SpecularColor from reflectivity (only affects CubeMap reflections) in MeshPhongMaterial is not really physically correct. BTW in the Disney PBR model, if you do set metalness to 0, reflecitivy/specularColor should be scaled down to 0.08 or something similar before going into the shading equations, because dielectric Fresnel materials have low reflecitivity in reality. It is only as it becomes metal (conductive Fresnel) that you can have reflecivity/specularColor near 1.0. |
Thanks for taking the time to explain the rationale. So for realistic metals we have to set diffuse color to the L0 constants for the RGB wavelengths and set metalness = 1, correct? The reflectivity parameter has no influence on the specular color in this case, correct? Because metals always reflect?
I see there should be |
@tschw wrote:
What is L0 constants? I am not used to that terminology.
SpecularColor and reflectivity are the same thing, it is just a terminology difference -- this is why we shouldn't have both if we want our system to make physical sense. Reflectivity often has RGB channels but in the Disney PBR model it is monochromatic, I guess because it is aimed at materials that have dielectric Fresnel. Generally, the large majority of materials reflect. For example this rant: http://filmicgames.com/archives/557 But metals have higher reflection ratios in general -- usually above 0.8, even at F0. Metals also differ in that they have no diffuse -- because diffuse models very minute subsurface absorption and re-emission (which is why it is unidirectional) -- metals do not do this. Rather metals have absorption at the interface without visible re-emission (I believe it is re-emitted at heat?), e.g conductor Fresnel, rather than pure reflection (dielectric Fresnel.) This is where specularColor makes physical sense -- because it is an attempt at modeling conductor Fresnel absorption at the interface. But modeling metals (conductor fresnel) via specularColors is not accurate. Here is a test I did a few weeks ago comparing a true Conductor Fresnel with Dielectric Fresnel using the SpecularColor "hack": https://plus.google.com/+BenHouston3D/posts/aRUrteKg4WV |
PS. I wrote a ThreeJS MeshMetalMaterial the other day that is a true conductive Fresnel material. But it is built on all my PRs so it isn't possible to contribute it back yet. |
Yes, I get that part. I was talking code: The specular color is a function of reflectivitiy, diffuse and metalness and the influence of reflectivity gets cancelled out by metalness: material.specularColor =
mix( vec3( 0.04 ) * reflectivity, diffuseColor.rgb, metalnessFactor ); So reflectivity only / mostly applies to dielectrics? It's also used to weight the input from the environment map in It contradicts your statement that the the environment is reflected based on the specular color alone and I am having difficulties figuring out how it can make sense. |
UE4 uses 0.5 as the default, and they give a list of suggested specular values of a number of surfaces (all of which are in terms of the Disney PBR parameterization of [0, 0.08] for realistic dielectric Fresnel at F0): https://docs.unrealengine.com/latest/INT/Engine/Rendering/Materials/PhysicallyBased/index.html |
Aha! So we can just default From your link, I see now where the
Maybe if we do decide to have a simple model and an advanced model, the |
Note I kept that property, suggesting to combine float metalness = smoothstep( 0.75, 1.0, specularity );
specular = mix( vec3( 0.08 * specularity ), diffuse, metalness ); It would sacrifice the upper end, figuring that a slight "metalness" may achieve a similar effect. All the values listed in the UE4 documentation can be represented. @bhouston |
@tschw wrote:
It is best to stick with what everyone else is doing because there are assets being created in a large number of tools that use the Disney/UE4 model. Merging reflectivity and metalness together means you can not really use the metalness maps generated in other tools properly in ThreeJS. I would prefer to discard "reflectivity" all together because it is generally around 0.5,, than to mix it with metalness in a non-standard fashion. I was trying to fix the issue with the previously existing "reflectivity" being non-standard by making it conform to the closest thing in the Disney PBR model -- so that it affected both direct and indirect specular equally in the same way the monochromatic "specular" behaved. @tschw wrote:
Reflectivity is just the ThreeJS version of the monochromatic "specular" that both Disney PBR and UE4 Physical have -- and both Disney PBR and UE4 Physical have separate clear coat properties. Clear coat behaves differently than the current "reflectivity"/"specular". You can download UE4 for free and try it out there. I allow for full clear coat in Clara.io, but I should probably only allow for 0.25 weighting -- here is an animation of what clear coat (nothing to full) is over top of a slightly rough steel: https://clara.io/view/039396c3-f2f0-42dd-bdb7-4243bfa96507 Clear coat is energy conserving as well. |
OK, this is a strong argument to keep it as is.
I think, despite all confusion, the monochromatic approach really makes a lot of sense. Parameters cancelling each other is a little awkward, but seems to be what everyone is doing. The usefulness of a purely dielectric specular vector is at least debatable. Do you have an example of a dielectric material with a non-monochromatic specular response or any clue why they have it?
Well, that question was pretty much answered as I read the UE4 material API.
I know. Still could brighten / darken the reflectivity to crutch around its absence, I guess.
Good to know they changed the licensing model. I should probably pay more attention to existing technology and what's happening in the world :-). Very subtle - I was immediately looking for a fader to crank the roughness up. |
BTW earlier this year I did a bit of work with Nick Porcino (of Apple now, but I know him from his ILM days) and a little bit with Brent Burley (of Disney) to help find a common PBR definition for both Clara.io and for Apple's Model I/O library (which come out as part of iOS 9) that Nick was working on. This is our working document: https://docs.google.com/document/d/1EUqnM-aQwl76aZpduQk-EL0vGEPHrJE7h1x7wSqqLlk/edit# You can see that this model is reflected in the final Model IO material design here: And here: I love the parameters that Nick chose for the rest of Apple's Model IO classes, like these light parameters, they are so clear and concise: |
Clear coat darkens the underlying specular, while adding bright pure white hilights that are typical of a lacquer. Particularly important for wood furniture like this one (which is V-Ray rendered): https://clara.io/view/1d984b08-9711-4643-ae01-c3e53b174ace/render It is a lacquer that makes wood look amazing, it gets nice dark colors that still respond to light but with that shininess/polish. Also many cars have a clear coat layer that gives them their deep colors coupled with their shine - you just can not get it any other way: Thus if you do not do clear coat, you can not do proper wood furniture nor car paints and other similar materials (e.g. the ceramics in your kitchen/bathroom.) |
@tschw wrote:
Metals have high absoprtion coefficients for various light types. Non-metals have neglible absorption coefficients because they are not conductors -- absorption == conduction, get it? :) Also all materials have varying IORs based on the wavelength of light. This is captured by the Abbe Number parameter which attempts to fit a line to the change. This is responsible for dispersion effects, such as rainbows. https://en.wikipedia.org/wiki/Abbe_number Btw, you can explain varying IOR and absorption coefficients on this website: http://refractiveindex.info/?shelf=main&book=Ag&page=Rakic |
@bhouston wrote:
If you want to remove it completely, that is fine with me. It is up to you. If you want to keep it, do you want to maintain suppprt for a |
Thanks for sharing! First time I see a
OK, that's better advertisement for the feature. Won't look much worse in real-time, I figure.
Yes, I get it. But you're not really answering my question - at least not directly. Are you saying that the UE4 specular (only applying to dielectrics) is a spectral vector, so that artists or rendering passes can paint dispersion effects into textures? But that'd be odd - sitting on a silver plate won't keep a glass prism from making a rainbow?! |
I vote for removing 😊 |
@tschw wrote:
In UE4, specular is a scalar I believe and only affects non-metals (basically they followed the Disney PBR specificiation.) UE4's "specular" has no relationship to dispersion. I've never seen a real-time engine actually have AbbeNumbers support -- I just mentioned that for completeness of understanding Fresnel effects at the interface (varying N (refraction) per wavelength is independent of varying K (absorption) per wavelength). Metals do have RGB channels for N (refraction) in most renderers, but they are not transparent, thus people do not model dispersion with these objects. |
@tschw wrote:
Mostly, but trying to get it to look like that with the lights will require fiddling. The reason it is nearly impossible to match V-Ray scenes in ThreeJS is because of ThreeJS's light definitions are non-physical, where as everyone else's (Apple's iOS, Unity, Unreal Engine, Maya, 3DS Max, Blender) are physically based. ThreeJS's lights use a unique formulation that isn't replicated in any other tool. It is a real problem when trying to get an efficient content pipeline into ThreeJS for everyone who wants to create content for ThreeJS without having to fiddle with things. |
Maybe we can change that next? |
That would be absolutely amazing! Did you know that all lights created in Blender look completely different when exported to ThreeJS? The only thing that is transferred correctly is their geometry (position, direction) and their color, but the intensities and falloff are incorrect in nearly all cases. This is one thing that Blend4Web currently has as an advantage over ThreeJS -- Blender, when used with Blend4Web, is really close to a WYSIWYG editor, and that is very powerful. |
We'll get there! I wouldn't mind breaking changes in lights. |
Not just the lights, also texturing. |
@bhouston Would you like me to remove I also notice that since |
I am fine with this. I thought you already removed it. :) |
OK. I will do it. : - ) One more thing. The Even one more thing. In |
I think we need to. It doesn't fix the seam problem completely though, the cubemaps for specular also currently have seams with Chrome and Firefox on non-ANGLE-based platforms (e.g. non-Windows.) Having a cubemap generator will fix both of these issues (irradiance and specular cubemaps.) |
To be clear, I advocate for using 32x32x6 cubemaps for the irradiance instead of the spherical harmonics approach. The reason is scalability and less pressure on fragment uniforms. In a game level you will want to have different irradiance maps for different regions and interpolate between them. If you are doing that, you likely also want specular blur maps as well. If you combine them into the same cube maps (with the irradiance in the lower levels of the specular blur map), then it is very efficient. But if you keep them separate, you need to have the same number of specular blur maps, but then a huge number of SH parameters in the uniforms. Also in generation, it is easy to generate an irradiance cube map if you are already creating specular blur maps, so it can be efficient in terms of time and code. So for efficient sake, I advocate trying to stay with cubemaps for everything and packing specular and diffuse together to further save on uniform slots in the fragment shader and just overall resource management. SH I believe is most useful if you only have a single pre-computed one. But otherwise, I think the benefits over a cubemap irradiance map of 32x32x6 are minimal. |
@bhouston OK.
Just so I understand, it is OK to comment it out for now? Also, what about the 0 roughness issue I mentioned above? |
@WestLangley Your remapping of the roughness parameter to never actually go down to 0 in the lighting equations is the reason why there are no sharp reflections in ThreeJS as it currently is. Basically this comment of yours explains why we should not have sharp reflections with a roughness of 0 -- because it is remapped to be not zero: I have advocated in other issues to remove this remapping because the full range of roughness is useful: #7420 |
To be clear, it is just commit of mine from last month that is required to fix the sharpness of the reflection map at roughness 0: |
You argued against this change here: #7420 (comment) But if you want sharp reflections you need to remove this remapping. If you want reflections to be crisp but not the light specular to be crisp you are advocating a disjoint physical model that makes no sense -- so you need to pick one side, either keep the non-crisp reflections and keep your remapping or move towards allowing crisp reflections and remove the remapping as I advocated last month. |
You are mischaracterizing my statements and my intent. I am not going down that path with you. |
This PR is built upon the simplified lighting PR here: #7324
According to the Disney PBR paper, reflectivity should control the amount of light reflected for non-metalness. Thus it should modulate the specularColor. This PR completes that change - thus only specularColor is modulated by reflectivity and reflectivity is not used elsewhere (e.g. not in the envMap incoming light calculation.)