godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.13k stars 92 forks source link

Add self-shadowing to parallax occlusion mapping in StandardMaterial3D #1843

Open NHodgesVFX opened 3 years ago

NHodgesVFX commented 3 years ago

Describe the project you are working on: A demo scene and a 3rd person game Describe the problem or limitation you are having in your project: I got POM to work which was was nice although the effect is not as convincing as I hoped because it lacks shadows and still exhibits banding.

Notice in the photo you can see the banding and there are no shadows. pom_issue

Shadows cast onto POM also don't look correct, it looks like the shadow is floating. ezgif-1-7e356977e2aa

Describe the feature / enhancement and how it helps to overcome the problem or limitation: Add the ability for POM to cast self shadows, smooth the banding.

Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams: here are some papers and topics on POM which show it can and how to improve it. http://web.engr.oregonstate.edu/~mjb/cs557/Projects/Papers/Parallax_Occlusion_Mapping.pdf https://developer.amd.com/wordpress/media/2012/10/I3D2006-Tatarchuk-POM.pdf - same paper as above with slight differences https://stackoverflow.com/questions/55089830/adding-shadows-to-parallax-occlusion-map

The main thing I think need improving is banding and shadowing but other improvements can be made such as silhouette POM

http://developer.amd.com/wordpress/media/2012/10/Dachsbacher-Tatarchuk-Prism_Parallax_Occlusion_Mapping_with_Accurate_Silhouette_Generation%28SI3D07%29.pdf

If this enhancement will not be used often, can it be worked around with a few lines of script?: no Is there a reason why this should be core and not an add-on in the asset library?: its a improvement to a feature in core

Calinou commented 3 years ago

Self-shadowing in parallax mapping seems to be a pretty uncommon feature in practice. By "in practice", it means that a few engines support it, but it's rarely seen in games in production. Self-shadowing looks nice on static images, but it's unlikely you'll see a difference in a real world scene during gameplay. It does have a pretty significant cost, still.

As for smoothing the banding, I think this can only be improved by increasing the number of passes, which increases the rendering cost even more. Banding is usually the result of having steep height changes within the heightmap. Consider blurring your height maps in an image editor to make banding less noticeable.

NHodgesVFX commented 3 years ago

Self-shadowing in parallax mapping seems to be a pretty uncommon feature in practice. By "in practice", it means that a few engines support it, but it's rarely seen in games in production. Self-shadowing looks nice on static images, but it's unlikely you'll see a difference in a real world scene during gameplay. It does have a pretty significant cost, still.

As for smoothing the banding, I think this can only be improved by increasing the number of passes, which increases the rendering cost even more. Banding is usually the result of having steep height changes within the heightmap. Consider blurring your height maps in an image editor to make banding less noticeable.

I don't think shadowing should be enabled by default, it should be an option that way it can be enabled when its necessary. The texture map is blurred, blurring it more does not fix the banding. You also cant adjust the max sample count any high then the default 32. In the paper it seems there method allows for perfectly smooth POM even with steep changes. Perhaps this is because there sample count is higher or there method is better I'm not sure.

Calinou commented 3 years ago

You also cant adjust the max sample count any high then the default 32.

You can set the number of parallax steps above 32 using a script, but I'd expect it to be very slow for anything more than a single material.

NHodgesVFX commented 3 years ago

You also cant adjust the max sample count any high then the default 32.

You can set the number of parallax steps above 32 using a script, but I'd expect it to be very slow for anything more than a single material.

Thats a good note, I tried it and it seems setting it to 96 gets rid of the banding

SIsilicon commented 3 years ago

the shadow receiving could definitely be improved though. What could be done in the shaders is that the shadow sampling position can be changed. That way, parallax occlusion mapping can shift where the shadows are formed. Not only that, the idea can be extended to shifting the position of lighting calculations too. TL;DR, let the fragment variable VERTEX be writable. Or at the very least, make an output variable for where lighting should be done.

Maybe this should be a proposal by itself...

Edit: Just checked; I already made such a proposal. https://github.com/godotengine/godot-proposals/issues/974