Skip to content

Fix examples to avoid fading alpha#33450

Merged
Mugen87 merged 2 commits intomrdoob:devfrom
gkjohnson:example-alpha-fixes
Apr 23, 2026
Merged

Fix examples to avoid fading alpha#33450
Mugen87 merged 2 commits intomrdoob:devfrom
gkjohnson:example-alpha-fixes

Conversation

@gkjohnson
Copy link
Copy Markdown
Collaborator

@gkjohnson gkjohnson commented Apr 23, 2026

Related issue: #33437 (comment)

Description

Fixes some examples incorrectly attenuating alpha resulting in the CSS background showing through.

I'm still not sure what's going on with "webgpu_postprocessing_sobel" in the above comment, though.

@Mugen87
Copy link
Copy Markdown
Collaborator

Mugen87 commented Apr 23, 2026

SobelOperatorNode sets its alpha value to 1 here:

return vec4( vec3( G ), 1 );

@Mugen87 Mugen87 merged commit ae575fd into mrdoob:dev Apr 23, 2026
9 checks passed
@Mugen87 Mugen87 added this to the r185 milestone Apr 23, 2026
@gkjohnson gkjohnson deleted the example-alpha-fixes branch April 23, 2026 09:47
@gkjohnson
Copy link
Copy Markdown
Collaborator Author

The examples outputs linear-srgb values. Is that maybe a help?

I'm not sure what this means exactly. Does this mean that "ColorSpaceNode" that is modified in #33437 is not run? If so I'm not sure why the example would be changing at all?

@Mugen87
Copy link
Copy Markdown
Collaborator

Mugen87 commented Apr 23, 2026

@gkjohnson Sorry, I have updated my latest comments since they were wrong. The example does indeed output sRGB values. The tone mapping and color space conversion just happens before the sobel pass runs.

The DragonAttenuation.glb asset used in the Sobel demo has transparent materials.

https://threejs.org/examples/webgl_materials_physical_transmission_alpha

Does that explain why the demo is affected by #33437?

@gkjohnson
Copy link
Copy Markdown
Collaborator Author

If we disable the "sobel" effect in the demo we can see that the render background is transparent (css background set to red):

image

The tone mapping and color space conversion just happens before the sobel pass runs.

If the color space conversion node is running before the conversion pass this would explain it because the input to the sobel pass would then be a bit different at any partially transparent pixels (eg at the edges due to AA).

Why would the color space conversion be running before the sobel pass, though? The color space conversion should be happening before writing to the canvas in this case, no?

@Mugen87
Copy link
Copy Markdown
Collaborator

Mugen87 commented Apr 23, 2026

Why would the color space conversion be running before the sobel pass, though?

The are effects that require sRGB input. Sobel, FXAA or LUTs are some examples where this is the case.

@gkjohnson
Copy link
Copy Markdown
Collaborator Author

Sobel, FXAA or LUTs are some examples where this is the case.

I understand why FXAA and LUT may need this but I don't see why this would have to be the case for sobel. But either way how is this being indicated? And what should the solution be? We can:

  1. update the screenshot
  2. update the example to use a solid alpha=1 black background color.

The same question applies for any of the other relevant examples in #33437

@Mugen87
Copy link
Copy Markdown
Collaborator

Mugen87 commented Apr 23, 2026

update the example to use a solid alpha=1 black background color.

Let's do this. I think all examples should do that if they don't want to blend with the HTML background.

@Mugen87
Copy link
Copy Markdown
Collaborator

Mugen87 commented Apr 23, 2026

Personally, I think clearColor.alpha should be 1 by default. Not blending with the HTML background is the more common use case, imo.

That would mean the renderer parameter alpha should be false by default as well. Unfortunately, this will be a breaking change.

@gkjohnson
Copy link
Copy Markdown
Collaborator Author

I've made the changes in #33452

Personally, I think clearColor.alpha should be 1 by default. Not blending with the HTML background is the more common use case, imo.

I don't have a strong opinion about this. Users should be setting a clear color relevant for their use case either way.

--

Sobel, FXAA or LUTs are some examples where this is the case.

I understand why FXAA and LUT may need this but I don't see why this would have to be the case for sobel. But either way how is this being indicated?

Can you explain how it's being indicated per effect in render pipeline that an effect needs srgb or linear input? How is it that bloom can run before srgb conversion but sobel is running after?

@Mugen87
Copy link
Copy Markdown
Collaborator

Mugen87 commented Apr 23, 2026

We currently assume at one point in the render pipeline the "render output" must happen. That means tone mapping + color space conversion. The current system allows to define when this step should happen. This can be different depending on how you render pipeline is set up.

We know there can be theoretical use cases where you have e.g. three subsequent effects where the first on requires sRGB input, the second linear-srgb and third one sRGB again. This is currently not supported. The passes do not indicate what color space input they need. The user must know that from the documentation. E.g.

* Post processing node for applying FXAA. This node requires sRGB input

@gkjohnson
Copy link
Copy Markdown
Collaborator Author

gkjohnson commented Apr 23, 2026

We currently assume at one point in the render pipeline the "render output" must happen. That means tone mapping + color space conversion. The current system allows to define when this step should happen.

I understand that 😅 but how is it happening in this case. Is the renderOutput node responsible for this conversion and it's happening by default? So the user will have to pass a "linear" color space option and "no tonemapping" to disable the automatic conversion? And these settings have to be aligned with the outputColorTransform value?

renderPipeline.outputNode = sobel( renderOutput( scenePass ) );

@Mugen87
Copy link
Copy Markdown
Collaborator

Mugen87 commented Apr 23, 2026

Is the renderOutput node responsible for this conversion and it's happening by default?

Yes, It's renderOutput.

So the user will have to pass a "linear" color space option and "no tonemapping" to disable the automatic conversion?

The automatic conversion is disabled when RenderPipeline.outputColorTransform is set to false. The user must then do it manually with renderOutput(). The used color space and tone mapping of both options (automatic vs. manual) are extracted from the renderer settings.

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