So, I made a small attempt towards this.
It essentially does the following things:
- For each pixel in both the mask and the source:
- Apply a bluescreen filter to the mask pixel.
- Check if the mask alpha (from the bluescreen filter result) is not 0 (if it is (transparent), skip this iteration)
- Apply a color filter to the source pixel (for the player colour)
- Check if the colour alpha (from the colour filter) is not 0.
- If 0, then it’s transparent, so it counts as a masked pixel
- Else, it’s not transparent, so it counts as a visible pixel
- The proportion of visible to transparent pixels is the visibility factor.
Unfortunately, my demo isn’t quite perfect. I haven’t exposed the colour filter threshold values to the python API, so the player colour filter is probably not filtering very well, requiring some scaling to the visibility value. The shading of the player affects the filtering, which in turn affects the quality of the result. As the player is further from the camera, you will get more discrete intervals of visiblity.
The idea for the demo is good, though. If we could render separate passes for geometry and the player, we could create a geometry mask, which would then be used instead of the chromakey to remove the player from the render (step 1.3) And this would not be affected by shading.
The source code is included, using Boost::Python (which, for size reasons ~350 mb is not included).
You could write a custom filter that would probably run faster.
You could also do this in GLSL provided you pass in a texture. This would probably be faster as it can run on the GPU, depending upon how fast your GPU / CPU is, and how much work they’re both doing.
If you wrote this directly as a VideoTexture filter, it would also run faster, because one of the big overheads is likely the conversion in python -> boost.
This demo will only work in 64 bit Blender, windows. (Because that is what I have compiled for. Compiling for 32 bit requires me to rebuild BOOST, a real PITA). If you build it yourself, you can run on any platform.
NB, in this particular build & source code, my variables are the wrong way round - I’m filtering the visible pixels, rather than the masked ones. Meaning, I inverted the result (1 - visible) to account for it, in Python.
test_visibility.zip (224 KB)