Cryptomatte: CryptoAux enum instead of a positional bool; GPU test for every display mode (#473)

crypto_aux_image_with takes CryptoAux::{ColorsAndMatte, MatteOnly}, and
CryptoAux::for_display holds the rule for which displays read the ID
colours. A new GPU test checks every display x Matte Only against the CPU,
so the GPU fails the test if the shader starts reading RGB in a mode that
skips it (checked by mutation: forcing MatteOnly fails display 0).
This commit is contained in:
Matej Kozlovský
2026-10-17 01:48:48 +02:00
parent 34d5f00af8
commit 0fbe76b2bf
3 changed files with 16 additions and 3 deletions
+3 -2
View File
@@ -280,8 +280,9 @@ fn cryptomatte(e: &mut Enc, ctx: &EffectCtx, b: GBuf, a: &AuxChannels) -> Option
// cores with the rank planes resolved once.
// The ID colours are only read by the Colors display; Matte, Preview and Matte Only need the
// matte alone.
let colors = pr.e("display") == 0 && !pr.b("matteOnly");
let img = effectcraft_effects::crypto_aux_image_with(a, &layer, &sel, colors);
// `tests_fx_depth::cryptomatte_every_display_matches_the_cpu` guards this against the shader.
let what = effectcraft_effects::CryptoAux::for_display(pr.e("display"), pr.b("matteOnly"));
let img = effectcraft_effects::crypto_aux_image_with(a, &layer, &sel, what);
let tex = e.g.upload_image(&img)?;
let plane = lookup(e, &b, a, &tex, [0.5, 0.5], [0.0; 4]);
let mut p = op(7);
+12
View File
@@ -251,6 +251,18 @@ fn ids_and_cryptomatte() {
case("ec.3d.cryptomatte", &[("selection", Value::Str("alpha".into())), ("matteOnly", on())]);
}
/// The GPU skips the ID colours for displays that do not read them
/// ([`effectcraft_effects::CryptoAux::for_display`]): every display × Matte Only must still match
/// the CPU effect, so a shader that starts reading RGB in another mode fails here.
#[test]
fn cryptomatte_every_display_matches_the_cpu() {
for display in 0..3 {
for matte_only in [false, true] {
case("ec.3d.cryptomatte", &[("selection", Value::Str("beta, delta".into())), ("display", e(display)), ("matteOnly", Value::Bool(matte_only))]);
}
}
}
#[test]
fn extractor() {
case("ec.3d.extractor", &[("red", Value::Str("Z".into())), ("green", Value::Str("UV.U".into())), ("whitePoint", n(1000.0))]);