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

Reflection map prefiltering improvements #331

Open
vorg opened this issue Nov 14, 2022 · 5 comments
Open

Reflection map prefiltering improvements #331

vorg opened this issue Nov 14, 2022 · 5 comments
Labels
Milestone

Comments

@vorg
Copy link
Member

vorg commented Nov 14, 2022

Current implementation suffers from two major issues:
a) due to lack of multiple scattering metals get darker and they get rougher - solved by bumping reflection color based on roughness
b) bright spots cause fireflies due to insufficient filtering - solved by sampling different mipmap levels

Both are described here https://bruop.github.io/ibl/

@vorg
Copy link
Member Author

vorg commented Nov 14, 2022

First implementation in a branch is promising.

Before (see dark metals on the right and very pale transition to plastic going down left column)

before

Getting blurry faster, and bright metals. Matches reference from Satin

after

ezgif-3-4f5a327465

@dmnsgn dmnsgn added this to the 4.0.0 milestone Nov 14, 2022
@vorg
Copy link
Member Author

vorg commented Nov 14, 2022

The issue of sparkles persists

Screenshot 2022-11-14 at 09 25 50

and could be fixed by adding the following (from here and here) to prefilter-from-oct-map-atlas.frag.js#LL93

 if (NoL > 0.0) {
            // Based off https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch20.html
            // Typically you'd have the following:
            // float pdf = D_GGX(NoH, roughness) * NoH / (4.0 * VoH);
            // but since V = N => VoH == NoH
            float pdf = D_GGX(NoH, roughness) / 4.0 + 0.001;
            // Solid angle of current sample -- bigger for less likely samples
            float omegaS = 1.0 / (float(NUM_SAMPLES) * pdf);
            // Solid angle of texel
            float omegaP = 4.0 * PI / (6.0 * imgSize * imgSize);
            // Mip level is determined by the ratio of our sample's solid angle to a texel's solid angle
            float mipLevel = max(0.5 * log2(omegaS / omegaP), 0.0);
            prefilteredColor += textureCubeLod(s_source, L, mipLevel).rgb * NoL;
            totalWeight += NoL;
        }

but.. the code is for cubemaps... which could be converted to octahedral maps if we find solid angle formula for them and improve mipmapping. So we either implement Improve reflection probes seams #321 or switch to cubemaps that can be seamless and mipmapped in webgl2.

@dmnsgn
Copy link
Member

dmnsgn commented Nov 14, 2022

but.. the code is for cubemaps... which could be converted to octahedral maps if we find solid angle formula for them and improve mipmapping. So we either implement Improve reflection probes seams #321 or switch to cubemaps that can be seamless and mipmapped in webgl2.

Would that impact #7 ?

@vorg
Copy link
Member Author

vorg commented Nov 14, 2022

Possibly as having prefiltered cubemap would allow us to convert it to SPH like e.g. BabylonJS does.

@vorg
Copy link
Member Author

vorg commented Nov 14, 2022

If we move to cubemap mipmaps then we could reconsider atlas packing to the following as it would be half the size.

Do85vNyX0AEi9Cw

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants