There’s a blended decal shader on the wiki, which is meant for separate objects, so you can place an object in exactly the same plane as the object below, and the decal texture will always appear on top. The reason for this is because normally when you do that, you get what’s known as “z-fighting”, as the two textures flicker since the graphics card can’t resolve which one is supposed to be on top. So the decal shader basically says “always draw me on top!”
This is, incidentally, a perfectly valid way of doing bullet holes. You instantiate small squares with a bullet hole texture on them (using the decal shader), and stick them on the surface where you want a hole. One drawback is that it’s harder to do with rough surfaces, since the decals are supposed to lie directly on the surface beneath, so you’d have to read the level geometry instead of just using flat planes, unless you don’t mind the bullet holes “floating” a bit. Also, the more bullet holes, the slower it will go, unless you remove the older bullet holes eventually (you’ll notice lots of games do exactly that).
The other option is to draw the bullet holes directly into the texture; that way you could have an unlimited number and they would stick around forever with no performance penalty. The main drawback here is that your level would have to be uniquely textured (no tiling), which means vast amounts of VRAM unless you’ve got a small level. You could also use the secondary UV coordinates, which would mean no extra VRAM usage if you’re lightmapping your level anyway, so you just draw into the lightmap texture instead. The drawback here is that the lightmap is normally going to have a very low resolution, so it’s not appropriate for detailed decals, but would probably work OK for big blurry scorch marks.
The thing to do in a case like that is to instantiate a copy of the texture into the scene, and then do SetPixel() on the copy. That way the original won’t be touched.
Well, except the script I used for the scorch marks was kind of lame, in hindsight. I just updated that project so it works in 2.0–mostly just replacing the Blender files so they’ll load properly now, and also removing the script that turns off the particles (not necessary anymore, yay!). Plus I took the opportunity to update the scorchmark script so it’s a bit shorter and a lot more efficient. (The updated script should still work with 1.6.2, even though the project folder doesn’t.)
Oh, and that project doesn’t quite use any of the above techniques.
Instead, it projects a texture onto the ground below, which is nifty but only appropriate for flat(ish) surfaces. Otherwise it’s similar to writing to a secondary UV channel, with the main advantage being that you don’t actually need a secondary UV channel. The disadvantage being that it projects onto everything below, not just the ground, but you can work around that by using layers, and making the projector ignore certain layers.
That can be done with RaycastHit.textureCoord2, which gets the secondary UV set coordinates.
–Eric