-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
Fix specular envmap in deferred #11534
Conversation
@@ -80,9 +80,11 @@ fn pbr_input_from_deferred_gbuffer(frag_coord: vec4<f32>, gbuffer: vec4<u32>) -> | |||
let props = deferred_types::unpack_unorm3x4_plus_unorm_20_(gbuffer.b); | |||
// Bias to 0.5 since that's the value for almost all materials. | |||
pbr.material.reflectance = saturate(props.r - 0.03333333333); | |||
pbr.specular_occlusion = props.b; // use diffuse occlusion as specular occlusion because we can't fit both in the g-buffer on webgl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we just disable specular occlusion on webgl instead? I don't really know the impact of doing that tbh.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i figured that would be a closer approximation than not occluding specular at all. this was discussed quite extensively around the original specular occlusion PR, but if not occluding specular at all on webGL is preferred then I don't really mind changing it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really have an opinion personally, it was mostly out of curiosity. I guess this is better than nothing yeah.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather disable specular occlusion personally, and leave diffuse occlusion functional, if it's a choice between the two.
But also, does it have to be a choice? Can't the deferred function just calculate the specular occlusion based on the diffuse occlusion? Or is the needed data no longer available, idr.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I know diffuse occlusion will not be affected by this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this mean then?
use diffuse occlusion as specular occlusion because we can't fit both in the g-buffer on webgl
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It uses the diffuse occlusion value for specular occlusion, but the diffuse occlusion value is also used for diffuse occlusion. At least, that's my understanding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That understanding is correct. The needed data for specular occlusion calculation is not present here anymore, you need the non-multibounce raw SSAO output, and a couple other things that im pretty sure we do have, like NdotV type stuff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I get it now, the wording confused me 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's pretty debatable if it's even worth including occlusion in the deferred gbuffer in the first place. The gbuffer space is pretty precious, and baked AO is quite rare.
Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
Oh btw, did we document anywhere that specular occlusion doesn't work on webgl2, and it'll use diffuse instead? If not, please add that to the StandardMaterial docs. |
I dont see why it should be in standard material docs, but I could add it there. There's no specular_occlusion input, the occlusion_texture field only affects diffuse. This is an SSAO/PBR effect, maybe it can be mentioned on the SSAO docs. |
Ah right. Docs on either the PbrInput in the shader or in SSAO, or in deferred would be fine, up to you where you think it's best. I just think we should note this down somewhere. |
@JMS55 There shouldn't be any limitation keeping specular occlusion from working in webgl2 vs diffuse with the current impl. The current XeGTAO impl in bevy doesn't work in webgl2 (though it could), but that's a separate issue. |
Yeah it would just mean adding another g-buffer texture on webGL, which could hurt performance. I think that can be done in a follow up with its own perf testing to assess whether its worthwhile. The visual difference will not be that big and we're already monochromizing the diffuse occlusion for gbuffer's sake. |
I just realized this fix is wrong and the correct fix is much simpler, here's why:
this means that a correct fix would just be to initialize specular_occlusion to 1.0 when there's no SSAO. If SSAO is enabled, then we get proper specular occlusion. If its not, then we get spec envmap unoccluded (we have no data with which to occlude it with). |
I definitely don't think we should add another texture for baked occlusion. At some point though we may add a color attachment for depth to enable the features the read depth directly in webgl. But it's really important to keep the attachments of the deferred prepass as small as possible. And we really should be removing the normal attachment and copying to the normal prepass texture in a subsequent pass, and then consider if there's a way to further minimize the size of the motion vectors. Occlusion would usually be either real time, or part of baked light maps, so I don't see much value in it being part of the gbuffer at all and only included it because there was a bit of extra space and it meant I wasn't changing as much about the capabilities for the initial deferred PR. I think the moment there is something more worthwhile to put in the gbuffer we should probably ditch it altogether. Also our current form of specular occlusion is pretty poor imo and leads to a lot of both over and under occlusion in a lot of common situations, and a more appropriate solution would not involve having a specular occlusion channel in the gbuffer anyway. For forward materials, there shouldn't be anything keeping baked occlusion from working in webgl2. |
@rodolphito Oh, good catch regarding the default value! I hadn't taken a look at the code. The default for occlusion should definitely be 1.0 or vec3(1.0) depending on the context for the reasons you stated. |
I just tested the new fix, seems to be working. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah, that new fix makes a lot of sense
# Objective - Fixes bevyengine#11414 ## Solution - Add specular occlusion to g-buffer so PbrInput can be properly reconstructed for shading with a non-zero value allowing the spec envmap to be seen ![image](https://github.com/bevyengine/bevy/assets/11307157/84aa8312-7c06-4dc7-92da-5d94b54b133d) --------- Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
Objective
Solution