filament
filament copied to clipboard
Scissor not correct with dynamic resolution
I am seeing weird behaviour with setScissor when turning on dynamic resolution (on Android). It looks like the left/bottom positions are interpreted according to the full resolution. So as the resolution is lowered in successive frames, the left/bottom of the scissor rectangle moves towards the right and up. As soon as I switch dynamic resolution off and render a frame with full resolution, the left/bottom jump back to the correct position.
Do you have repro steps?
@pixelflinger As usual this is part of a larger project but I will try to reproduce on a filament sample. In the meantime, I did notice that it is not just an Android issue; it happens on iOS/Metal as well. But in short, the area shown by using a scissor is different depending on whether dynamic resolution is turned on or off. It looks like this is because the scissor coordinates are interpreted with respect to the full resolution even when drawing a lower-resolution frame.
Ok, I have managed to reproduce it with the sample-textured-object sample on Android, with the attached diff. I use a scissor
setScissor(400,400,800,800)
Dynamic resolution starts "on", and is then turned "off" after 200 iterations of the render loop. In order to make sure that dynamic resolution actually does something, I had to artificially slow down the rendering (by calling render(view) 100 times each frame), otherwise my mac is too fast and will happily do full resolution frames with or without dynamic resolution.
The result is in the attached video (shot from the emulator, but this happens on real hardware too). While dynamic resolution is "on", the part of the scene which is drawn is not the square set by the setScissor above. As soon as dynamic resolution is turned "off" (about 18 seconds into the video), the correct result is shown.
Hope this helps to pin it down.
One final note: while I of course do not do anything as silly as calling render(view) multiple times on the same view in my actual code, I do use multiple render(...) calls in the same frame, but with different views. I haven't yet tried to see if that is what causes the trouble, but I would expect this to be fine.
https://user-images.githubusercontent.com/5918606/188653836-b6dca8c8-c125-4e36-be72-c0c35ddd3c0e.mp4
Well, I think you're right anyways, when we set the scissor we just don't take the scaling into account. I think there are many other bugs with scissor. For instance I think it doesn't work with the guard bands. It was initially implemented just so that we could use ImGUI. I can't promise this will be fixed any time soon.
I understand, no problem. I may have a look myself. Is the current dynamic resolution available in the shaders at all?
What would be the preferred way to get the scale info into the backend? I guess it should end up in the PipelineState object that gets passed into the driver.draw call? Should RendererUtils::colorPass fish the scale out of the ColorPassConfig and feed it to the RenderPass which it creates? Or is there a better way?
(I can of course cook up an ugly hack that gets the scale to the driver somehow, and just works for my limited use case, but I'd rather do it properly if at all feasible).
Well I think scalling the scissor is not going to work well anyways, because it's an int value. So it's unclear how to round for example.
e.g. If you have 2 scissor regions at normal resolution that touch each other without overlap, they could end up overlapping once scalling down.
It's just not obvious to me how to do that scalling properly, even if you know it.
Ok, fair point. I was hoping to be able to use scissors to do things like showing two views on top of each other, with an A/B slider in the middle (so that you see the left-half of view A and the right-half of view B). That's easy with a scissor, but my code which uses viewport settings instead is quite messy (because you have to adjust the camera in that case). I would have been happy with a rounding of the scissor to the nearest upscaled pixel, but I can understand if you feel that that's a hack and this is not what scissors should be used for.