Repository navigation
libobs: Draw Darken sources over white so transparency keeps the background - #1406
Merged
Merged
Conversation
github-merge-queue
Bot
removed this pull request from the merge queue due to a conflict with the base branch
Oct 18, 2026
A source set to Darken blending draws black where it is transparent, and its alpha punches a hole through the scene, instead of leaving the background as it is (obsproject/obs-studio#6591, reported by SuslikV). test_darken_transparent puts an opaque light grey background on the program and over it a box that is transparent in its left half and an opaque darker grey in its right half, runs a raw video encoder on the program and compares the mean luma of each half with Darken and with Normal blending. Where the box is opaque it is darker than the background, so the two modes must agree. Fails 1 of 2: darken_keeps_background_where_transparent (left half luma 16, black, with Darken; 180 with Normal). The Normal control passes. Needs core video, so it runs under xvfb-run on Linux and skips without a display. Refs obs-rust#1404.
…ground Darken draws the item's texture with GS_BLEND_OP_MIN, and Direct3D and OpenGL ignore the blend factors for MIN and MAX: each channel becomes min(source, destination) on premultiplied colour. A transparent source pixel is (0, 0, 0, 0), so it always won: black in colour and 0 in alpha, which also cut a hole through the scene (obsproject/obs-studio#6591). Darken items always render through their item texture first. That texture is now cleared to opaque white instead of transparent black for them, so the source is drawn over white: a transparent pixel becomes white with alpha 1, and the minimum keeps the background's colour and alpha; an opaque pixel is the same as before. A partly transparent pixel is darkened as the source over white would be, which is the workaround users were given (export the image on white). Other blend modes are unchanged. test_darken_transparent: 2 of 2 (three runs). In the app, a half- transparent PNG set to Darken over a grey background now shows the background (209, 209, 209, alpha 1) in its transparent half instead of (0, 0, 0, 0). Fixes obs-rust#1404.
rdoupe
force-pushed
the
fix/darken-transparent
branch
from
October 18, 2026 16:08
4f105bc to
e34bbce
Compare
zackees
enabled auto-merge
October 18, 2026 16:13
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1404
What and why
A source set to Darken blending now leaves the background where it is transparent. Before, it drew black there and cut a hole in the scene's alpha (upstream obsproject/obs-studio#6591, reported by SuslikV; closed upstream as not planned, though the blend-mode author agreed it is a bug).
GS_BLEND_OP_MIN, and Direct3D and OpenGL ignore the blend factors for MIN and MAX: each channel becomesmin(source, destination)on premultiplied colour, and a transparent pixel (0, 0, 0, 0) always wins.item_texture_enabled(): non-default blending). That texture is now cleared to opaque white instead of transparent black for Darken items, so the source is drawn over white. A transparent pixel becomes white with alpha 1 and the minimum keeps the background's colour and alpha. An opaque pixel is the same as before. A partly transparent pixel is darkened as the source over white would be, which is the workaround users were given upstream and on the forum (re-export the image on white).Headless (private Xvfb, private D-Bus, fresh HOME), driven over obs-websocket: a light grey (209) colour source, a PNG over it whose left half is transparent and whose right half is opaque grey (128), scene screenshot:
RED → GREEN
test/cmocka: Add failing test for Darken over a transparent source.test_darken_transparentputs an opaque light grey background on the program and over it a box that is transparent in its left half and opaque darker grey in its right half, runs a raw video encoder on the program and compares each half's mean luma with Darken and with Normal (where the box is opaque it is darker than the background, so the two must agree). On master it fails 1 of 2:darken_keeps_background_where_transparent(left half luma 16 with Darken, 180 with Normal). Needs core video: runs under xvfb-run on Linux, skips without a display.libobs: Draw Darken sources over white so transparency keeps the background. 2 of 2, three runs;test_scaled_mix_alpha(Subtract) still passes. Full build (C libobs lane) and full ctest -j4 (private Xvfb, private D-Bus, fresh HOME, systemlibobs-openglmasked): 304/304; the only skipped case isopen_crashes_without_obs_core, as on master. The scene renderer is C in both libobs lanes.Checklist
master-W..., ratchets): noneAI note: Claude Code (Claude Opus 5.5) wrote the code, the test, the commit messages and this text under the submitter's direction, and ran the tests above on the submitter's machines.