How can I let players "scrape away" one texture to reveal another?

In this game I’m making, I want my players to be able to remove rust from an object based on collisions from another object such as a wire brush. Since it’s a VR game, performance is key.

I’ve been having a hard time getting on the right track; I think I’m not asking the right questions. The closest I’ve gotten was a video about making a scratch-off lotto ticket. Someone in the comments to that video says:

Good Idea. But, this isn’t practical for any real world apps. It instantiates too many gameobjects. There are better more efficient ways of achieving this effect using shaders or render texture.

They don’t really expand on that further, but I did do a little more searching to see how I might do this using shaders. I found this video about using replacement shaders, but I’m still not sure if that’s the right track. I don’t know If something like that is the smartest way to do it.

I’m basically a complete noob when it comes to shaders and textures so this is new territory for me. I apologize if this is a duplicate question, I’ve tried searching but haven’t found anything quite like what I’m looking for. Please let me know if there’s anything I can explain further, and any help that gets me pointed in the right direction would be greatly appreciated.

I agree that the most performant implementations will involve custom shaders, but there are still many ways to do it, and it won’t be easy if you are completely new to shaders.
The video you showed includes many basics about shaders that are good to know, but you won’t need to use actual replacement shaders.

In most shader based solutions you will probably want to have a untouched and a scratched-off version of you texture as well. Next, you need to blit your untouched texture version into a rendertexture. This is the only kind of texture, your shaders can actually write to.
Then, you need to locally update the rendertexture with the contents of the scratched off version where the mouse touches the object.

To do that you can create your own camera that renders into the rendertexture. It should be set to not clear each frame and it should be disabled, so you can make it render manually only when you need to update the texture (when you click/hold mouse down on the object). In this case you cane e.g. render screen-space textured circles into it, which overwrite the contents of the rendertexture with the scratched-off version.

I personally would just use compute shaders instead if your target platforms all supports them.
These are just programs that are executed in parallel on the GPU, without all the other rendering overhead involved, so they might also be easier to understand for you. They can also read textures and write to render textures, so you can give them a “stamp” shape texture and an update location (e.g. in texel coordinates) and dispatch it to update the rendertexture with the contents of the scratched-off texture.

The CPU-based solution that instantiates masks for each click comes with a drawing overhead for each click in each frame. When you just update the texture on each click instead, you only have this overhead once per click and the rendering performance is untouched.

You could of course also update the texture on the CPU, but that will probably not be a viable solution, depending on your texture size, not just because the CPU is not as highly parallelized as the GPU, but mostly because you would need to copy the texture from CPU RAM to GPU RAM afterwards in order to render it, and the memory bus between CPU und GPU is very limited and you should avoid updating stuff this way each frame at all cost.