Allow specifying intermediate textures for cameras.
Objective
Currently we only support Rgba8UnormSrgb and Rgba16Float as intermediate texture formats for the camera (chosen between by the is_hdr field on the camera struct).
This isn't ideal for low power devices where we might want to use Rg11b10Float instead of Rgba16Float for faster rendering while still supporting effects like bloom. Closes #13011.
Solution
TLDR:
- Add the
ViewTargetFormatenum which describes a subset of texture formats which can be used as render attachments. - Replace the
is_hdrfield with a field describing whatViewTargetFormatwe want to use for the intermediate texture. - Change most pipeline keys to take a target format they should render to.
[!TIP] Don't miss the detailed description of this PR that I collapsed because It's a wall of text.
I've replaced the is_hdr flag with a target_format field to let the user define what texture format the intermediate render passes should use.
Since not all texture formats can be render attachments, I've chosen to isolate a subset that I know can be supported. This subset is the enum ViewTargetFormat. I mostly pulled information from this table in the WebGpu working draft. The precise selection criteria are specified in a note comment in the enum definition. Because not all of these formats are supported by all GPUs I've also added a SupportedViewTargetFormats resource that the user can query to check if a given format is supported.
I've also changed several pipeline keys to contain a target format field instead of an is_hdr flag. This change makes up most of the LOC additions in this PR and is mostly noise.
Finally, I tried to figure out what the is_hdr flag implied other than changing the render target format. I've chosen to split the view target formats into clamped and unclamped. The clampedness(?) of a view target format is determined by whether their values are clamped to [0, 1] in the shader. For clamped formats, the code behaves as it would for situations where the is_hdr flag from the extracted view or pipeline key was set to false. Conversely, unclamped formats are handled as if is_hdr was true. I'm concerned this is the wrong distinction to make but I don't know enough about rendering to tell what the correct one should be.
I have questions about the bloom pipeline. Specifically, it's the use of BLOOM_TEXTURE_FORMAT. Before this PR the rendering flow would presumably feed a Rgba16Float formatted texture into the bloom downsampling pipeline which would output a Rg11b10Float formatted texture. Said Rg11b10Float would find its way into the final bloom upsampling pipeline which would output a Rgba16Float texture. My questions are, is it okay for the pipeline to be fed a Rg11b10Float texture from the start (as can happen with this PR), and what format should we use when Rg11b10Float is not supported?
Concerns
- [ ] Is clampedness the correct concept to use instead of HDR (See the details section or the comment bellow)
- [ ] How should we handle
BLOOM_TEXTURE_FORMAT(see details section)
Changelog
TODO
Migration Guide
TODO
One major thing that needs to be discussed. Should we be using the word unclamped in contexts where hdr had been used before.
To explain so you don't have to wade through the changes. The values of ViewTargetFormat are split into clamped and unclamped. Clamped formats are as the name implies, clamped to some range of values in the shader (currently [0, 1] for every clamped format we support). Conversely, unclamped formats can attain any floating point value (don't quote me on this, I have no idea how NaNs and infinities are handled). In this pr, view targets with unclamped formats are handled as we used to handle hdr view targets (bloom is supported and tonemapping happens as a separate step of the rendering pipeline) while view targets with clamped formats are handled as we would have handled non-hdr view targets.
Does this allow avoiding the RG11B10UFLOAT_RENDERABLE requirement by tonemapping into rgba8? That would be nice for me personally.
Does this allow avoiding the RG11B10UFLOAT_RENDERABLE requirement by tonemapping into rgba8? That would be nice for me personally.
I'm sorry, but I'm too out of my depth with this PR to answer your question. Most everything I know about Bevy rendering and rendering, in general, I learned while writing this PR. What I can tell you, though it probably won't help, is that the only place I found the engine using the Rg11b10 texture format was as the intermediate output format of the whole bloom pipeline. This hasn't changed.
Can you fix the conflicts? The PR direction looks overall good to me, but I'd prefer waiting on the conflicts being fixed before doing a full review.
Also, would it be possible to split this in 2 PRs? One that add the ViewTargetFormat and another that updates the pipeline to remove the is_hdr? That way the PR will be a bit easier to follow without all the noise.