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

Glossy area recieves highlight even when it's shadowed due to lack of specular occlusion #19561

Closed
mysticfall opened this issue Jun 14, 2018 · 31 comments

Comments

@mysticfall
Copy link
Contributor

mysticfall commented Jun 14, 2018

Godot version:
master / acd9646

OS/device including version:
Manjaro Linux 17.1

Issue description:
Currently, glossy areas of a spatial material look unrealistically bright even when under a shadow, because they still recieve highlight from light sources:

glossiness
40037235-31854b7e-5847-11e8-8260-bc3ff47e965c

@akien-mga akien-mga added this to the 3.1 milestone Jun 14, 2018
@reduz
Copy link
Member

reduz commented Sep 7, 2018

This is how it works in real life.. shadows will only stop direct light, but not reflections. I think shadow mapping only stops the light specular lobe (which is not entirely correct), but that reflection seems to come from your environment.

@reduz reduz closed this as completed Sep 7, 2018
@mysticfall
Copy link
Contributor Author

That makes sense. It seems that I have set indirect energy too high. Thanks for the explanation!

@mysticfall
Copy link
Contributor Author

Recently, I revisited this issue but still haven't found a good way to fix this problem. I was able to track down the cause to the GI probe, and its sky contributon so far (toggling interior option fixes the problem completely, but of course, it also results in much less realistic result).

But in order to mitigate the problem, I had to turn down the GI influence so low that it almost makes little difference whether or not it's being used at all.

Tweaking the directional light doesn't seem to affect the problem, by the way.

I've linked this issue in my tracker for rendering a realistic character (#26891). And I wish either this issue could be reopened, or I could be given a direction as to how to fix this problem on my end, if it is indeed an expected behaviour.

@golddotasksquestions
Copy link

I would also like this to be reopened. I'm not sure how to solve this though, because if reduz is right, the environment would have to somehow detect ambient occlusion and self shadowed areas and reduce up to eliminate the environment reflection there. Typical areas are: ears, nostrils, eyelids, armpits, hands, feet on a nude character. But the same effect is visible on gear as well.

@Megalomaniak
Copy link

Looks like the fresnel component of the reflection. If you want to have realistic looking skin on your characters you might want to consider developing a proper purpose built skin shader either by using shader language or the visual shader graph. This is of course a more advanced topic though. Things to look into would be for an example Fresnel reflection, subsurface scattering and PBR shading in general.

@mysticfall
Copy link
Contributor Author

@Megalomaniak But is the current behaviour correct one? If not, I think we better reopen the issue as this is by far the biggest obstacle for me among those I listed in my tracker issue, and I'm pretty sure others would be affected as well.

But if this is indeed the right behaviour and should be handled by a dedicated shader as a special case, then I think we need to open another issue as a feature reqeust.

@Megalomaniak
Copy link

Megalomaniak commented Mar 20, 2019

Yeah for a generic default material it's probably about right fine(this is more performance optimal and there are mobile device constraints to consider).

In reality that Fresnel effect should act like a mask for a reflection that would reflect according to ray reflections off of the geometry(the object would also be self reflecting then). But we are not dealing with path-/ray-tracing in here. There are potentially ways to achieve this but they are going to be rather performance costly. Hence why for a basic default material it's probably not the right choice.

As for specialty/custom shaders it might make more sense to simply have the community develop such shaders, we have the asset library/store for a reason. Mind, this is just my personal opinion.

@golddotasksquestions
Copy link

If it is indeed the fresnel component of the reflection, we could have a much better default material if the ambient occlusion would mask the fresnel component. I would much rather have this built into the engine because there is no usecase where you want fresnel in ambient occludes areas, which seems to be the only option right now.

@mysticfall
Copy link
Contributor Author

mysticfall commented Mar 20, 2019

@Megalomaniak Thanks for the explanation. If it is indeed the case, then I'll just open another feature request for a dedicated skin shader. I'm not sure if something like this could be written with Godot's built in shader editor, but even if it coud, I wish something like that could be shipped by default as it is the case with other popular engines.

The reason is, it is practically impossible to make character skin look decent at this moment, because there is no middle ground between soaked-in-oil level glosinnes when shadowed, and looking completely dry otherwise.

This shows how the exact same material changes in the same environment, according to the way it's shadowed:
image

image

@golddotasksquestions
Copy link

I don't think a skin shader is the solution for this particular problem. This is unwanted behavior on any rendered object, not just skin

@Megalomaniak
Copy link

Megalomaniak commented Mar 20, 2019

I would much rather have this built into the engine because there is no usecase where you want fresnel in ambient occludes areas, which seems to be the only option right now.

That's not necessarily true, in reality where there is light there is always reflection/refraction with absorption and more rarely diffraction causing the color of an object. There's always going to be some ambient lighting in atmospheric conditions. Thus it should be a mixture of AO and ambient lighting controlling it then not just the AO on it's own. There certainly should be a way for a developer to use the ambient lighting and AO components to control the Fresnel though, I can agree with that.

I haven't looked into using AO component within a shader material but I would be surprised if it really isn't already possible.

@golddotasksquestions
Copy link

golddotasksquestions commented Mar 21, 2019

Fresnel component of reflection used here or in most 3D applications has very little to do with reality.
The Fresnel effect does, but it only occurs on uneven convex object that receives light from behind the object. Visually squished together through perspective, the "moutain-tops" of an uneven surface become one very shiny reflective surface. http://filmicworlds.com/blog/everything-has-fresnel/

Which is why the more mirrow-like an object, the less fresnel it has. The only way to make a perfect mirrow-surface have fresnel is to make is dusty. Because everyday life is less sterile and rather dusty and unpolished, having some amount of fresnel on convex objects always looks more "realistic" than none.

A visually similar effect occurs when light shines from the viewers position onto an object with fine, very short and thin hair. The anisotrophic nature of the hair causes the light to reflect back to the viewer with increasing intensity on the normal.

That's why a material with only fresnal will often look like velvet or a very smooth soft to touch vinyl.

The reason why the fresnel component of reflection is found on so many default materials, is not because behaves realistically, but because it creates the faked impression as if the object would receive light from all around and behind the object and have some kind of silky-smooth textured surface. Anything but the mathematical impeccable surface it actually has. It works, it's cheap, but not very realistic.

Either way there should be no fresnel in a nostril or earhole or anywhere on a convex shape inside a concave one, because the shape is blocking the light:
fresnel

@Megalomaniak
Copy link

Megalomaniak commented Mar 21, 2019

Your illustration assumes that there can be no light bounces in the cavities. Also you seem to be thinking only in terms of direct lighting. That is to say you assume that Sun would be the only light source, and while it's technically true that in a day time out doors scene most of the light would originate from the sun, it would still get reflected off of other surfaces(ground, trees, walls, out of atmosphere objects such as any moons) and refracted and diffused by the atmosphere. As far as the object rendered is concerned those would all be light sources.

@golddotasksquestions
Copy link

golddotasksquestions commented Mar 21, 2019

? This issue is about the highlight inside an area where is has no reason to be. It's not about Global Illumination or Raytracing.
Right now all you can do to lessen the effect is to turn up AO, but this will just multiply black onto the highlight, resulting in a grey highlight.

@Megalomaniak
Copy link

Megalomaniak commented Mar 21, 2019

The real issue is that the Fresnel shows up in the correct place but for it's color values it should be reflecting the shaded color values of the neck(mostly), head and hair of the character in front of the sky rather than just the sky, talking about the example in OP.

The reflection for the character is calculated before the character is rendered to the scene hence no character in the reflection. This is the perfect example for why real-time ray-tracing would be awesome. An easy way to achieve self reflection on an object as well as reflection of everything else. It's the so-to-speak holy grail of PBR.

Actually the real holy grail would be to achieve accurate spectral caustics on top of that I guess.

@golddotasksquestions
Copy link

golddotasksquestions commented Mar 21, 2019

You are correct and Realtime Raytracing is cool no question but waaay more expensive. We only start to get Graphic cards supporting it on the market. AO is already available in the engine and cheap. With AO we have texture data where this effect should not appear.

@Megalomaniak
Copy link

Megalomaniak commented Mar 21, 2019

And as I said above¹, sure it should be possible, with that I meant that if it is not then that option should indeed be added. But to have it work at least a little more accurately it should be AO and ambient lighting value both in combination used to modulate the Fresnel with.

@mysticfall
Copy link
Contributor Author

mysticfall commented Mar 22, 2019

I just posted comparison screenshots between Godot and Unity in #27283. I wonder if it could be a sufficient proof that this is actually an issue in Godot, if it's not some mistake on my part (in that case, I really hope someone could tell me how I could fix that problem).

@mysticfall
Copy link
Contributor Author

@reduz @akien-mga Could we reopen this issue? Apparently, a similar setup doesn't exhibit the same symptom in Unity as shown in #27283, and I think I have already exhausted options that other people have suggested to fix this problem if it was caused by something I have done wrong.

@akien-mga akien-mga removed the archived label Apr 8, 2019
@akien-mga akien-mga reopened this Apr 8, 2019
@akien-mga akien-mga removed this from the 3.1 milestone Apr 8, 2019
@mysticfall
Copy link
Contributor Author

@akien-mga Thanks! :)

@mysticfall
Copy link
Contributor Author

New screenshots after #29182. I have an impression that the symptom looks slightly less pronounced after the the radiance map fix, but it's definitely still there:

화면 저장_20190528_090349
화면 저장_20190528_090653

@clayjohn
Copy link
Member

Could you re-test this when 3.2 releases? I think the extensive improvements to radiance/irradiance may fix this

@mysticfall
Copy link
Contributor Author

mysticfall commented Jan 27, 2020

For the moment, I'm stuck with d711c57 build because recent versions CTD when I open up my project (already reported an issue about it).

The problem described in this issue seems to be largely unaffected with the build I've been using. But I'll report it here once I'll be able to update Godot again and see any changes to this issue.

@Calinou
Copy link
Member

Calinou commented May 19, 2020

@mysticfall Have you been able to reproduce this issue with 3.2.1 or the master branch recently?

@Megalomaniak
Copy link

Perhaps worth a note here that @SIsilicon is implementing buffer/pass access from Viewport textures. Accessing them via uniforms would enable for more advanced skin-shaders to be developed.

godotengine/godot-proposals#798

Though it's done for the GLES renderer, apparently this was/is a planned feature for the Vulkan renderer as well so hopefully this will be available in both the renderers in version 4.0

@SIsilicon
Copy link

I don't think this is a skin shader issue, but a general real time lighting issue. The problem is that the object is lacking specular occlusion. It's like ambient occlusion, but for reflected light. 🙂
Technically, screen space reflection is one of the solutions to this issue, because it can cover up unrealistic highlights with a truer reflection. There are other solutions out there such as bent normals, and extensions of some ambient occlusion algorithms.

@Megalomaniak
Copy link

Yes, real reflections(especially raytraced) would be the most correct solution to this as I've insinuated here before, but the AO pass could certainly work as an approximate occlusion method as has been noted here before.

@Calinou Calinou added enhancement and removed bug labels Jul 4, 2021
@Calinou Calinou added this to the 4.0 milestone Jul 4, 2021
@Calinou Calinou changed the title Glossy area recieves highlight even when it's shadowed Glossy area recieves highlight even when it's shadowed due to lack of specular occlusion Jul 4, 2021
@Calinou
Copy link
Member

Calinou commented Aug 30, 2021

Horizon specular occlusion was implemented in #51417 and #51416. It should alleviate this issue significantly. There's further work ongoing to also use the ambient occlusion buffer to provide even more specular occlusion: #50601

I'll close this as the most obvious case of specular light leaks is now resolved.

@Calinou Calinou closed this as completed Aug 30, 2021
@Calinou Calinou modified the milestones: 4.0, 3.4 Aug 30, 2021
@Megalomaniak
Copy link

@Calinou and outside of using raytracing - the last cherry on top here would be to have screenspace reflection blended with probe/cubemap for artifact correction be used instead of white/sky color for the fresnel/rim reflectance here.

@Calinou
Copy link
Member

Calinou commented Aug 31, 2021

@Calinou and outside of using raytracing - the last cherry on top here would be to have screenspace reflection blended with probe/cubemap for artifact correction be used instead of white/sky color for the fresnel/rim reflectance here.

This is already done, but you need to have a ReflectionProbe in the scene. The scene displayed in the screenshots didn't use any ReflectionProbe, so they used the sky reflection fallback instead.

@Megalomaniak
Copy link

Great to hear! Would be nice to have a screenshot of that included in there tho, I'm sure I'm not the only one who missed it.

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

8 participants