What about only clear the region that you don't want residual goop using stencil buffer or similar tricks?
Oooh, thank you for making me Google "stencil buffer", that sounds like it could be really useful!
So someone on the ShaderLab forums suggested using a blending mode of "Blend SrcAlpha OneMinusSrcAlpha, OneMinusDstColor One", which makes the individual color values come through, but blends the alpha channel additively. This would allow me to have theoretically infinite colors of goops, and while that's not within the scope of this project it sounds like the better way to do things. Plus since Alpha isn't limited to displaying a specific color, I can overlap colors without having their RGBA values combine into other unintended colors.
Unfortunately, we're still blending colors together though, so I need to posterize the splats into one of the four applicable colors. I check which color each pixel is closest to in color, and then snap it to that color.
Looking good!
But now how do I shade, highlight, and outline my splats? Beforehand, my sampler2D's were separated into 4 distinguishable channels. In order to check surrounding pixel positions to determine whether it should be shaded and how, I now need to calculate and posterize the color of those surrounding pixels first for stuff like
if(pixelColorAbove != myPixelColor) {
myPixelColor = highlightPixelColor
}
Which means that I'm checking 20 neighboring pixels...for every pixel... Computers are fast so it keeps up on my desktop, but it lags a bit on my laptop.
...be better than me. Don't do this.
So obviously there's gotta be a better way to do this. It'd be great if I could do a first pass where I posterize everything into those four initial colors, and a second pass where I shade, highlight, and outline, cause then for every pixel I'm not calculating 20 surrounding pixel values, I'm just calculating one. I need to setup a second Tex2D that's written with the values of that posterization, and then use that to calculate all that other junk, but Google hasn't been cooperative in helping me figure that out, so let me know if you know how to do this! For each pixel I'm calculating I'm also doing tex2D (AliveSplats, UV ) + tex2D (DeadSplats, UV), and it'd be more efficient if I just combined the textures first and called tex2D() just once, right? Another thing I'm not sure on how to do :/
Instead of blending, I'd use a shader that picks the max channel before thresholding, and uses that as the color. Then two splats near each other will form a neat dividing line, with the same curving that metaball outlines have.
Unfortunately if you want newer splats overwriting older ones, I think you will need a texture that is never cleared.
You're absolutely right! Creating a camera that never clears specifically for "dead" splats was the answer
So then I had two materials being rendered, one for "alive" splats (those that are airborne and shouldn't streak across the screen), and one for "dead" splats, that are written to a camera that's never being cleared. This is great! I don't have to do any memory management too because all the particles die within a second or two after throwing the goop, and their resulting splats live on!
But there's another problem, alive splats are all laid on top of dead splats, which
works, but it sort of breaks the metaball magic I have going on when moving particles are overlaid on top of still splats. So instead of having two shaders/materials, I now combine the color values from both the alive and dead RenderTextures.
AND IT LOOKS FANTASTIC!!! Both behaviors combine seamlessly in a single pass!
This looks even better at 60fps but LICECAP only gives me .gif's at like 15 or so
Thank you all SO MUCH for helping me! Let me know if you know how to do those two optimizations I mentioned earlier or anything else like that!