godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.16k stars 97 forks source link

Overhaul Environment map filtering #498

Closed clayjohn closed 4 years ago

clayjohn commented 4 years ago

Describe the project you are working on: The Vulkan rendering backend

Describe the problem or limitation you are having in your project: Currently environment map filtering is done at load time and is too slow for real time effects. On my hardware (GTX 1050) updating the radiance map for a panorama sky can take anywhere from 30-60 ms on high quality. This makes realtime updating of skies or reflection probes impossible.

Describe the feature / enhancement and how it helps to overcome the problem or limitation: 1) Implement this paper for low-quality realtime reflections (I have already done so on a local branch). 2) Improve the default high-quality importance sampling. 3) Alter the quality settings for radiance

Between the three of these we should be able to create high quality radiance maps in realtime for all levels of hardware. This is necessary before we implement real-time sky shaders. This is also helpful so that users can have realtime reflections.

Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams: 1) I will update with a link to my branch soon. 2) This will be done by sampling from a higher mip level from the environment based on roughness and PDF described here 3) I think the radiance quality setting should be "Offline" or "Realtime". "Offline" would always use the current array based importance sampling to get highest quality without any artifacts. Of course, for certain HDR maps, a higher number of samples will be needed, while this is extremely slow, it may be desired for high quality rendering needs. "Realtime" would have options for high-quality and low quality which can be configured in the project settings.

If this enhancement will not be used often, can it be worked around with a few lines of script?: This enhancement will be used by almost every Environment.

Is there a reason why this should be core and not an add-on in the asset library?: This feature modifies core parts of the Vulkan backend

Old Comparison ## Comparison ### HDR Environment Map (fast filtering excels) *Old Method* ![Screenshot (58)](https://user-images.githubusercontent.com/16521339/75052432-75faac00-5484-11ea-8552-3c658b32375f.png) *Fast Filtering* ![Screenshot (55)](https://user-images.githubusercontent.com/16521339/75052419-7004cb00-5484-11ea-83a8-e2fe4019c9df.png) ### Default Sky (fast filtering shows cubemap artifact) *Old Method* ![Screenshot (57)](https://user-images.githubusercontent.com/16521339/75052506-9165b700-5484-11ea-85c9-903574df7d75.png) *Fast Filtering* ![Screenshot (56)](https://user-images.githubusercontent.com/16521339/75052424-73985200-5484-11ea-878a-4867cc70b1af.png)

Updated Comparison (23/02/2020)

Using Arrays

Current "High Quality": 1024 tap importance sampling Screenshot (74)

Fast Filtering: High Quality HQ-Array

Fast Filtering: Low Quality LQ-Array

Not Using Arrays

Current "High Quality": 1024 tap importance sampling Screenshot (73)

Fast Filtering: High Quality HQ

Fast Filtering: Low Quality LQ

The Numbers

Everybody's favourite part I know 😋

1,000 us = 1ms 1,000 ms = 1 second

Current implementation using Importance Sampling High Quality Low Quality
Array 75,000 us* 5,000 us*
Non-Array 20,000 us 670 us
Proposed implementation using Fast Filtering High Quality Low Quality
Array 10,000 us* 4,000 us*
Non-Array 2,000 us 300 us

*Array methods also have an extra 900 us overhead to generate mipmips, this can be spend up using compute

clayjohn commented 4 years ago

Implemented in https://github.com/godotengine/godot/pu ll/36588 and https://github.com/godotengine/godot/pull/36691