- Home /
Real time vertex paint (or similar solution) possible?
Is it possible to draw onto textures in real time (while playing) and get a good result? This is something that has boggled my mind a bit lately. The thing is I would like to be able to do it for instance with a collisions hit point, preferably with a second texture layer on top of the underlaying layer(s).
This could for instance be used for scratching the paint job of a car inside a OnCollisionStay(). Is vertex paint the thing I'm looking for here or could perhaps another technique be more suited? Perhaps if Texture2D.SetPixels takes alpha procedurally from another texture?
By the looks of it the question is a bit vague, I was meant to ask how you would solve a task such as drawing procedurally onto a textured mesh in theory. :)
i Save, just so you know, this is completely possible technically. No problem at all. Indeed, they all but spell out how to do it just here on the ordinary manual page... http://unity3d.com/support/documentation/ScriptReference/RaycastHit-textureCoord.html
Of course, regarding the actual "beautiful and amazing textures" you are suggesting in your image: obviously, it would be incredibly hard to program such a beautiful, complex texture.
If you were working at Adobe and you were tasked with program$$anonymous$$g that "look" for the next version of Photoshop, you would be busy for awhile.
But just purely in terms of accessing the Texture (the image that makes up the skin of your object in the scene) it's actually very surprisingly easy .. there is no performance problem whatsoever .. go for it.
Answer by DaveA · May 27, 2011 at 12:03 AM
You can use SetPixels (or SetPixel), which do take alpha (part of Color). If it's freehand drawing you want, this is probably it. I'm guessing using a raycast from a screen-to-world conversion to get the hit point and texture coordinates.
If you're wanting to put scratches per se on stuff, like also bullet holes etc, it's probably 'decals' you want.
Thanks DaveA, it sounds like that could work. The scratching would be on a few specific objects, for instance a couple of cars in a race. It sure sounds complicated to find a screen-to-world point onto a texture depending on a mesh in the world-coordinates - a task for the future coder of me I suppose.
Answer by Eric5h5 · May 27, 2011 at 12:35 AM
The problem with doing this is that you have to upload the texture whenever you make any changes, by using Apply(). The entire texture has to be uploaded even if you just change one pixel, so using Apply() with a large texture can cause a slight but visible hiccup in the framerate. It's also somewhat memory-intensive, since you have to read the texture into a Color[] array, which uses 16 bytes per pixel (4 floats).
Thanks, that sounds very intense. How about having a texture in two layers on the mesh and just alpha-scratch the top layer, would that make any difference? (a bit confused on how SetPixels work)
I believe the point of Eric's post is simply:
you must (of course) only update your work at the end of doing a batch of work. For example, say your "scratch" modifies, oh, 550 pixels.
Of course, obviously, as good program$$anonymous$$g practice you would only run Apply, at the end of the run of changing 550 pixels. If, bizarrely, you ran Apply after each pixel, obviously it would slow down!
What you say about two layers is not relevant or workable here - you simply happily modify the object's Texture ... it's no problem!
Don't forget too there are other completely different options to add scratches to an object, which may be better for you.
(1) Adding a PROJECTOR - check it out in unity docs. Incredibly simple and effective. (You can't add too many for performance reasons.) This probably gives you the best look, after all it's a calculated projector (like projecting a slide at the object).
(2) Adding DECALS .. incredibly simple. this is how kids normally program "blood splats" these days
(3) An interesting approach is to add another whole mesh, "another object," that shows all the scratches, skid marks, or whatever in the scene. Unity's Example Programmers like doing this and you'll see it in some of the example projects they provide