Thursday, December 19, 2013

Slack

OK, I've been slacking on daily updates again.  :)

There hasn't been a lot of bloggable stuff going on, though.  I've mostly been focusing on greyblocking all of the levels and putting dialog in.

I made a few additions to the level editor to support some of the things I was doing.  I added clone/duplicate to the editor, which has made placing multiple objects a lot easier.  This was pretty easy to do because cloning is basically an inherent feature in the game object / component system.

There are still some changes that I need to make there.  Most importantly, I need a better way to select objects.  The mouse clicking actually works OK right now, except I'm not displaying bounding boxes for everything, so sometimes it's hard to know what you're clicking on. 

Overlapping objects are a bit of a pain.  What I ended up doing was, when you click on multiple overlapping objects, you select the one with the smallest bounding box.  Most of the time this actually seems to do what you expect.

Some bounding boxes overlap completely, though.  Worse, some objects really don't have a bounding box because they're either points or just stuff in the scene that's doing stuff that doesn't really exist at a specific location in space (such as the main music track).  These all just kind of overlap at the origin.

My UI controls are kind of in a state of brokenness.  I suppose I should just fix them, then I can choose from a list of objects.  I had started work on a tree view, but didn't get it finished yet.  Or I can do the hacker thing and put in next/prev object keys.

Sounds like I have code to write, yay! :)  I like doing level design and dialog, but it doesn't flow as easily as code.


Oh, and after nine years of purposefully avoiding it, World of Warcraft has finally got its hooks into me.  So far it's only cutting into lunch and overtime hours.  :)

Tuesday, December 10, 2013

Weak Parent

Blogging on the go today.  Typing a whole post with the iPhone keyboard is far from fun, but not much choice today.

Today started with a little modeling work. There were a couple "vents" on one of my spacecraft I wasn't too keen about.  I'm still not liking it too much, but it's better.  I'll probably have another go at it tomorrow and maybe get an image up.

Most of the rest of the day was trying to get everything in place to allow proper level transitions.  It's about time to rough in all of the planned levels, but currently things are a bit debuggish and I can't currently chain level loads.

I also put in a new "weak parent" component that basically just copies the transform of one game object to or from another.  After parenting the game camera to the ship, I discovered that the game stops rendering when the player ship explodes because the camera goes with it as the child of the ship.  I suppose you can debate whether this is a good arrangement, or if children should just be reparented.  This way makes a little more sense to me, and adding reparenting as a separate operation from destruction would work fine.

So, busy day, working towards getting levels roughed in.  More of the same tomorrow.

Monday, December 9, 2013

Gray Day

After a weekend of Bioshock: Infinite (which was just excellent, in case you are like me and way, WAY behind the times) it's time to get back to work.

After doing a bunch of art-related stuff this morning, I decided to get back to level creation stuff.

Using the drum track of the level's music last week was a good start, but needed to introduce some more randomness into the equation.

I assigned a spawn range to each drum note and then used a Gray code to determine a spawn position inside each range.  This is a little nicer than just using completely random numbers, because you're guaranteed to not have a repeated number (each new number differs from the previous by exactly one bit).  But it's also gives the appearance of randomness on the scale that I'm working at.

Result:  pretty fun, actually.  :)  New problem:  it's pretty difficult, too; will need some testing to determine if it's appropriate for just the second level.

Oh, and the art related stuff.  Kicking around "movie poster" type ideas.  I was looking at a bunch of minimalist movie posters and thought they were quite striking.  This is not quite so minimalist, and will probably make no sense to you at the moment, but hopefully it stands out:


Friday, December 6, 2013

"End of stream" means something else apparently

Trying to get the audio synchronization to work.

I was having some trouble last time I looked at it with getting a proper sample cursor position on the stream voice.  The music stream gets read in chunks, so there are multiple buffers getting filled and submitted to the audio system.  I seemed to be having the problem that every time a buffer was started, the current play position was reset, even though the docs said it should be the count until an end of stream marker is reached.

Debugging audio can be a pain in the butt, because there are all sorts of things all happening at the same time with multiple threads, hardware interrupts, etc.  It's hard to debug things in a properly "stopped" state sometimes, because every time you step an instruction, all sorts of other stuff happens.

In any case, the problem should have been obvious:  the end of stream marker doesn't actually stop anything, it just keeps playing submitted buffers happily.  And the end of stream marker was set on every single buffer.

Then I got into looking at the shader node stuff in Blender.  I was trying to set the transparency based on the dot product of the view vector and the surface normal to give a nice smooth falloff.

First off, the shader system is completely awesome, because it actually has input pins for normal, view vector, etc., and math nodes for doing dot products and other vector operations.  So, in theory, it should actually be possible to compute that.

Two problems:

  1. Specifying transparency is a bit difficult, because the renderer is using path tracing, so there isn't really an "alpha channel" you can specify for opacity, it's more about probability that each of the R/G/B channels will be passed through.
  2. The above math operations don't seem to be working as expected.
Not sure what the problem is trying to get a dot product result.  Possibly some difficulty dealing with negative results, maybe the vectors aren't in the same space (camera vs. world?) 

Plus, it seems that different operations might give output on different pins.  The dot product will result in a scalar, it would be nice if it output it to all channels of the vector pin or something too.  Or was documented at all.  Or the source code wasn't so opaque.  (haha, opaque... stopping now)

Oh, I also wrote a tool to convert a MIDI file into script commands to spawn objects a specific time values.  This is half way to cool, except drum tracks only have a few different notes, which is presently kind of boring.  Still working on a good solution to that.

Thursday, December 5, 2013

Smooth, very smooth

Back to work.

I basically took the last two days to recharge.  Motivation and energy have been in short supply recently for some reason, so I took some time to play some games and just record some music for fun.  It's nice to be able to take a mental break when you need it, and today has been relatively productive.

A while back while playing with Shadertoy(1) I came across the smoothstep shader command, which for some reason I hadn't come across before.  Microsoft's documentation is a little opaque, but the Wikipedia article there is quite informative.

So basically, rather than doing a linear interpolation with lerp(), you can smooth interpolation with smoothstep().  The function it uses is f(x) = 3*x^2 - 2*x^3, which at first glace looks like a bunch of numbers somebody just made up, but as you can read in the article, they're the numbers you come up with if you figure out the coefficients on a generic 3rd order equation that has f(0) = 0, f(1) = 1, f'(0) = 0 and f'(1) = 0.  How cool is that?

You can also do the same thing for a 5th order equation that also has zeros at the second derivative, for a "smootherstep."

So, I inserted that into my vector and curve libraries, because that's just very useful.  :)

Then, onto some real work.

I want blue laser "bullets," but they really weren't showing up very well against my background.  What I really want is the "lightsaber" look - bright white inner "core" with a blue halo around it.  I was trying to put a really bright blue bullet into the scene hoping the bloom filter would blur it out, but that doesn't really give the white core. 

I modified the bullet model to have a white core with a transparent blue shell around it.  That's an improvement, but not quite there yet.  This uncovered some unimplemented features in the shader graph (the "mix" node wasn't working properly).  This also prompted me to fix the alpha sorting, which wasn't properly detecting when transparent shader nodes were being used and setting the correct flags.  Hopefully that's it for pipeline work for a while.

Regardless, I now have a white core... with a blue shell around it.  Which looks OK, but doesn't have the falloff I want.  Ideally I would adjust the alpha based on the dot product of the view vector and the normal at each pixel to give more falloff at the edges.  That's an easy enough shader to write, but I'll need to find a way to specify it in the shader graph.

Then I wondered what the game would look like if I set the parent of the game camera to the ship rather than the world as I'm fly down and around the "hyperspace tunnel."  I think this is going to have to be part of the game.


1:  In Firefox, I needed to go to about:config and set webgl.prever-native-gl to true, or that site would hang Firefox basically forever and I would have to kill it from the process manager.  From what I was able to determine, the translation layer that converts from WebGL to DirectX doesn't work very well on some code.

Monday, December 2, 2013

I Used To See Four Lights

So, what's going on today...

I decided to put some proper lighting code into the component system.  I've been using the same four hard-coded lights for quite some time, and it seemed like maybe now was the time to do something a little better.  :)

So, adding in a couple of light components.  First, the lights themselves, which are attached to a transform and can therefore be attached to other objects or otherwise moved around the scene.  And second, a collector, which can be attached to a model object and determine the influence of the lights in the scene on the object.

This is pretty basic, we'll see how well it works out.  Currently I'm just accumulating all of the lights into a single set of spherical harmonic coefficients for each object.  That might become performance-prohibitive eventually, though any sort of dynamic spatial partitioning probably won't be cheap either.

So, today was mostly spent brushing up on the math for all of that again... and then remembering that DirectX has a bunch of functions for this already... and then remembering that I already wrote code that was using them months ago.  I seriously need to defrag my brain or something.