Edited. As Alexis points out in the comments, I had this wrong at first. Thanks for the gentle nudge!
EitherCondition =
VAR MatchesColour =
CALCULATE (
COUNTROWS ( 'FactTable' ),
KEEPFILTERS ( TREATAS ( VALUES ( 'ColoursDisconnected'[Colour] ), 'Colours'[Colour] ) )
) > 0
VAR MatchesShape =
CALCULATE (
COUNTROWS ( 'FactTable' ),
KEEPFILTERS ( TREATAS ( VALUES ( 'ShapesDisconnected'[Shape] ), 'Shapes'[Shape] ) )
) > 0
RETURN
MatchesColour || MatchesShape
With no other details of your data model, I'm assuming a simple dimensional model with a 'Colours' dimension of unique colours and a 'Shapes' dimension of unique shapes, each connected in a 1:N relationship with a fact table named 'FactTable'. As Alexis pointed out in comments, to drive this behavior, we need to build disconnected tables to drive the slicers.
Thus we have slicers populated from disconnected tables, and we have the table visual created with the related dimensions.
The first VAR says whether there is any data in the fact based on diconnected colour context. The second does the same for shape. If either is true, we return TRUE.
You can filter your visual on [EitherCondition]=True to remove the other values. Or you could build from here into a more complex measure.
The key part is that filter context in DAX is always a logical AND situation. The only way to get logical ORs is to evaluate multiple expressions and come up with a way to combine them that works in your situation.
Here's the model diagram:

And the measure in action:
