I’m looking for ideas on how to handle the following. I’d like to accumulate into a texture. This would in effect make some marks/decals permanent by re-rendering the texture with the additional marks on top, then turning that into the new, base texture.
Perhaps this might work by rendering to texture, using the same texture as both the destination of the render and the background of the render. Or if this is unsafe, perhaps I could copy the results of the render back into a 2nd texture which is being used as the background of the render-to-texture scene.
Or I suppose I could manipulate the texture image directly somehow (the “rendering” is basically drawing lines and decals onto the original texture; I don’t need any lighting or anything like that.)
You could just modify the pixels of the original texture. That is probably the most robust, fastest and easiest way. Wait just a tiny bit for Unity 1.6, that will have some useful functionality exactly for this purpose (in raycasting and texture script API).
“Wait for Unity 1.6” : That sounds perfect. And if it’s out in the next two weeks, great. But this is for the 3DU contest so time is short. I’ll work on other tasks for the next week or two, and keep my fingers crossed.
“Create a plane slightly above the surface” : that might work for a while. But the player will constantly be adding to the mess throughout the game, and I don’t know how long a single game will last yet. So I’m predicting there would be thousands or tens of thousands of polygons by the end.
Maybe I should look into using direct OpenGL calls?
Don’t bother about direct OpenGL calls. If you want to go that route, build a Mesh and add to that - then you get a bunch of HW platform- specific optimizations.
With mesh you can end up with lots of polygons. The usual trick is to kill the old decals (fade them out, etc.) to keep the total number under control. You still want to use the mesh interface in Unity for this; will be much better than direct GL calls.
With textures you have to uniquely texture all your level (can’t tile or reuse textures). Otherwise a decal-splat in one texture place will appear in the other place as well! In Unity 1.5.1 you can already do the texture decals using GetPixel and SetPixel on Texture2D class; in 1.6 there will be faster and better functions to deal with blocks of pixels at once.
In this case, I can’t fade out old marks. For the purposes of this discussion, imagine that it’s a paint program. There is only a single rectangular area where this “painting” can take place, which simplifies things.
It’s a good technique if your game really centers around a lot of decals. The drawback of the method however is:
You need unique uv coordinates for all objects in your world, thus you can’t tile textures. Otherwise the applied decal will appear in other locations when painting too.
Your textures can’t be stored as dxt compressed, because you can’t change a dxt compressed texture at runtime for performance reasons.
That said, it looks really cool, being able to live brush an entire level and all changes can just stay forever without any performance overhead.
Painting into the normal map also works very well.
If you just want to use some decals here and there, i’d recommend simply creating small polygonal planes where you hit the surface. Then you don’t need to worry about keeping your uv’s unique. Usually you would put all decals in a single mesh, and have a maximum number of decals, fading out old ones after a while.
The script that does the paint brushing is contained in the Procedural example project folder. You can put in arbitrary brush textures, with alpha maps for fading in the brush.
It’s really rather uncanny how OTEE delivered this feature in version 1.6 just as I started to develop this game (in 31 days or less!) It’s practically tailor-made for me.
You will either laugh at the coincidence when you see how the game works, or think that I got the game idea from the feature. But in fact I jotted the idea down many years ago, and was reminded of it by that “splatter” demo someone put up recently. One way or another I was going to make it, but you’ve just made my job a lot easier. Thanks!
Had a bit of a panic when I found that my application has some kind of memory leak, relating to the code that paints on the textures.
I believe a bug is actually present in the original texture paint example I downloaded from OTEE. If you run Activity Monitor and run the example Paint Texture scene as a built app, you will see the memory usage increase very quickly when you hold down the mouse button.
Something to do with the instantiatedTextures array, because when I refactored my code to remove that logic, the leak went away. Without looking into it any further, I think the script is cloning the destination texture every time instead just once. (Not sure why garbage collection doesn’t kick in, but like I said, I stopped investigating once I found a workaround.)
Just thought I’d let you know. The example scene you supplied has been a HUGE timesaver for me; this little hiccup didn’t cost me much time.
Would you mind sharing your solution? I low the PaintDecal script, but after just a few clicks, every subsequent decal takes longer and longer to compute.