Search Unity

using decals

Discussion in 'Scripting' started by ratamorph, Dec 20, 2007.

  1. ratamorph

    ratamorph

    Joined:
    Sep 2, 2007
    Posts:
    458
    I'm looking for a way to display an image on a texture given an arbitrary position, a lot like bullet holes. I'm thinking the decal shader is the way to go, but will this shader allow me to place x number of decals on any x,y position on the texture? How else can I do this?

    Thanks for all the help.
     
  2. AaronC

    AaronC

    Joined:
    Mar 6, 2006
    Posts:
    3,552
    The docs had a cool script for setpixel(), but be warned, those bullet holes are burned into your origional texture!

    And theres this thread, which rocks:

    http://forum.unity3d.com/viewtopic.php?t=5790&highlight=decal

    What I would like to know is how to do what Eric did but on a lightmapped shader, so it darkens both UVsets.(They are both Planar)
    AC
     
  3. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    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
     
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I haven't actually done all that much with secondary UV sets and lightmapping yet, so I did a little experimenting. Ignore what I said about doing scorch marks with the second UV set...obviously that's not gonna work too well, since when writing to the texture, the scorch mark might get divided up in various bits depending on the layout of the UVs. Duh. Still, it might be OK for bullet holes as you can see here. The size of the "hole" depends on the resolution of the lightmap texture, and can also vary from spot to spot depending on what the UV map is doing, so it's not an exact science by any means. Also the holes get erased if you change the lightmap texture, of course.

    There are a couple of generic scripts here that might be useful...an itty bitty one (CopyTexture) that instantiates a copy of the object's texture on startup, so doing SetPixel() stuff to it doesn't permanently alter the texture in your project. Also RaycastColor, which sets the color of the object by doing a raycast downwards a certain distance and seeing what the lightmap color is at that point. Thus the ball gets "shadowed" by the lightmap shadows. I assume this is more or less what games like Quake etc. do to achieve the "shadow" effects you see on your weapon when you're in areas darkened by the lightmap.

    --Eric
     

    Attached Files:

  5. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Oooo! Another pre-holiday gift from Santa Eric! Nicely done!
     
  6. AaronC

    AaronC

    Joined:
    Mar 6, 2006
    Posts:
    3,552
    What I might ask Santa for is a shader for doing decals (In unity 1.x) similar to the lightmapped shaders, but instead of blending the 2nd UV into the layer as transparent shadow, Having it on top as decal. So if you imagine UV 1 consisting of tilable bricks, and UV 2 consisting of different posters or billboards, you could stretch one shader to do a really large wall area.

    It looks like the "Decal 2UV's" shader might do something close but it too appears to be transparent (according to the wiki page). I might play with the shader and see if I can make the 2nd UV opaque. I've had good experiences editing shaders lately.

    Thanks again Eric! Will check that out soon
    AaronC
     
  7. AaronC

    AaronC

    Joined:
    Mar 6, 2006
    Posts:
    3,552
    Yup, thats what it does..

    The UT guys will put santa out of work one day..

    Thanks yet again guys, but for something you actually did a long time ago.

    Have an awesome break.

    AaronC
     

    Attached Files: