normal map attenuation properties
closes #1139
per the open question in the issue, I didn't yet implement a mode for this. do we want to be able to set this to "inherit" etc.? if that's something we want I can add it, these properties are just slightly different than other zone properties so not sure?
Funding
This project is funded through NGI Zero Core, a fund established by NLnet with financial support from the European Commission's Next Generation Internet program. Learn more at the NLnet project page.
This might be a weird question to ask after you open this PR, but why should we expose the normal map attenuation? Is it a tradeoff thing, like with the shadow bias, where there is no "good" setting?
fair question! yes it’s kinda like the shadow settings. normal maps are for small details which become high frequency noise at a distance, causing artifacts like moire patterns. we fade them out over a distance to hide this, but the distance at which we want to fade can depend on the scale of the objects/normal maps, so it’s nice to make it configurable for creators
other engines have similar things I believe
Sounds like the distance should be set based on render resolution and how large a normal map is rendered in relation to its resolution (or how detailed it is, if we can find that out).
Currently lack of normal maps on distant objects makes normal mapped terrain look very flat, and having this setting is a very welcome improvement that was requested by several artists. I think it's a really good idea to allow it to "Inherit" like other settings. @HifiExperiments Maybe the normal map noisiness in the distance is caused by mipmap bias?
I just tested it and everything works very well, but currently there's no Inherit functionality, so it makes using this feature very difficult. I think zones should inherit it by default, like skyboxes for example. Another thing is that I didn't notice any adverse effects of setting this to a very high value, world looks much less flat that way. Maybe we should set it to a very high value by default, so that users are not confused why normal maps disappear in the distance? @AleziaKurdis Your opinion on this would be really appreciated, especially since your worlds use normal maps extensively.
In my opinion it looks way better with limit set to greater distance, for example in Alezia's Kopra world:
Default distance:
Increased distance:
I just tested it and everything works very well, but currently there's no Inherit functionality, so it makes using this feature very difficult. I think zones should inherit it by default, like skyboxes for example. Another thing is that I didn't notice any adverse effects of setting this to a very high value, world looks much less flat that way. Maybe we should set it to a very high value by default, so that users are not confused why normal maps disappear in the distance? @AleziaKurdis Your opinion on this would be really appreciated, especially since your worlds use normal maps extensively.
Inheritance would be good to have. But not sure we need to have s specific node for it. Maybe if the properties was in the Keylight node that would be enough. As for shadows stuff. (just an idea, let me know what you are thinking about it.) Not sure I would risque to change the default value. It will affect existing content. I supposed that if there was a limit that it has a rendering cost when we increase it? It would be nice to know how much. Aslo, is there a natural distance limit where the normal map just stop to be renderable? or it can be allied what ever the distance?
I supposed that if there was a limit that it has a rendering cost when we increase it?
There doesn't seem to be any performance decrease, I think shader always samples normal map?
Aslo, is there a natural distance limit where the normal map just stop to be renderable?
I don't think so. The worlds I tested looked much better with longer normal map distance, and normal maps become softer in the distance naturally thanks to mipmaps.
Not sure I would risque to change the default value. It will affect existing content.
True. Considering amount of existing content though, maybe it would be best to test and see if there are any problems, and if exisitng worlds look better or worse with longer distance? I'd be happy to help testing and gather comparison screenshots.
If there is no real rendering cost impact. Then I see no reason to have this as a property. There is not artistic value to reduce that "normal map "rendering distance. So I said just let the mipmaps rules the game.
So inheritence would become pointless too.
Maybe turn this as an interface graphical setting (if it's not already that) and have it high by default. At second thought, the existing limit was more a visual punishment than other things
I will test a bit more and see if I can find world where attenuation is needed - for now it looks like having normal maps at all distances looks much nicer in most worlds.
I think the problematic case is going to be more like:
- eye level with terrain
- normal maps are high frequency/small
- (edit) while you’re moving
in those cases the mip maps start to break down. trilinear blending would probably help but not completely. if I remember correctly hifi ran into this problem for some event or environment, hence the introduction of the fade out
so if that were true, even if it’s not used much, seems like we’d need a property for it. but can certainly bump up the defaults (there’s no cost, like 74 said), and definitely add inheritance (would add a new mode)
but if that’s NOT true and we decide it’s not necessary, I can certainly make it just a graphics setting or something (and still bump up defaults)
@HifiExperiments That's a really good point, I need to test more and see what happens at sharply angled surfaces
Is it possible that we are already using anisotropic filtering for mipmap textures?
oh! possibly: https://github.com/overte-org/overte/blob/4cbde7e3f07d2574f80c0fe24c598b378ccbf128/libraries/image/src/image/TextureProcessing.cpp#L1123
https://github.com/overte-org/overte/blob/4cbde7e3f07d2574f80c0fe24c598b378ccbf128/libraries/gpu-gl-common/src/gpu/gl/GLTexture.cpp#L47
https://github.com/overte-org/overte/blob/4cbde7e3f07d2574f80c0fe24c598b378ccbf128/libraries/gpu/src/gpu/Texture.h#L163
but…is that sufficient?
ok I've updated this with a proper normalMapAttenuationMode property, and the default zone defaults to the old values. "off" actually turns it off. thanks to Alezia once again for the new icon for create!
Inherit
Off
Near = 50, Far = 50
Also does the same when far is < near
Near = 50, Far = 51
is that big wall on the left triplanar? seems like the attenuation isn’t working on that specifically?
Oops, forgot to get a screenshot of it actually working… It works just fine outside of the far <= near case on the big cube.
It's the projected UV mode with the material scaled to the same as the big cube so there's big normal bumps
huh wacky! I can’t think right now why that would behave different. this sounds generally safe to merge then if we’re trying to push a release in the coming weeks, or can wait. either way I’ll take a look when I get back. thanks for testing!
@ada-tv I haven't been able to reproduce the issue - this is a zone with min = max (same with max < min) on a big box with a projected material with a normal map:
I added an epsilon to the min/max comparison so maybe that will help, in case it was some kind of driver issue with smoothstep when the two edges are equal.
if that doesn't fix it, can you send me a serverless json or link to the location?
While working on a test case serverless I found something interesting, UV and projected are handled correctly but triplanar acts like nothing's happened, but only on the near cube? The far cube is also triplanar but gets attenuated properly
@ada-tv thank you, that was super helpful! looks like I had screwed up a rebase and broken triplanar, but works now!
I just tested it and everything works well. Water in Overte_hub looks so much nicer with longer distance normal map attenuation :)
Before:
After:
