-
-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Post-Process example #5648
base: master
Are you sure you want to change the base?
Post-Process example #5648
Conversation
Where does all those 1087 lines of code comes from? |
Yes, thanks for pointing that, I completely missed the new feature of A-Frame to use importmap. Sorry for that, I've reduced the bloom.js to the bare minimum to work. |
That new importmap example exist since 2 days ago ;) I'm glad I did it so we can have a simpler example here without copying all the code. |
Didn't we agree from supermedium/three.js#20 to use |
Whatever yields 90fps with the simpler code and least amount of dependencies |
pmndrs does not work in VR at the moment. I have opened tickets there, but at the moment no one is working on it. |
Typo Co-authored-by: Noeri Huisman <[email protected]>
deleted useless tick function Co-authored-by: Noeri Huisman <[email protected]>
I merged THREE changes and updated A-Frame so should work on top of master. Can you put the examples under Thanks so much for all the effort |
examples/post-process/bloom.js
Outdated
this.scene = this.el.object3D; | ||
this.renderer = this.el.renderer; | ||
this.camera = this.el.camera; | ||
this.composer = new EffectComposer(this.renderer); |
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.
Instead of recreating EffectComposer
, RenderPass
and UnrealBloomPass
each update, they can be created once in init
and only updated here.
examples/post-process/bloom.js
Outdated
}, | ||
bind: function () { | ||
const render = this.renderer.render; | ||
const system = 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.
Nitpick: this isn't a system, probably better to name it self
.
examples/post-process/bloom.js
Outdated
* Unreal Bloom Effect | ||
* Implementation for A-Frame | ||
* Code modified from Akbartus's UnrealBloomPass.js | ||
* https://github.com/akbartus/A-Frame-Component-Postprocessing |
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.
Given that the source is MIT licensed, the original copyright and license notice should be included.
examples/post-process/index.html
Outdated
"imports": { | ||
"aframe": "../../dist/aframe-master.module.min.js", | ||
"three": "https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js", | ||
"three/addons/": "https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/" |
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 should be
"three": "../../../super-three-package/build/three.module.js",
"three/addons/": "../../../super-three-package/examples/jsm/",
like https://github.com/aframevr/aframe/blob/master/examples/boilerplate/importmap/index.html
so it uses the three version from node_modules.
examples/post-process/index.html
Outdated
shadow="type: pcfsoft; autoUpdate: true" | ||
background="color:black;" | ||
renderer="anisotropy:4; stencil:true; alpha:false; colorManagement:true; exposure:1.0;" | ||
bloomm="threshold: 1.0; strength: 0.6; radius: 1; exposure: 1.0"> |
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.
Does the example still work? there is two m here.
Wow, amazing work @mrxz ! Yes, as you were saying the effect seems a little bit cheaper than the one on this PR, but it is super acceptable and nice. Maybe two paths with different levels of quality / performance are the right way. And, I agree that we should merge and than iterate over it. |
Haven't tried in VR. Is the "more expensive" one noticeably better visually? If yes two paths is fine. If not maybe we can just have the cheaper one. |
The But it's actually possible to get closer while still (though barely) maintaining 90fps on Quest 2. See: https://thrilling-alkaline-headline.glitch.me/index2.html
But it becomes questionable how useful a post processing effect is that eats up practically all your rendering budget.
The biggest gains are in reducing the render targets used while rendering, but this is mostly caused by the internal implementation of the One thing that can be done is optimizing the car asset using gltf-transform, as it does cause more draw calls than needed. But that isn't directly related to the bloom effect, of course. |
I think your new iteration looks very good! Yes, it is very veery similar to the PR's one. |
How much of the rendering budget is used in Quest3? How much is reasonable? Any target we should aim at? |
Depends on too many factors to give a concrete answer on what is reasonable. In general I think users just want to "slap on bloom". In that sense the implementation in this PR is limiting for Quest 3. It pushes the GPU to the highest clock level (4) and GPU utilization is consistently >90%. You'll probably have a hard time adding much more to the scene, making it only really suitable for relatively small experiences. Although users could experiment with targetting 72fps and/or use viewport scaling (https://immersive-web.github.io/webxr/#dom-xrview-requestviewportscale). With https://thrilling-alkaline-headline.glitch.me/index2.html the Quest 3 remains at GPU level 2 in my testing. Though worth pointing out that due to the way it works the bloom effect isn't a fixed-cost and does actually scale with the overall scene complexity. But at the very least there is clearly headroom. It also depends on what you want from the bloom effect. The current demo scene is setup with a fairly large bloom effect. If someone only cares about a subtle glow around lights/neon-signage a cheaper blur method is probably good enough and less demanding. |
Thanks. We should probably limit to Quest3 and up then. People slapping bloom (without understanding the cost) representing 90% of post processing demand is the reason why I resisted. It’s good this PR is just an example. Some friction to use it but enables those that want to experiment. |
I agree, this PR is for opening the way to Post-Process in VR in A-Frame, implementation is not finished here and it is good to leave room for experimenting and improving. With this PR merged we can also push other repos to contribute, i.e. pmndrs/post-processing. At the moment it does not work in VR but yesterday I've managed to make it work, maybe I can open some discussions over there to have more tools to use. |
FYI Quest Browser 36.5 added support for dynamic viewport scaling so you could ask to render fewer pixels if you see the framerate dip. Does the current approach allow for dynamic resizing of render targets?
Simply activating post-processing will still cause all those flushes. |
I don't see how you could bring a bloom effect down into a single pass. You will need to perform a blur, which is going to require either ping-pong between two targets or consecutive downsampling and upsampling steps. Unless you do the full kernel per fragment, but that is prohibitively expensive. @cabanier Did you try this demo https://thrilling-alkaline-headline.glitch.me/index2.html? ovrgpuprofiler trace
|
yes, bloom still needs a separate pass. Looking at your trace, you can see that we bound to the swapchain texture, but then immediately switch: The second pass is likely rendering the scene (with no MSAA and only half the resolution?) and since it's so simple, it renders quickly. (My proposal to foveate any texture would likely make little difference in this case) Do you know what all these other small items are that are rendered each frame? if they don't change, maybe they can be cached. At the very end, there is an expensive pass which is likely unvoidable. I suspect that foveation would still help. That being said, this trace is looking a LOT better than the one I capture 2 days ago! |
@cabanier Thanks for you insights
Visually foveation is definitely still active. There are no draw/clear calls issued at this stage so that might explain why. Either way, after avoiding this switch it didn't really impact the trace much: ovrgpuprofiler trace
I was aware, just didn't invalidate it yet as Three.js doesn't expose a convenient way to do so.
These are the blurring passes. That's what I meant with not seeing how you could bring the bloom effect down to one pass. Currently 5 different blur radii are combined, so there's definitely some saving possible at the expense of image quality. But even if we'd only want a subtle short length bloom, you'd at the very least have something like "main render" + "horizontal blur pass" + "vertical blur pass" + "bloom pass". The only way I know to avoid this would be to do the full blur kernel for each pixel, but that can't possible be more performant. Though if there is some technique I'm missing, I'd love to know. Any reference to bloom implementations for Quest are also be appreciated.
This is indeed unavoidable, though a cheaper bloom based on a singular blur radius can still save almost 1 ms on this pass. Though obviously not sure how meaningful these time measurements are when the GPU level is at 2 (not fixed, just not seeing it jump up with this load). Foveation is already active at this point as mentioned above. When I disable the foveation the render time does indeed shoot up. Interestingly enough the output using
Your previous capture was essentially just the stock |
It's one of the things that will be fixed in the three.js redesign. As long as you clear the swapchain backed texture, you should still get foveation.
OK, since those passes are very fast, it doesn't look like a problem.
Yes, that is expected. Because of the out-of-process nature of the Chromium renderer, we can't use the system API calls that set up foveation so it's not recorded in the tool.
Great! The rendering of the scene itself would still benefit from foveation but we'll have to wait for that API to land. |
The main forward pass is the last one, which is using MSAA x4 as can be seen from the trace. No MSAA is used for the bloom input as it will get blurred anyway (blur is a great AA technique 😉) and resolving an HDR buffer still leaves aliasing artifacts around bright areas. So I don't see a reason to use MSAA there.
Indeed, looking forward to trying that out. Also |
@enzofrancescaHM this is pretty close. let me know if you need any help. all the back and forth can be overwhelming 🙂 |
@dmarcos well, don't worry, my commitment is still very high. I'm waiting for you to take decision on the right path. My opinion is that all the proposed modifications by @mrxz are not resolutive, touching only a small subset of the performance issue by lowering the number of passes or the resolution of them. There is, of course, something else to change to drastically raise FPS, but at the moment I think there is no one that has the needed commitment to work on that. This PR is here also for demonstrating that Post-Processing is indeed possible in VR via A-Frame, I suggest to use the current example and merge, maybe using the optimized car model, and leave room for improvements in the future, counting on the fact that who wants to work on it can start from a working example and not from scratch. |
No changes on the effect for now in this PR. Just need to improve example as per comments. |
@dmarcos ok, just to be sure, the improvements for the example are:
|
Yep. That's most of it. Thanks so much! looking forward to shipping this in 1.7.0 |
@dmarcos ok, done. |
toggleEffect(); | ||
}); | ||
|
||
leftHand.addEventListener('triggerup', (event) => { |
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.
This should go into a component effect-controls
<a-entity effect-controls="hand: right">
You can set inside:
this.el.setAttribute('meta-touch-controls', {hand: this.data.hand});
this.el.setAttribute('hand-tracking-controls', {hand: this.data.hand});
You don't need to treat each button separately. Can only listen to buttondown and pinchstarted
Almost done:
Thanks so much for sticking with it |
Description:
Minimal example to show the possibility of implementing Post-Processing in A-Frame.
NOTE: for Post-Processing to work also in VR mode, supermedium/three.js#20 must be implemented in supermedium three.
Changes proposed:
-index.html running a simple scene with simple geometries with and without emission
-bloom.js, a minimal implementation of Bloom effect