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

SSAO delayed resize fix #4342

Merged
merged 11 commits into from
Jun 21, 2022
Merged

SSAO delayed resize fix #4342

merged 11 commits into from
Jun 21, 2022

Conversation

GSterbrant
Copy link
Contributor

Fixes #4239

Removed the resize timeouts. Added a general resize callback to the post effects such that they can handle resize.

Bloom needs such a callback to adapt it's internal targets (which should save performance when viewport is small).

Removed the resize timeout in the post effects queue.
Removed the resizecanvas listener from the SSAO effect.
@mvaligursky
Copy link
Contributor

Please add the handling of this for the bloom as well.

@@ -76,10 +72,6 @@ class PostEffectQueue {
*/
this.resizeLast = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this.resizeLast still needed?

@@ -404,6 +368,8 @@ class PostEffectQueue {

for (let i = 0, len = effects.length; i < len; i++) {
const fx = effects[i];
if (fx.effect.resize !== undefined)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (fx.effect.resize !== undefined)
if (fx.effect.resize)

BloomEffect.prototype.resize = function (target) {

var width, height;
if (target == null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (target == null) {
if (target === null) {

height = target.colorBuffer.height;
}

if (width == this.width && height == this.height)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (width == this.width && height == this.height)
if (width === this.width && height === this.height)

return;

if (this.targets) {
for (let i = 0; i < this.targets.length; i++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cannot use let in ES5, only var

var width = Math.ceil(this.device.width / this.device.maxPixelRatio / this.downscale);
var height = Math.ceil(this.device.height / this.device.maxPixelRatio / this.downscale);
var width, height;
if (target == null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (target == null) {
if (target === null) {

} else {
width = Math.ceil(target.colorBuffer.width / this.device.maxPixelRatio / this.downscale);
height = Math.ceil(target.colorBuffer.height / this.device.maxPixelRatio / this.downscale);
}

// If no change, skip resize
if (width == this.width && height == this.height)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you please use === here as well

Copy link
Contributor

@mvaligursky mvaligursky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

approving with some minor comments (please fix before the merge)

@GSterbrant GSterbrant merged commit abb890f into main Jun 21, 2022
@GSterbrant GSterbrant deleted the gsterbrant_ssao_resize_fix branch June 21, 2022 15:12
var width = Math.ceil(this.device.width / this.device.maxPixelRatio / this.downscale);
var height = Math.ceil(this.device.height / this.device.maxPixelRatio / this.downscale);
var width, height;
if (target === null) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GSterbrant If the target is undefined this method will error (happens in line 561).
I guess it should be checked if the target is actually defined and instead of passing null everywhere, just call the function without arguments?

@@ -577,11 +561,6 @@ SSAO.prototype.initialize = function () {
this.effect.resize();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion this resize should also happen if the effect is not enabled. Else we can have this situation:
User disables the effect -> User changes the downscale -> User enables the effect
Now we have the situation, that the render targets did not change in size although downscale was changed

@lucaheft
Copy link

lucaheft commented Jul 4, 2022

Also the new resize function should be added to the pc.PostEffect docs.
(https://developer.playcanvas.com/en/api/pc.PostEffect.html)

@mvaligursky
Copy link
Contributor

Perhaps the resize function should be called internally within the effect, and not from the engine (post-effect-queue). Inside the render call, the effect should check the sizes of its internal buffers vs the source / target buffer it has, and rescale those internal buffers as needed.

@GSterbrant
Copy link
Contributor Author

The effect itself doesn't know about the input target and has to defer to the graphics device for dimensions. The post effects queue knows about the input targets, and can therefore forward it to the effect when it's enabled/disabled.

Wouldn't it be better if we can avoid dealing with resize related code if we're not resizing?

@mvaligursky
Copy link
Contributor

the render function of the effect knows input and output
render: function (inputTarget, outputTarget, rect)

handling size compare is not very expensive, we handle it in few places like this. It's simpler for the user / creator of the effect.

if (this.colorRenderTarget?.width !== device.width || this.colorRenderTarget?.height !== device.height) {
self.releaseRenderTarget(this.colorRenderTarget);
this.colorRenderTarget = self.allocateRenderTarget(this.colorRenderTarget, device, this.colorFormat, false, true, false);

@mvaligursky
Copy link
Contributor

This way you also avoid to maintain / handle resizing while the effect / camera is disabled and similar. Each time you render, you make sure targets are the right size.

@lucaheft
Copy link

lucaheft commented Jul 4, 2022

I like that approach. This way the resizing can be handled on a per post-effect instance.
The post-effect-queue shouldnt handle it anyway, it's just a simple queue isn't it?

@lucaheft
Copy link

lucaheft commented Jul 4, 2022

Also what i noticed, in the post-effect-queue the width and height is calculated like this:

const desiredWidth = Math.floor(rect.z * this.app.graphicsDevice.width * this.renderTargetScale);
const desiredHeight = Math.floor(rect.w * this.app.graphicsDevice.height * this.renderTargetScale);

In the bloom post effect like this:
width = this.device.width;
height = this.device.height;

And in ssao like this:
width = Math.ceil(this.device.width / this.device.maxPixelRatio / this.downscale);
height = Math.ceil(this.device.height / this.device.maxPixelRatio / this.downscale);

Shouldnt those calculations all be the same? Except for the downscale in the ssao effect.

@GSterbrant
Copy link
Contributor Author

The issue of having to make this calculation at all is due to the fact that post effects are setup prior to knowing the input target. This will be fixed in the PR I am working on addressing these issues :).

The post effect queue calculates the size of the internal targets, and really the effects should just read those values. The device dimensions shouldn't be used at all.

@GSterbrant
Copy link
Contributor Author

GSterbrant commented Jul 4, 2022

I've made a PR here for these issues: #4397

@GSterbrant GSterbrant self-assigned this Jul 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SSAO / depth buffer rendering does not handle resize correctly
4 participants