Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

Advanced search

1110051 Posts in 46257 Topics- by 37869 Members - Latest Member: cvl4317

April 18, 2015, 12:47:20 pm
  Show Posts
Pages: [1] 2 3 ... 16
1  Feedback / DevLogs / Re: ◁ DO NOT CROSS ▷ on: April 12, 2015, 01:57:56 am
Wow! Love the concept and the art. Your first-person view looks especially great.
2  Feedback / DevLogs / Re: Return of the Obra Dinn [Playable Build] on: April 01, 2015, 02:41:14 am
what I was wondering: do you have night and day-scenes? does the sun position change in your flash-backs? If I recall correctly you are not always jumping back to the same day/time. the last composed image would have to be night, but the shadows are strong. I hope the moon is up Smiley

The moon is up, but yeah I just now notice that the screenshots seem weird with the bright light and black sky when the moon is to your back. It feels ok when you're in the game when you can see a bit of the moon light source though.

Are you changing the mesh geometry each frame? That's the only way you'd be sending a lot of stuff to the GPU. Mesh data resides on the GPU's memory after it's allocated by the driver. I'd say it's likely the slowdown was because of Unity dynamic batching breaking down due to your multi-pass shader, resulting in excessive draw calls.

Except for a few small objects, all meshes are static and marked for static batching. There's not much room for dynamic batching to help. I render each pass with Camera.RenderWithShader, not as in-shader "Pass"es. I don't know even know how to do it in-shader with a render target switch between passes.

Also, the old sectioning pass used very fast forward rendering and the old lighting/sectioning pass used deferred. The new single pass is just deferred. So there might've been room for multipass optimizations, but it's hard to make guarantees about Unity's batching and it'd never be as fast as a single pass.
3  Feedback / DevLogs / Re: Return of the Obra Dinn [Playable Build] on: March 28, 2015, 07:54:54 pm

Working on the lower decks, some performance problems have been building up for awhile now. Even though the game's resolution is super low and there's no obviously fancy surface shaders going on, the geometry/object count is pretty high. Normally that wouldn't be a problem but since the 1-bit rendering technique requires two passes, sending all the geometry to the GPU twice eats up a lot of frame time. Yesterday I decided to sit down and see if I could get all the rendering done in a single pass (plus post-processing). 

The Old Way

The original technique required rendering the scene in two passes:

Scene Pass 1: Sectioning 

The sectioning pass just draws the vertex colors, which have been pre-processed to define areas that should be separated by edges. Wireframe lines are later drawn along these edges in post. 

Old method: Sectioning pass

     RED = Tool-generated random hash (lower bits)
     GREEN  = Manually-set adjustment color
     BLUE = Tool-generated random hash (upper bits)
     ALPHA = unused

Scene Pass 2: Lighting/Texturing

Lighting/texturing runs the full Unity SurfaceShader pipeline to generate lightmaps + dynamic light + textures. Dithering and other logic is applied to these results in post.

Old method: Lighting/texturing pass

     RED = Light value
     GREEN = Markup value (0: normal, 0.5: ordered dithering, 1:dust)
     BLUE = Texture value
     ALPHA = unused

Post-processing Combiner

These scene passes are written to two render textures which are then combined in a post process to make the final buffer. Having the light and texture in separate channels from the lighting/texturing buffer enables me to adjust their gradient ramps separately, which I use to make the hard shadows and blown-out textures that help with legibility.

The final post-processed output, 30fps

Separating the two passes like this makes sense for a couple reasons:

  1. Easy to visualize the two main features of the rendering style: wireframe lines and dithered 1-bit surfaces
  2. Two 32-bit RGBA buffers gives plenty of space for the data.

Both of those reasons aren't worth the framerate hit though. Unity's not very good at reusing scene data for subsequent passes, so even when the sectioning pass runs at +100fps, sending all the geometry twice bogs things down too much.


So the goal was to combine the two scene passes into one with the hope that performance improves on lower end video cards. That last bit is important because it precludes me from using MRT. For a single pass, everything has to fit in 32-bits.

One particular complication is that Unity's SurfaceShaders by default don't allow writing to the alpha channel, so you're effectively limited to just 24-bits in an RGBA buffer. I tried to be happy with that for a long time before finally tracking down a fix, which just became possible in Unity 5.

The problem. Alpha being "helped" to 1 for all surface shaders.

You can't easily edit the generated code directly, but you can redefine the offending macro in your own code, which is thankfully included after UnityCG.cginc:

The fix requires undefining the macro in your own surface shaders

With that, you have use of the full 32-bits and can write anything to the alpha as long as it's non-zero.

Single Scene Pass

So now I just had to pack 48 bits from the two separate passes into 32 bits for the single scene pass. The basic idea was to chop off the lower 8 bits of the sectioning hash (leaving 16 bits), reduce the lighting/texturing output to a single 8-bit channel, and use the alpha as a markup value to specify which "pass" the RGB values were coming from. Because the final output is dithered 1-bit, very few bits are actually required for the lighting/texturing. The result:



I was also able to use Unity's shader Queue tags to control draw order: set the sky shader to "Queue = Background" and the dust shader to "Queue = Transparent". 

Post-processing Combiner

The post-processing step now just has to do the edge detection (with 2 channels instead of 3), the darkness check (to invert wireframe lines in darkness), the dithering (bluenoise or ordered based on the alpha bits), and the dust inversion. There is some extra cost to doing more of the lighting/texturing combination in the scene shader instead of the post processing shader. But the final output looks identical to the old two-pass method, and it runs significantly faster.

Single scene pass, 60fps

Optimizing Early

There's always a danger in doing optimizations like this before the game content is mostly done. Now that I have an extra 30fps to work with there's a good chance I'll paint myself back in to poor performance. A common trick for smarter programmers is to keep a few secret optimizations in their pocket until the very end. If you optimize too early, the artists will just fill up the scene again and you'll be in a spot where it's much harder to get in framerate. I'll have to rely on self-discipline instead.

I am glad this worked out ok though. There's a (justified) perception that a 640x360 1-bit game should not have framerate problems on any machine. There's a lot going on behind the scenes that makes the rendering more intensive than it looks initially, but I'd rather match the perception than make excuses.
4  Feedback / DevLogs / Re: Return of the Obra Dinn [Playable Build] on: March 15, 2015, 09:02:06 pm
[...]Out of curiosity, have you tried talking to a historian about the game? I'm sure there must be some out there willing to help...[...]

I've thought about it off and on. Actually it's a great idea that I'll probably follow up on a little later. If Panurge isn't careful I might hit him up for a few things.

Have you read the Master & Commander series of historical fiction novels? Apart from being super reading they are also set in the same time period & go into lots of carefully-researched detail.

So far I've tried to stay away from fiction. Everywhere I look these novels come up though so I'm currently teetering on the edge of reading at least the first one.

working hard... researching hammocks... Smiley
I wasn't going to say anything, but I think Crawl would have been vastly improved if a little more attention had been paid to the hammock physics.  Wink

5  Feedback / DevLogs / Re: Return of the Obra Dinn [Playable Build] on: February 24, 2015, 05:28:05 am
You probably don't need any more book recommendations but 'The British Seaman' by Christopher Lloyd (not that Christopher Lloyd) is pretty good, as is 'The Wooden World'.

I'll grab both of these, thanks Lee.

Your attention to detail is what sets you apart from your peers (Also the fact that you're still on TIG and devlogging your work after finding success). Cheers!

6  Feedback / DevLogs / Re: Return of the Obra Dinn [Playable Build] on: February 20, 2015, 03:42:59 am

Researching the period, the ships, and the sailors for this project has been a lot of fun. It's not so much a dedication to accuracy as it is having no idea where to even start and needing the reference. The only problem is most of the information covering these topics is in books and most of those are old and/or expensive. And whereas there's a ton of information about Ships of the Line and Nelson's Big Heroic Whatever, there's much less on the merchantmen. Where I can, I try to dig up PDF or Kindle versions online.

Digital reference

If I can't find a digital version then I have to look for a physical copy. All the good ones are no longer in print so I've been buying mostly used books.

Actual books, made of paper

Reading through the really old books is enlightening. Some are proto-OCD material, where every detail is listed in the driest possible tone. And there were a lot of details about the East India Company and their ships. Better books have a little flavor that chips away at the EIC's shiny exterior. All the ship porn is great. When this is all over I kinda want to buy (not make) a big wooden model ship.


I'm working on the lower decks now and every once in a while, the stupidest things take forever. On ships like this sailors slept in rows of hammocks hung from the ceiling. I wasted a bunch of time modeling these.

Exhibit A: Ship hammock

My first mistake was ignoring this basic structure and trying to model a more complicated hammock, with support bars. Second problem was trying to use dynamics to form the hammock naturally. Maya's dynamics are pretty good but as usual trying to use their editing UI is an exercise in rage control. After some poorly-controlled rage:

Not using this hammock

Finally I threw all that shit out and just modeled a banana-shape that's much simpler, way fewer polys, and looks better in context anyways. The dynamics hammock was cool in some ways, but too much work to set up, and too many polys. I may go back and hook up the simpler hammock to dynamics if I find it hard to add the sleeping sailors by hand.

Bad, bad, good.
7  Feedback / DevLogs / Re: Return of the Obra Dinn [Playable Build] on: February 20, 2015, 12:52:01 am

You've basically hit on the two main challenges with the design.

1. Where are all the corpses?
2. How can the story/revelations be structured in a way that makes sense.

#1 is tricky because any dead body would've been quickly pitched overboard. So it's inherent to the setting that there not be a bunch of bodies around. I have a relatively simple solution for that. It requires careful sequencing of events but not much beyond that.

#2 is a lot harder. People don't give a lot of exposition in the ~15 seconds before they die. Well, not in good stories they don't. But that dialog just before dying is all I've got to communicate anything complex to the player. This is a nut I haven't cracked yet. I first want to focus on the mechanical requirements - the player has to piece together the identities of the crew. Once I'm confident with that I can weave a larger narrative into the functional parts.

I'm still worried about both of these problems though so no promises.  Grin

If you haven't read it already, I suggest the seminar work of Peter Linebaugh
The Many Headed Hydra, even though it covers a bit earlier period.

I'll check it out, thanks!

Uncharted is an action game though, right? I think you can get away with this in a slower paced game such as this.

Yeah, you're right. I've sorta bitten off more than I can chew with this game though, and this is one feature that would only get in if I had time to spare.
8  Feedback / DevLogs / Re: Return of the Obra Dinn [Playable Build] on: February 08, 2015, 12:52:14 am

The basic outline of the story is more of less decided and I'm currently doing some research to fill in the details. Reading this book for some inspiration:

A collection of naval disasters, published in 1813

I've learned two things:

 1. Life was cheap in 1700-1800
 2. If you want to survive a shipwreck, sneak off in the working launch boat ASAP before anyone notices.

There's nothing in here I can use directly but it's useful to get the tone of how shit hits the fan so spectacularly when a sailing ship runs into trouble.

Surprisingly the biggest problem I have now is how exactly to lay out the crew. I can't find a good list of specific crew roles for merchant sailing ships of the time. The muster role in the dev log is all just placeholder. Will probably just wing it and make something up soon.
9  Feedback / DevLogs / Re: Return of the Obra Dinn [Playable Build] on: February 04, 2015, 08:59:47 pm
[...]Judging by the animated screenshots, all wind animations (ropes and sails) look maybe some 200% too fast. [...]

Good eye, but I think this is just the gifs. The wind animation combines some fast low-amplitude waves with slower bigger ones. It looks ok in-game.

[...]Do you have any plans in mind to turn the crew muster roll into something more physical, so that when you press tab it seems like you are opening a book rather than accessing an interface?

I may add something like this but it's not a high priority. Uncharted 1 shows an animation as Drake brings his journal up to read it and that slight delay, even though it looks cool, always bothered me. So if I put an animation in there it'd probably only show the first few times you open it.
10  Feedback / DevLogs / Re: Return of the Obra Dinn [Playable Build] on: February 04, 2015, 08:54:48 pm

SMB Castle Flag This is the 3rd best devlog of 2014 SMB Castle Flag

Congrats to #1 JLJac's Project Rain World, and #2 eigenbom's Moonman (currently Kickstarting)!

Also check out Willy Chyr's RELATIVITY at #4.

11  Feedback / DevLogs / Re: Return of the Obra Dinn [Playable Build] on: February 01, 2015, 08:40:05 am
Honestly, I don't think the pulleys on the ladder ropes look weird, at least at the level of flapping you have them doing now. Maybe if they stretched further it would look more gelatinous, but right now it looks fine.

I tried to tune it so it's not too obvious. You can see it more clearly up close but this is probably something I won't try to fix.

[...] I wonder if the rope shadows might be a bit too crisp?

You're right, they are a bit sharp. I'll see if using softer shadows looks ok and doesn't kill performance.

The perfect unbroken rigging looks a bit odd against the tattered sail. A few broken lines would help I think. At least a few in the ratlines.

Yeah, the current rigging is too perfect for what the ship's been through. I'll break a bunch of ropes and masts after figuring out the exact damage later.

I'm guessing the sails were made by stitching together strips of fabric of equal width?

Right, that's the idea. I tried putting a grid of squares instead of the vertical strips and it was a little too busy.
12  Feedback / DevLogs / Re: Return of the Obra Dinn [Playable Build] on: January 31, 2015, 09:00:46 pm
Well, it's been a long time since I've had a chance to post here. Thanks again for all the feedback. After finishing the public dev build in October, I jumped straight onto porting Papers Please to iPad. That finished up in December and a bunch of family stuff has kept me from spending full time on Obra Dinn.

I did manage to make some progress though, on creating the ship's ropes, sails, and rigging. I thought this would be done in a few days but it ended up taking a few weeks. There was a lot more technical work than I expected, and several different systems that I needed to figure out in Maya and the game. I'll list what I ended up with for each system and the stuff I tried before getting there.

Maya Script Ops

Before that though, a brief explanation of the scripting setup for this project in Maya. I mentioned way upthread that I prefer modifier-based editing over Maya's lossy system. To get that working, I attach custom commands to a node's "notes" attribute (editable directly in Maya).

Notes attached to a node in Maya

Then I've got a big "applyOps()" script command bound to Cmd-R. When I hit Cmd-R, it duplicates the object, applies all the commands, then hides the original. If I Cmd-R on the opped copy, it deletes that copy and unhides the original again. So I can quickly tweak the geometry and commands. Each time there's some new operation I need, I add it to the applyOps() function. There are already tons of commands like "cut", "add", "combine" (boolean operations), "bend", "pieces" (split into pieces), "duplicate_reflect", "material", etc.

The system isn't perfect (I can't edit and see the results at the same time for instance) but it's good enough. And there's an unintended benefit to staying out of Maya's construction history that I'll talk about below.

Rigged Ropes

All the rigged ropes are generated from Maya curves. The "rope" command allows me to specify non-rope geometry to place at the start and end for pulleys, deadeyes, etc. And I can also easily add a slight sag to the geometry.

Pressing Cmd-R on a bunch of curves to generate ropes+pulleys

At the beginning I tried hand-modeling a single rope, then instancing it across the ship but that turned out to be a huge pain in the ass. Placing ropes is much easier if you can just drag the two endpoints of a curve around. Getting that to work requires scripting/engineering work as opposed to artistic sweat.

"Ladder" ropes are also really hard to do by hand. After a few tries I gave up and wrote a script for that too.

Script-generation of crossing ladder ropes

In Maya I apply a "vertical" or "horizontal" material to each rope, which gets picked up in the game to generate special uv-coords on import. These coords are used by the vertex shader to flap the ropes around in the wind while keeping the ends pinned. Generally-vertical ropes flap differently from generally-horizontal ones. Getting sets of ropes (the shrouds for climbing the masts) to flap around in sync required some extra work.

Using a vertex shader for this animation allows Unity to consider all the rope meshes as "static" and batch them together to save draw calls. That ends up being a big win. The downside is that I don't have a good way to treat the the pulley verts on the end differently from the ropes, so there's some unwanted warping there.

Flapping ropes


The sail booms are pretty simple except that they have ropes attached to them. So if I want to swing the booms back and forth a bit, the ropes need to somehow move with them. If I had a true in-game rope system this would probably be easy, but all the rope geometry is baked/static.

I ended up generating skinned meshes on import to Unity, with definitions in the Maya file for how each attached rope should be bound.

Instructions for the importer to generate a skinned mesh bound to transforms with certain weights

This technique creates a slightly-unnatural bending in the attached ropes and they don't slacken/tighten correctly. But it also doesn't interfere with the flapping vertex shader and as long as the attached ropes are long and the movement is subtle it looks fine.

Ropes attached to swinging booms using skinned meshes


The flapping vertex shader worked great on the ropes so I tried the same thing with the sail fabric. Unfortunately, flapping 2D cloth is a lot more complex than anchored 1D ropes. After some unfruitful vertex shading experiments I discovered that Unity has a built-in cloth system. The editing interface is buggy beyond useless, but you can set the cloth coefficients directly in code no-problem. The results run fast and look good enough.

Torn sails using Unity cloth

For better performance, the cloth is non-colliding. This requires some special modeling to guarantee no intersections - and a constant wind force from behind to push the sails away from the masts and all the rigging.

I use the texture v coordinate to specify whether a cloth vert should be pinned or not. Using UVs like this, and not for actual texturing, has been a common and really useful trick for this project.

Using texcoord V value to specify cloth coefficients

Rendering for the sails is slightly different: they're two-sided and use a special lighting function to make them fully-white when viewed from the front and fully-black when viewed from the back. I found that proper lighting makes them too distracting, especially with the low-poly cloth-friendly geometry and all the ropes passing around.

Piled Ropes

One thing I learned in researching all this rope rigging bullshit is that old sailing ships were basically just wooden boxes full of ropes. The amount of ropes holding everything together is staggering. I don't even have all the rigging in place and it's already distracting to look up and see all those lines.

On top of the rigged ropes though, these ships also had a ton of coiled and piled ropes just lying about - ready to be used quickly. I wanted to capture this sense of excess by leaving realistically-coiled ropes all over the deck. My first attempt at that was hand-modeled and is visible in the first dev build as a tire-looking thing on the aft deck:

Original piled rope. Don't steal.

To get these looking right, I needed technology: dynamics. Maya Complete has a great nDynamics system built in, but up until recently I've been using Maya LT, which has exactly nothing. This was the final straw for me working around Maya LT's limitations though so I finally cracked and bought a license for Maya Complete. My thanks again to the success of Papers Please that I can make purchases like this; Maya Complete is expensive.

The enormous downside of upgrading to Maya Complete at this point is that it can't open any file generated by Maya LT (.mlt). That's purely a marketing/DRM thing from Autodesk - they don't want studios buying lots of cheap LT licenses for their animators while the TDs use one or two expensive Maya Complete copies for the heavy lifting. It makes sense tbh, but it really sucks when you're like me and just want to upgrade your single-seat studio to the full version.

The recommended path for LT->Complete is through FBX export/import. Unfortunately and predictably this loses tons of information, most critically all HumanIK properties and all node construction history. I haven't tackled HumanIK yet, but the heavens shine on me for construction history. Since I'm using my simple applyOps() system for most of the complex modeling I can just delete the "opped" output meshes in the imported FBX and regenerate them in Maya Complete.

Now that the ship scene has been transferred to Maya Complete (.ma) I have access to nDynamics. Specifically, the hair follicles system is just right for taking a hand-modeled curve, giving it dynamic properties to have it fall in a pile, then converting it to a rope using my existing scripts.

Using hair dynamics in Maya Complete to physicalize/drop/collide a curve

In practice there are plenty of small complications with the scripting here: detecting and temporarily physicalizing all meshes beneath the rope, choosing dynamics properties for a good shape, running the simulation for a few frames, optimizing the output curve shape, converting to a polygon rope, adding color bands for in-game rendering, etc. But all told I'm really happy with this. So far I've only added a few loose and piled ropes but it's so quick that I'll hit my target of "way too many ropes lying about" easily.

O.S.H.A violation

The crew couldn't tidy up before dying violently


Ok, one last thing. Something I worried about for a while was how exactly to render all the rigging ropes. Drawing them with the standard outlines looks ok close up, but ends up generating too much visual chatter and thickness for distant ropes. The fix is to LOD the ropes so the outlines stop rendering at a certain distance.

Dropping outlines on distant ropes

From Here

Most of this rigging work so far is for the main realtime scene. The flashbacks won't have any movement so the vertex animation, skinning, and cloth will all be baked/modeled straight in Maya. I've purposely held off on filling out all the rigging in this scene since I won't know exactly how it'll look until more flashbacks are implemented.


Several weeks of sporadic work compressed into 18 minutes. Skip to ~17:10 to see a short in-game walkthrough of the final results.

13  Feedback / DevLogs / Re: Karate Dino on: December 01, 2014, 07:54:31 pm
This looks great.

The one thing missing is the "karate" part I think. Would be nice if after jumping over 10 dinos, your 11th jump would be a tornado kick or something that can be used to attack. Or you can collect a floating star/whatever powerup that makes your next jump a jump-kick. Something to extend the mechanics and reward a bit without losing the one-button part.

For ducking, you don't need any player input. Just automatically duck under certain enemies in certain configurations. Learning when not to jump is enough of a challenge I'd say.
14  Feedback / DevLogs / Re: Machiavillain on: November 24, 2014, 06:03:59 am
We liked this one (kind of german expressionist-ish ?), but it would have quickly become unreadable so...

This is striking. Can't remember seeing anything else quite like it.

I think you could probably make it readable, but it'd require a lot of work and some sacrifices. If it were me, I'd spend significant effort on exactly that.  Grin
15  Feedback / DevLogs / Re: Das Boot [working tittle] on: November 24, 2014, 05:46:21 am
...(If anyone has any suggestion, they are more than welcome!  Grin)...

Some random quick ideas:


Death At Any Depth

Death Tube

Variations: Submersion, Death At Depth, Death Hull

I'm sure there's a lot of cool submarine-related terminology that you could pull a good title out of. My one piece of advice is to avoid the temptation to use a term or phrase as-is since this will bury you in search results (like "Das Boot" would). So, for example, "Torpenator" instead of just "Torpedo".

Good luck!
16  Feedback / DevLogs / Re: Warboat (Local Multiplayer Boat Battle) on: November 23, 2014, 10:13:48 am
Your latest shots look fantastic, but I have to wonder how this work relates to making a fun 4-player battle arena game. Some of my wondering:

1. If I've learned anything from other local MP battle games, it's that the framerate is absolutely critical. The work you're doing with subtle shader effects is trading framerate for fine details that are not meaningful to the gameplay and may not even be visible at the normal zoom distance.

2. The environment feels thematically wrong for cartoonish renaissance-looking characters in little cannon-armed paddleboats. I would've expected something more in line with that time period (small dock off an island paradise, in a mediterranean port amongst larger ships, etc) instead of a post-apocalyptic swimming pool.

3. I don't predict much strategy with a wide-open pool. Do you have plans to add obstacles or other interactive elements to the play area?

I don't mean to get you down though, I really like this project. Smiley
17  Feedback / DevLogs / Re: Das Boot [working tittle] on: November 23, 2014, 09:47:10 am
This looks great. Just tons of potential. I especially like the how naturally the split screen view works for this setup.. And the weirdness level is a great idea too.

Keep at it. You're gonna have an awesome game on your hands. Smiley

(Change the title soon!)
18  Feedback / DevLogs / Re: Return of the Obra Dinn [Playable Build] on: November 21, 2014, 03:31:19 am
I thought there was already frozen muzzleflash/smoke in the current build?

Yeah, the dust system is in the public dev build. Just didn't have time to post in the devlog about it until now. There's one more thing I want to talk about in that build (sound and voice stuff) but I'm not sure when I can do that.

As mentioned before, I also had this feeling that the boat was not moving. So maybe if you add some cracking wood sound at random time it should do the "trick"

Were you playing with the sound on? It currently plays a good number of creaking wood sounds, mostly audible inside the cabins.
19  Feedback / DevLogs / Re: Return of the Obra Dinn [Playable Build] on: November 21, 2014, 01:54:48 am

After getting the basic gameplay down for the dev build, I wanted to add something to enhance the sense of volume and 3D-ness in the flashbacks. The gimmick is that you're able to walk around in something like a 3D picture. That's not so special when you're already walking around in the same environment before and afterwards. It needs something "otherworldly."

My first thought was to invert the colors. Bad thought. Next, I tried just putting a bunch of particles floating around the player. That got the basic idea across but actual particles aren't well suited for low resolution 1-bit rendering: they pop in/out and they scale with distance. Those two problems led me directly to the idea of using a "true" point cloud:

Dust cloud in a test level

The points need to be exactly one pixel in size, no matter how far from the camera. Unity's built-in particles can't be restricted like this OOTB and they also have a lot of extra logic that I didn't need (almost everything), along with some stuff I couldn't turn off (lifetime). So I threw together a custom solution that surprisingly worked well right away.

To render the dust cloud, I generate actual little quads on the CPU. Each of the 4 quad points has the same 3D position with different UV coordinates to specify which corner of the quad it is. That gets picked up in the shader and transformed to be exactly one pixel in screenspace.

v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
// convert from homogenous
float3 screenPos = o.pos.xyz / o.pos.w;
// push corner out based on UV
float2 screenSize = float2(640,360);
screenPos += float3(1 / (screenSize * v.texcoord), 0);
// convert back to homogenous
o.pos.xyz = screenPos.xyz * o.pos.w;
return o;

Even with huge meshes and tons of quads the performance is really good. Probably because GPUs are optimized for churning through large static data sets like this. And that's another advantage of a custom solution over Unity particles: it's completely static, generated once at asset import time.

To make the points more legible in various situations, I invert their color against whatever's behind them. That took some finagling (and one of the renderbuffer color channels), but the whole greyscale/1-bit thing helped again here since there was a channel to spare.


One of the things I'd been holding off with this 1-bit rendered was support for partial transparency. Unfortunately, the public dev build has a gun-firing scene right at the start that calls for some kind of smoke/muzzleflash. So this needed to be tackled sooner rather than later. My first attempt was to just model and texture the smoke shape, apply an alpha shader, and render as usual:

Modeled smoke with transparency shader (lined)

Nope. Second try, remove the lines:

Modeled smoke with transparency shader (unlined)

That's much better from the side when you have a simple bright background, but completely illegible from the front. The poor mix of transparency and 1-bit-ness makes the shape completely disappear on an unsuitable background. Also, moving around the clearly-defined shape of the smoke makes it look cheap and fake. More-so than usual anyways. I tried a few shader tweaks to fade out the edges or otherwise mask the shape, but nothing helped much.

Dust Come Back

After messing around with the modeled smoke a bit, an idea came to me: why not use the dust clouds for this instead of trying to fake it with surface geometry. At 640x360, you can put enough single-pixel particles onscreen to suggest exactly the shapes I'm after.

Modeled dust cloud in-game

The tricky part to make this work was figuring out how to take the procedurally-generated dust clouds and enable modeling their shape manually. There are dedicated point-cloud editors but that's not something I want to deal with.

The solution ended being pretty simple. In Maya, I model the shape and subdivide it a bunch until there's an overkill of verts. Export that to Unity where an import script picks it up, shifts each vert randomly, and converts each vert into a full quad for the dust cloud system. The original shape's triangles are discarded. It's a lot of data but again, GPUs eat this shit up.

Cloud modeled in Maya

In another stroke of pure luck, this technique is much easier production-wise than modeling and texturing traditional geometry. My favorite kind of solution.

Action Lines

Replacing transparent shapes with dust clouds turned out ok visually, but not objectively great. The real win comes when using this same system to indicate lines of action. I found these a great way to make the scenes feel dynamic, even while perfectly static.

Action line in-game and modeled in Maya

This meandering path from otherworldy clouds, to transparency replacement, to action lines is one of the fortunate surprises that I really enjoy in game dev.
20  Feedback / DevLogs / Re: Vatnsmyrkr - Deep sea submarine exploration [GIF WARNING] on: November 20, 2014, 11:52:51 pm
Yeah, that's still only rectangles, tho. But perhaps I can have a mixed system that does this for rectangles and the "brute force" approach for everything else?

The technique in that link is based on segments, not rectangles. What you want is to model all of your shapes out of segments (even circles), so this technique works generally. That's (basically) how I did it in Helsing's Fire and AFAIK it's the standard way to handle this problem. I agree that you shouldn't care about this until you identify it as a performance issue though.
Pages: [1] 2 3 ... 16
Theme orange-lt created by panic