bevyengine / bevyengine/bevy

Unexpected texture clears when using camera-driven rendering (minimal not working example included).

Open
#6,051 6 comments 0 reactions 0 assignees View on GitHub
A-Rendering C-Bug
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 16h
Merged PRs (30d)
171

Description

## Bevy version

0.8

## Bug Information

Here's the [minimal not working example](https://github.com/bzm3r/texture-clear-mnwe).

`bevy_pancam` is enabled, so you should be able to drag the camera around, but we suggest just maximizing the window upon startup, in order to see everything clearly.

The basic setup here is: there's a large texture (the **accumulation texture**). We render into small squares (**tile**) of the accumulation texture sequentially. The accumulation texture has [`ClearColorConfig::None`](https://docs.rs/bevy/latest/bevy/core_pipeline/clear_color/enum.ClearColorConfig.html#variant.None), which should in the background trigger a WGPU [`LoadOp::Load`](https://docs.rs/wgpu/0.13.0/wgpu/enum.LoadOp.html#variant.Load).

Every so often, we skip rendering a tile. The **problem** is that: when this skip occurs, the accumulation texture is cleared entirely.

A little more detail:

0) every tick, [we check to see](https://github.com/bzm3r/texture-clear-mnwe/blob/3ce626bbf9e47260a3d78e723d608cf4430e39e4/src/tiled_renderer.rs#L192) if an event to draw a tile has been received ([initially](https://github.com/bzm3r/texture-clear-mnwe/blob/3ce626bbf9e47260a3d78e723d608cf4430e39e4/src/main.rs#L409) we send one such event, to start off the process);

1) if we are asked to draw stuff into a tile: we render some rects [using bevy_prototype_lyon](https://github.com/bzm3r/texture-clear-mnwe/blob/3ce626bbf9e47260a3d78e723d608cf4430e39e4/src/tiled_renderer.rs#L80) by using a [camera targetting a 4096 x 4096 texture](https://github.com/bzm3r/texture-clear-mnwe/blob/3ce626bbf9e47260a3d78e723d608cf4430e39e4/src/main.rs#L113) (the [**hi res image**](https://github.com/bzm3r/texture-clear-mnwe/blob/3ce626bbf9e47260a3d78e723d608cf4430e39e4/src/main.rs#L79));

2) we take the 4096x4096 texture, and give it as a input (using Materials) to [another camera](https://github.com/bzm3r/texture-clear-mnwe/blob/3ce626bbf9e47260a3d78e723d608cf4430e39e4/src/main.rs#L183) which [uses a viewport to target into `TILE_SIZE x TILE_SIZE`](https://github.com/bzm3r/texture-clear-mnwe/blob/3ce626bbf9e47260a3d78e723d608cf4430e39e4/src/tiled_renderer.rs#L263) (where `TILE_SIZE = 64`) region of a large accumulation texture ([here some downscaling happens](https://github.com/bzm3r/texture-clear-mnwe/blob/3ce626bbf9e47260a3d78e723d608cf4430e39e4/src/tiled_renderer.rs#L315)); crucially, we [queue sending of a rendering complete signal from the render device](https://github.com/bzm3r/texture-clear-mnwe/blob/3ce626bbf9e47260a3d78e723d608cf4430e39e4/src/tiled_renderer.rs#L274)

3) [if a render complete signal was received](https://github.com/bzm3r/texture-clear-mnwe/blob/3ce626bbf9e47260a3d78e723d608cf4430e39e4/src/tiled_renderer.rs#L288) we set `is_active` on the cameras responsible for rendering [to `false`](https://github.com/bzm3r/texture-clear-mnwe/blob/3ce626bbf9e47260a3d78e723d608cf4430e39e4/src/tiled_renderer.rs#L281), and we [write a render complete event](https://github.com/bzm3r/texture-clear-mnwe/blob/3ce626bbf9e47260a3d78e723d608cf4430e39e4/src/tiled_renderer.rs#L302)

4) [we check to see](https://github.com/bzm3r/texture-clear-mnwe/blob/3ce626bbf9e47260a3d78e723d608cf4430e39e4/src/main.rs#L243) if a render complete event was written; if it was, we send the the next "draw a tile" event.

We used RenderDoc to see what is happening during a skip. It seems that an unnecessary texture clear is called. But we are not yet fully at home in RenderDoc, so perhaps are not getting as much info out of it as we might be able to.

We tried understanding the Bevy code to see where in the "lifecycle" of an `Image` the corresponding `Texture` might be cleared, but we found it very hard to trace the "lifecycle" of an `Image` and its corresponding `Texture` to figure this out.

We have been stumped by this for a while 😖

Any of the following would be welcome:

* ideas on *why* the texture clear is happening, or where it is happening?

* ideas on *what* we else we could try?

* suggestions on what we can do to make the minimal not-working example easier to work with?

* thoughts on whether you would like to see us upload RenderDoc captures?

Contributor guide

Open the contributing guide

Research direction

Start with the linked minimal not-working example, then read tiled_renderer.rs and the camera setup in main.rs, especially the tile viewport, render-complete handling, and ClearColorConfig::None path. Reproduce the skipped-tile case and inspect the render lifecycle with the existing RenderDoc evidence. Done means skipped tiles no longer clear the accumulation texture unexpectedly, with a regression test or reproducible verification if the project supports it.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
computer-graphics, game-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
32/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.