Skip to content

add note about sRGB conversion to renderer - #1755

Open
euclio wants to merge 1 commit into
linebender:mainfrom
euclio:srgb-note
Open

euclio wants to merge 1 commit into
linebender:mainfrom
euclio:srgb-note

Conversation

@euclio

@euclio euclio commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

This PR adds a helpful note to Renderer::render_to_texture about sRGB conversions to avoid washed out colors when rendering. I found this behavior surprising, and had to go down a big rabbit hole about color spaces to understand it.

@euclio
euclio marked this pull request as ready for review July 20, 2026 01:51
@DJMcNab

DJMcNab commented Jul 29, 2026

Copy link
Copy Markdown
Member

Welcome! We discussed this in the #office hours > Renderer 2026-07-29 meeting, and think that this kind of note is valuable. However, I think that the exact way that this is expressed is a little bit unclear - do you have a code example for what your proposed fix is?

Fwiw, in vello::utils, we fix this by using a non-Srgb Surface texture format. Is this for use cases involving embedding Vello in a different application? Is there perhaps some wgpu docs we could point at instead, to avoid growing ever-more-case-specific docs here.

@euclio

euclio commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Yes, using a non-Srgb surface texture format also works, and should be mentioned.

In my application, I'm using Vello to draw UI that is blitted on top of other renders, so I want the Vello pipeline to be able to handle any surface texture format.

My application code looks something like this:

const VELLO_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Rgba8Unorm;

impl VelloPipeline {
  /// `target_format` is the texture format of the view passed to `draw_ui`
  fn new(device: &wgpu::Device, target_format: wgpu::TextureFormat) -> Self {
    let vello_texture: wgpu::Texture = device.create_texture(&wgpu::TextureDescriptor {
      format: VELLO_FORMAT,
       // ...
    });

    let vello_texture_view = vello_texture.create_view(&wgpu::TextureViewDescriptor {
      format: target_format.is_srgb().then(|| VELLO_FORMAT.add_srgb_suffix()),
      usage: Some(wgpu::TextureUsages::TEXTURE_BINDING),
    });
  }

  fn draw_ui(&self, encoder: &mut wgpu::CommandEncoder, target: &wgpu::TextureView) {
     // blit `vello_texture_view` to `target`, perhaps through wgpu::util::TextureBlitter
  }

When I create the surface view texture in my windowing code, I use the first format returned in SurfaceCapabilities.formats, since that's the "preferred" format (and it tends to be Srgb). But I don't want to hard-code any specific texture format if I don't have to.

There are some wgpu docs on this topic but they're lower-level than is probably helpful for this method. The TextureFormat docs also mention that "Srgb" formats "specify a conversion". As a graphics noob, the part that was most confusing to me is that the Vello texture isn't "Srgb" but already has the "Srgb" conversion applied.

@DJMcNab

DJMcNab commented Aug 6, 2026

Copy link
Copy Markdown
Member

I suspect that just pointing to the that wgpu doc is probably the best approach. I don't really have the context in my head to even review anything else!

You might also be able to find someone else who could review this, but I'm not sure who the candidates would be currently...

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

Successfully merging this pull request may close these issues.

2 participants