Whitewash
The game designer at Flashbang Studios, Steve Swink, came up with an idea for a game mechanic where you are in a world of complete white and the only way to see around is by shooting paint on the environment. After he mocked it up in Unity, I took a pass it. My contribution to the project is how the paint is applied to the objects in the scene. In the original mock up, the paint would be a bunch of quads placed over the mesh. Every single splatter of paint was an additional draw call as well as an additional 4 vertices. With the amount of paint we want to spray on the environment this was simply unacceptable. So the new approach is to draw the splatter directly onto the objects’ textures. This technique has virtually no rendering overhead. However, it does have the downside of not being able to draw over UV seams.

September 15th, 2008 at 4:30 am
So this is super cool but the use of red is hilariously disturbing. I mean eventually it’s all over the walls and ceiling and it’s really gross. Haha! But the UV seem is an interesting problem…how much time would you need to solve that?
September 15th, 2008 at 10:06 am
@Ben
I have a couple ideas on how to solve the UV seam problem.I had a thought of using the second UV set to get information about the UV seams, but that still wouldn’t solve the problem of where there are two separate objects that intersect. The biggest thing would some smart construction of UVs and mesh placement by the artists.
September 15th, 2008 at 12:40 pm
Very nice!
It seems to me that there is no fundamental problem with the UV seams. It’s just that the logic of which texture to paint onto goes with whichever object first interrupts the raycast from the mouse’s position into the scene. Seems to me that you could adjust it to paint on more than texture.
For example, when painting just above the seam between the floor and the wall, imagine for a moment that the wall wasn’t there, and the floor continued a little further (to catch the ray.) The portion of the paint landing on the floor inside the room would be correct.
So this suggests a few approaches. 1) The walls making up the room could each be extended a little, up to the width of the brush. This might be what you meant by “smart construction [..] and mesh placement”. 2) Your raycast code could be rewritten to work mathematically rather than using the meshes. Detect the intersection using the math representation of each wall’s plane. This is a bit of work but frees the artists from having to do anything to their geometry. 3) Maybe you can get 90% of the way by casting some rays from the boundaries of your brush, instead of once from the brush center. Paint each distinct object you hit, compute the center of the brush relative to that object.
(At first I thought you would again need the plane’s equation for #3, to figure out where the brush center is relative to that object. But maybe you can cheat by having multiple versions of your brush. So if you cast the left-side ray and hit a distinct object, you would paint at that spot using a version of your brush whose origin was on the rightmost edge of the mask. But it’s been a while since I played with Unity’s texture painting; maybe I’m just blowing smoke here.)
Anyway, fun stuff to think about. Thanks for the demo!
September 15th, 2008 at 4:57 pm
@Matt
I had considered your first and third suggestions. I see potential problems with both.
Expanding the meshes will work fine for these specific meshes, but once you have a more complex (organic) mesh, you can’t simply expand the mesh where there’s a UV seam. That’s just asking for problems from the physics engine. Plus it would be difficult to parse which raycast hits we were interested in, since we have to shoot the raycast through the entire scene rather than simply stopping at the first collision. This could lead to false positives on objects that are actually behind other obstacles.
I’ve seriously considered doing the third suggestion, but I’m hesitant of doing four ray casts per fire. Just doesn’t seem like a wise idea, especially for a collider heavy scene.
I don’t think I’m fully understanding your second suggestion. I don’t see what additional information I’d be able to get out of handling the raycast myself rather than letting the physics engine handle it. The raycast already gives information about the texture coordinate and triangle at collision. Let me know if I’m missing something.
Very much appreciated your feedback.
September 16th, 2008 at 2:09 pm
I checked in the updated settings :).
September 19th, 2008 at 8:55 am
No, I don’t think you are missing much about my suggestions. :-)
Four raycasts instead of one is actually a very small price to pay, particularly since it’s probably occuring at most once per frame. I suppose if you had 100,000 colliders it might have an impact, but even there I think you may be overestimating the cost. Unity is doing a lot more work than that just to calculate what objects in the scene are in the view frustum, and to let walk around bumping into all those colliders.
It would be possible to only cast the extra rays some of the time. For example, only if your single ray hit near the edge of a wall would you bother checking for other walls. But really, it’s not worth the effort. Raycasts are fast and many Unity games use them heavily for things like, “can the enemy robot see the player?”, “did the shot hit anyone?” and “is the player in shadows?”.
Since you asked I’ll try to clarify my 2nd suggestion, even though it’s not the way to go. What happens is that a ray which narrowly misses the edge of a wall might still be close enough that part of the square texture you want to paint would overlap the wall. (This is precisely the case we are trying to catch, actually.) The built-in raycaster won’t tell you about near-misses, but you could do your own math to find them. Once you find the point in space near to the wall, you then have to do some math to work out the boundaries of the rectangle that overlap the wall, and from there get the texture coordinates.
#3 really is the way to go, I think. If I’d thought of it first I wouldn’t have bothered writing the other two. :-)
Regards,
Matt
September 19th, 2008 at 9:23 am
Here’s another way which is similar to #3 above but even easier. Instead of painting one big splat, paint 4 smaller, slightly overlapping splats, each centered on one of the 4 rays we talked about earlier. In the normal case all four splats hit the same wall, but at a seam some of the splats will hit the 2nd wall.
This should be pretty easy to code given the logic you’ve already written. The downside is a possible performance hit: you are redrawing some areas, and texture painting is not the fastest operation in Unity. Might not be significant as long as you call Apply on each effected texture after all 4 splats have been drawn, not after each splat. Apply is an expensive operation, don’t call it more than once per texture if you can avoid it.
Eventually might also want to design the 4 splats so that the outside bits have that nice extended spray look, but the bits that overlap with the other splats trail away quickly, to reduce the amount of overlap between the splats.
Hope I’m not boring you :-)
Looking forward to whatever else you come up with.
– Matt
September 19th, 2008 at 12:00 pm
@Matt
Agreed that using four raycasts will help and I may take that route if I continue to develop this. My thought for it is to splatter the same texture for each of the four raycasts, however each of the raycasts will act like one of the corners for the splattered texture.
Hope that makes sense. Hopefully I can find time to continue working on this tech.
Thanks
~Shawn
September 22nd, 2008 at 12:25 pm
Cool.
Not to let the tech details distract from the real innovation, which is the game mechanic of not seeing anything until you splat the walls. That seems pretty unique to me. I saw something slightly similar a long time ago in the Laurie Anderson “Puppet Motel” CD-ROM- there was a completely dark room, screen was black, no instructions to the player. By moving the mouse you projected a vertical bar of light across the room from left to right, which revealed something that you could interact with once you’d made out the shape.
As for how to use this in a game, maybe it’s a timed run through a maze and each burst of paint costs you 5 seconds… Or maybe the splats are made when you shoot some puffy enemies who are floating around. So you have to lure them to (unexplored) areas you want to splat before popping them.
> Hopefully I can find time to continue working on this tech.
Looking forward to it, or some completely new demo, however the mood takes you.
September 30th, 2008 at 8:17 am
http://iandallas.com/games/swan/
September 30th, 2008 at 10:48 am
this looks like a real good idea just needs to have a few evil twists to make it real fun.
like you could just start with one paint gun and with one color. put a few monsters around and make them white to so the player cant see them and needs to lure the monster back to a part of the level that has been painted.
but give the monsters AI so they wait in the color or could even change color.
and the player could have a ”paint bat” to hit walls with when they run out of paint. and different types of paint gun fast and slow or biger and smaller ”beams” of paint. lots of traps and pitfalls switches.
could have a monster that ”eats” paint and will wipe it off walls so you cant find your way.
its got a lot of potential i hope to see a grate game out of this.