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

WebGPU: RenderTarget is upside down #6334

Open
erikdubbelboer opened this issue May 2, 2024 · 1 comment
Open

WebGPU: RenderTarget is upside down #6334

erikdubbelboer opened this issue May 2, 2024 · 1 comment

Comments

@erikdubbelboer
Copy link
Contributor

The flipY of pc.RenderTarget is inverted for WebGPU.

Project that reproduces the bug: https://playcanvas.com/project/1176285/overview/webgpu-rendertarget-bug

WebGL:
Screenshot 2024-05-02 at 09 46 54

WebGPU:
Screenshot 2024-05-02 at 09 47 01

Script used to generate the image:

var Render = pc.createScript('render');

Render.prototype.initialize = function () {
    const device = this.app.graphicsDevice;

    this.colorBuffer = new pc.Texture(device, {
        width: 400,
        height: 400,
        format: pc.PIXELFORMAT_R8_G8_B8_A8,
        mipmaps: true,
        anisotropy: 1,
        minFilter: pc.FILTER_LINEAR_MIPMAP_NEAREST,
        magFilter: pc.FILTER_LINEAR,
        addressU: pc.ADDRESS_CLAMP_TO_EDGE,
        addressV: pc.ADDRESS_CLAMP_TO_EDGE,
        addressW: pc.ADDRESS_CLAMP_TO_EDGE,
    });

    const renderTarget = new pc.RenderTarget(device, this.colorBuffer, {
        depth: true,
        flipY: true, // Bug can be fixed using !device.isWebGPU
        samples: 1,
    });

    this.camera = this.app.root.findByName('Camera2').camera;

    this.camera.renderTarget = renderTarget;

    this.frameCounter = 0;
};

Render.prototype.update = function () {
    this.frameCounter++;

    // Wait a couple of frames to do this, doing it right away will fail.
    if (this.frameCounter == 10) {
        // This line isn't needed on WebGL, but on WebGPU causes:
        // Texture (unlabeled 400x400 px, TextureFormat::RGBA8Unorm)] usage (TextureUsage::(TextureBinding|RenderAttachment)) includes writable usage and another usage in the same synchronization scope.
        this.camera.renderTarget = null;

        this.entity.element.texture = this.colorBuffer;
    }
};

There is a simple fix to set flipY to !device.isWebGPU, but it's probably better if this gets fixed.

As you can see in the script another minor issue is that the renderTarget can't be in use by a camera at the same time as being used as a texture in WebGPU, with WebGL this is fine. I understand this is not something that can be fixed, but it's maybe nice to have documented somewhere if people search for this error.

@mvaligursky
Copy link
Contributor

Yep, thanks, I'm aware of this, and have tried to fix it, but do not have a generic solution yet - there are many parts to it.

As you said, there is this workaround currently: set flipY to !device.isWebGPU but this depends on what gets rendered to the target. If forward renderer renders to it, the flip is internally handled by the adjusted projection matrix as well, but when custom shaders are used, this is different. Extra complication comes with cubemaps too.

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

No branches or pull requests

2 participants