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
+1 -1
View File
@@ -110,7 +110,7 @@ pub use time_fx::{PixelMotion, TimewarpPlan, TwStep, pmb_plan, posterized_time,
// effectcraft-gpu fx_tone.
pub use ocio::color_stabilizer_maps;
// GPU effects, part B (3D Channel, Immersive Video, colour management, simulation render passes).
pub use channel3d::{CRYPTO_LAYERS, crypto_aux_image, crypto_aux_image_with, id_color, selection_hashes};
pub use channel3d::{CRYPTO_LAYERS, CryptoAux, crypto_aux_image, crypto_aux_image_with, id_color, selection_hashes};
pub use ocio::{ColorOp, Straight, Tf, color_program};
pub use sim::{Acc, Blob, Bubble, Post, Shape, Sprite, SpritePlan, Tint, bubble_list, drizzle_drops, mercury_blobs, sprite_plan};
pub use sim2::{
+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))]);