WebGPU: RenderTarget is upside down
erikdubbelboer opened this issue · comments
The flipY
of pc.RenderTarget
is inverted for WebGPU.
Project that reproduces the bug: https://playcanvas.com/project/1176285/overview/webgpu-rendertarget-bug
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.
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.