Return to “[Archived] Daily Dev Logs, 2012 - 2015”


Week of January 20, 2013

Sunday, January 20, 2013


Very fun day, much better than the average slow Sunday!! I started the morning with working up a list of things I wanted to target and destroy this week. At this point, about half of my list has already been crossed off. You mustn't be afraid to dream a little bigger, darling. Indeed! Always a nice way to start out the week :D

It was really a boatload of smaller things that got done today. I made subsystems damageable, so now you can blow up and incapacitate weapons and thrusters. Speaking of blowing things up, I spent a good bit of time improving the explosion effects, which needed some work. They still do, but they look much less "perfect" now, since I've added some shape to them. Ah, and speaking of weapons - I implemented correct weapon tracking. The weapon is now two distinct parts: a base which rotates only about one axis, and a barrel which rotates only about the other. This is a typical turret implementation, and yields a nice visual effect. Previously, you may have noticed the whole gun was moving uniformly when I aimed. Now it looks much more natural! Speaking of guns, I improved the pulse weapon visuals. I still think they could look slightly less "cheesy," but I'm getting there.

I also drastically improved performance of the particle engine, which was hogging a good bit of CPU time creating those lovely little puffs of dust and minute space particles that you probably haven't even noticed :roll: No sense wasting lots of performance on something you can hardly see!

Speaking of shields (wait, what?), I worked on generalizing the way that shields are implemented in the game. Well, suffice it say they're sufficiently general now. A shield object can be attached to anything with a generator, which I've added as a new type of hardpoint. So far we have thrusters, weapons, and generators. I'm thinking generators will be used for anything that basically consumes a constant stream of energy to provide some effect - shield, cloaking field, long-range scanner, etc. Oh, and if you have multiple generators, there's no rule that says you can't put a shield on each of them so...multi-layered shields? Sure, why not! I don't see why this would be a problem gameplay-wise, although I haven't tried it yet. Could make for a very nasty surprise when you finally pop that battleship's shield, only to realize that...there's another one. Oh dear. Of course, could make for an equally-nasty surprise for your enemy! Especially when those fighters think they can drop through that outer layer to sink a few bombs in...only to witness the bombs exploding on the surface of an even tighter inner shield. It's the Limit Theory mentality. Why impose a limit when there doesn't need to be one? :D

Let's see if I can't finish up the other half of that list tomorrow!

Hour Tally

Coding: 5.33
Internet: 2.89
Testing: 2.19
Total Logged Time: 10.42
“Whether you think you can, or you think you can't--you're right.” ~ Henry Ford

Re: Week of January 20, 2013

Monday, January 21, 2013


The day started just like any other. A hot shower, a cold coke, and that crunchy sound of bits flowing through the machine as ships exploded on-screen. A tweak here, a fix there. Missiles came back online, as I had neglected them for so long that they were badly broken. But it was a painless fix. Ah shields, yes, they need some kind of graphic for when they go down. One heavily-tweaked explosion shader clone later, large puffs of plasma were flying through the air as my god-mode laser beams ripped through the poor capital ship's one-and-only shield. I was a happy little boy, working on my happy little code. And then it started.

Density fields...isosurfaces...surface extraction... What?? No, stop that Josh. Stop now. You know no good will come of that. Fast raymarching, fast collision elegant. No!!! You've already been there. You've already tried. It's not worth it. We gave up on it long ago, it's just not practical. Come to your senses. Beautiful shapes, effortless constructive solid geometry. No!!! It's fine. You've got good collision detection. You've got fast raycasting. You've got a decent polygonal CSG implementation. It's going to be fine. Just breathe.

I tried, I really did.

But in my heart, I knew I wouldn't be able to resist.

Since the moment I first learned about scalar fields and their application to computer graphics, about three years ago, I was in love. The elegance...the beauty...the effortless solution to so many problems. Representing space, surfaces, and geometry with 3D math functions rather than loads of little ugly triangles. I couldn't get it out of my head. It felt so right, so simple, so beautiful. But time passed, and I lost confidence in my scalar fields. I implemented a half-baked physics engine for them, but ran into many complications. I made some really blobby, ugly ships, and was left feeling underwhelmed. Maybe that's why no one uses them, I thought. Maybe they're just not as powerful as I thought. I can still remember telling my mentor at Pixar that I firmly believed all game geometry can and should be represented with fields - with math - rather than with triangles. But time passed, and I lost my vision. I had neither the vector math capabilities nor the computer science capabilities to truly harness the power. So I came back to the world of triangles. The world of ugly, discrete little flat surfaces. The world of hackery. And I enjoyed it - or at least pretended to - for as long as I could.

But today, I've been infected, once again, by the beauty of a mathematical description of the world. And this time, I will not turn back. Maybe it's crazy. Maybe I should stop while I'm ahead. But I won't, I can't. I can do better this time. I can easily build everything that's already in Limit Theory with pure math, but I can go so much further. Without triangles inhibiting me, I can finally have exact geometric operations...which means carriers, stations, hallow asteroids, destructible asteroids, dynamic ship destruction. I can finally have a physics engine in a few hundred lines of simple code. Truly, there is no limit with pure math.

As a test, I've already written the field evaluation engine, plugged it into a machine that spits out triangles, and taken it for a test-drive in-game. It's fantastic. Asteroids look the same. But they're not. Underneath those triangles is pure f(x, y, z). Which leads to beautiful-looking asteroid bases, where the carved-out hangar is not only completely free of geometric errors (unlike last time), but it's also smooth, and blends smoothly into the outer surface of the asteroid. Try that one with triangles. No chance. And ships? Where do I begin. Ships are going to be beautiful. I'm only getting started. It's just the beginning. Ships are the most difficult, so it will take time. I'll have to keep building my mathematical toolkit. But they will be better than ever before.

Everything, my friends, will be better than ever before. In time, and with the help of my good friend, the scalar field.

I'm sorry I ever abandoned you pal, but I promise, I'm here to stay this time.

Hour Tally

Coding: 6.63
Internet: 3.45
Testing: 3.11
Total Logged Time: 13.19
“Whether you think you can, or you think you can't--you're right.” ~ Henry Ford

Re: Week of January 20, 2013

Tuesday, January 22, 2013


Today I abandoned scalar fields.


:D Of course not. Rather, today I spent the whole day indulging myself in working with these beautiful things! Slowly but surely, I'm building an engine that's going to be the foundation of every piece of geometry in Limit Theory. I had a number of breakthroughs today related to this technology. The first was to implement analytic gradients for all of my field functions, as well as all of the operators on them. If you're familiar with calculus, then you're familiar with gradients, whether you know it or not. They are simply the multidimensional analogue of derivatives. Believe it or not, they're actually important outside of math class! The reason is that we use them a lot in computer graphics. One of the main uses, is that having this information in the form of what's called a surface normal is the main way that we perform lighting/shading calculations on that surface, so that it actually looks like a real object. Without derivative information, we wouldn't be able to model the way that the object interacts with light at all! Now, there are several ways of computing this information. Usually, we use a hacky method that provides a pretty good approximation. But it starts to break down when we use very low-quality models, which we might want to use for, say, objects that are really far away.

One of the many amazing things about these scalar fields that I've been talking about recently, is that they actually provide this information in a mathematically-exact way. In other words, not a hack, not an approximation, just reality. It turns out that, to obtain the true surface normal for a model, all you need to do is evaluate the gradient of a the field that corresponds to that model at the point. And you get precisely the surface normal!!! Amazing! :) So with a little help from our infamous frenemy Sir Calculus, we can obtain exact information about the surface we're making. In practical terms, this just means that the surfaces in the game look that much more realistic. In particular, low-resolution surfaces will look wayyyyy better than before, so I should be able to do some heavy optimizations by switching to lower-resolution models for objects that are far away.

Ultimately, it's just one more thing that'll make the LT universe look better, and that's always a welcome thing! :)

Needless to say, where heavy math is involved, heavy headbanging is also involved. It was quite an endeavor to get this working for all of the types of fields that I'm working with. As Han Solo would say, "Good against a sphere is one thing. Good against a smoothed box subtracted from a 15-sided polyhedron, that's something else." That's why a whole lot of my time today was spent on the internet and on my notebook, reading and writing plenty of excruciating symbols. In the end, however, it couldn't have been more worth it. I've got it working, and the surfaces are just beautiful!!! The possibilities are really endless now :D

If you really want more nasty details, feel free to have a look at my dev blog, where I've gone ahead and shared the pain with the rest of the world.

Now then, I think it's probably time to get back to the game and start putting this technology to work! :geek:

Hour Tally

Coding: 4.94
Internet: 4.25
Testing: 2.08
Total Logged Time: 11.27
“Whether you think you can, or you think you can't--you're right.” ~ Henry Ford

Re: Week of January 20, 2013

Wednesday, January 23, 2013


Ok, I guess I needed one more really mathy day before getting back to the real world of applying this stuff in-game :roll: Since it was such a technical day, it's going to be pretty hard to describe what I did today in approachable terms. I invite you to skip this dev log if you aren't interested in boring math!

Yesterday, while I was working on the field engine, I kept thinking that it would be nice to have some help from the computer where the calculus was concerned. As I mentioned in the last log, it got pretty nasty when I was trying to analytically derive the gradients for some of those fields. But the reason it got nasty is because I am a human, and big formulas scare me. Interestingly, though, derivatives are actually extremely easy to compute from an algorithm perspective. There's a simple rule for just about any function that you might want to differentiate, so, in theory, the whole process should be super easy! Why not let the computer do it? That was a thought that teased me yesterday, but completely stole my mind today.

So today, I spent the whole day working on a calculus engine. Well, I say calculus, but really, it is a symbolic differentiation engine, it cannot do integration. Symbolic differentiation is really, really interesting for a few reasons: 1) It's immensely practical 2) It's always really easy for a computer 3) It quickly becomes impossible for a human (for large expressions). These factors make it one of those "high-payout" things to implement, because it's, that was easy, but wow, I could never have done that on paper...! So in about 500 lines of code, I have a machine that can compute exact derivatives for just about any expression you like, and performs simplification on top of that. Simplification was actually by far the hardest part, and is generally a much more difficult problem than differentiation. Differentiation is completely local, meaning you can look at each pieces of the equation individually, find the derivative, and then bring all of the parts together. But simplification is inherently a non-local thing: you want to take pieces from different parts of the equation and collapse them into a simpler form. Despite my initial skepticism, it actually ended up being easier than I was expecting, and I was able to obtain much better simplification results than I anticipated! In many cases, my results are as simplified as WolframAlpha, which is an extremely powerful symbolic math engine. The main thing that mine can't do is factoring. Sometimes simplification requires very clever factoring, and I'm just not sure how to approach that one yet. Nonetheless, this sure would have been a great tool to have while doing calc homework back in HS...sure wish I had it then :D

But anyway, what's the point of all this mumbo-jumbo fancy math talk? Here's what I'm thinking: I've got the field engine, I've got the calculus engine, and I've got a GPU. Maybe you can see where this is going :ugeek: What I can do now is write an equation, hand it to the field engine and calculus engine, which will give me the field and gradient equations, respectively, then I'm thinking I can bake those equations into a GPU program (aka shader), and execute them on the GPU to evaluate the field + analytic gradients really quickly (because the GPU is a beastly math machine). Then, of course, this field data will get turned into geometry to go into the game! By employing the GPU, I should be able to produce a level of detail that the CPU wouldn't even be able to touch.

As for hours today, I'm really happy with the coding - I pretty much just sat there working on the math engine for hours and hours on end, and the time reflects it! And I spent plenty of time consulting my good friend Wikipedia to help solidify my understanding of derivatives, total derivatives, gradients ... all that garbage.

Hopefully I will get back to some less-technical work tomorrow and give my brain (and dev log readers) a rest!

Hour Tally

Coding: 7.88
Internet: 4.22
Testing: 0.19
Total Logged Time: 12.28
“Whether you think you can, or you think you can't--you're right.” ~ Henry Ford

Re: Week of January 20, 2013

Thursday, January 24, 2013


Back to the real world 8-) And very happy with some of the results today. Very proud to say that the graphics have taken another leap forward today, although you'll have to hold tight for pictures, because it will be a while before I will have them fully-integrated (might not even make it in the monthly update video).

I started out the day with working on ship textures. Don't worry, I was very aware of the fact that they were extremely lame up to this point. And, to some extent, they still are, but they've gotten much better today. I'm getting better at texture generation, and starting to see an awful lot of similarities with mesh generation, because guess what technique I'm using? Ah yes, our favorite scalar fields are now being used to generate ship textures :D Gotta go all the way, right? But really, there are just so many nice things you can do with them, even in 2D. So I'm having plenty of fun with that.

Around midday came some very exciting work on lighting quality. I re-introduced occlusion into the engine, this time in the form of per-vertex occlusion. Occlusion is, in a nutshell, information about whether a particular piece of the geometry should be shaded dark or light, based on how much light is getting to it. Thanks to some properties of the algorithm that turns scalar fields into triangles, I'm actually now able to compute and implement occlusion in a way that is more natural, higher-quality, and faster than the implementation in most modern games! I'm very happy with the results, as I really hate the industry-standard way of doing this, which you may have heard of - the infamous screen-space ambient occlusion (SSAO), which is truly one of the ugliest yet most popular hacks that we graphics programmers have perpetuated over the past few years.

Finally, the end of the day brought the first incredible results of using the GPU to compute the field, as I mentioned in yesterday's log. Let me tell you the story, since I love exaggerating my coding battles...

  • There I was. Sitting cozily in my chair, diet coke at the ready, geared up to implement scalar field evaluation on the GPU. I had my hopes set pretty high, but nothing overly-optimistic. I had my reservations. GPUs can be fickle friends...from random shader compiler bugs to floating-point precision issues, the graphics card is truly a mighty yet unpredictable beast. Or so I thought. I implemented the code. It took under an hour, definitely nothing fancy, just a straightforward port of the math to the GPU, and a fairly simple method of computing it in a shader, then sending the result back to the CPU.

    I ran the code. Hmmm....looks like a 100% performance gain. Cool, but...kind of underwhelming. Still taking 2 seconds to compute the mesh, that's about 1.9 seconds too long for my taste. "Hey, GPU, I thought you were like...100x better at math than my CPU?" The graphics card just shrugged and snickered at me, mumbling something that I couldn't hear but I thought I heard the word "profile," so I decided to investigate a little further.

    It didn't take long to realize that nearly all of the time was being spent of the CPU, computing the gradients. That's odd, I never thought that would be a bottleneck...ah well, let's remove that. Oh, and let's put a timer around the GPU code just to be sure we're getting a good measurement.

    I ran the code. "GPU evaluation took 0.01s" Wait, what??? Indeed, there it was, the full-precision, completely correctly-constructed mesh, right before my eyes, free of errors or inaccuracies. All in...a few milliseconds!?!? "That's more like it, I knew you were better than that." The GPU smiled back at me. But I wasn't going to let it off that easy. Sure, that was just a 50x50x50 voxel field with two simple shapes in it. Not exactly intense math, even though the CPU seemed to struggle with such things. So I cranked up the resolution.

    75...100..150...200...each time, "GPU evaluation took 0.01s" ...!!!?!? Ok, this is a little crazy. "You must think you're pretty clever, doing that in a few milliseconds..." Again, the sleek, black graphics card smiled back at me, saying not a single word. We'll see how good you are, I thought. More geometry. More boxes. I had never pushed the CPU past 25 boxes. I gave the GPU 100. Then 200. Then 500.

    "GPU Evaluation took 0.4s" ...!!!!! My God. 400ms for 500 boxes at 200 resolution...truly impressive. My CPU would have taken several minutes for that. "Alright, you win, I am truly impressed." The card squeaked a little bit, enjoying my words of praise. But I still wasn't done. Sure, so it can compute boxes. Those are easy. Now...rounded boxes, that's another story. Computationally, they are far harder than angular boxes. On the CPU, about 10x slower. Quietly, I switched the boxes to be soft - but still maintaining 500 of them - and threw what I thought would be a crippling job at my "helpless" little GPU..

    "GPU Evaluation took 0.6s" ...... :shock: :shock: :shock: The card broke out in laughter. It was having quite a good time, while I sat there in total awe. 500 smooth, rounded boxes, unioned together with smooth blends, computed at a resolution of 200 x 200 x half a second. With no errors. You win, GPU, you win.

Hey guys, good news, graphics cards are really, really good at math. What does this mean for LT? Ultra-high-quality geometry, with lots of complexity, and it's going to be generated really fast. I'm so excited about this result!! Hats off to that little mathemagical miracle from NVIDIA, as it has once again blown my expectations out of the water :D

Hour Tally

Coding: 4.66
Internet: 3.32
Testing: 2.15
Total Logged Time: 10.13
“Whether you think you can, or you think you can't--you're right.” ~ Henry Ford

Re: Week of January 20, 2013

Friday, January 25, 2013


Another day of being amazed with GPU speeds :D

Today I moved the entire model generation process onto the GPU. Yesterday I had only the field evaluation. Today, I have field evaluation, gradient evaluation, and ambient occlusion evaluation. The latter was particularly expensive and basically killed the CPU. But on the GPU...yep, you guessed it...absurdly fast. Together, all of these results make for some pretty awesome-looking models! They're high-detail, have accurate normals, have great AO, and, of course, can be made from very cool math functions 8-) Speaking of which, I almost finished implementing the code for evaluating the scalar fields on the GPU. Only remaining thing is fractal noise, which is used in asteroids.

For a pretty picture of a bunch of boxes with nice occlusion...check out my latest blog post. Now just try to picture a ship like that (oh, and try to make the texture less ugly when you picture it in your mind) :)

A bit of an off-day in terms of hours, but I'm thinking tomorrow will just have to be a codefest to make up for it! I still have quite a few things left on my list for the week...then again, I never had "rewrite entire geometry engine using GPU scalar field evaluation + automatic normals + nice AO" on the list, so I guess I'm OK with that! And, as I've said, I think the past few days have been an excellent investment in the graphical quality of LT.

Onward to a better-looking procedural universe!

Hour Tally

Coding: 3.97
Internet: 2.15
Testing: 1.38
Total Logged Time: 7.51
“Whether you think you can, or you think you can't--you're right.” ~ Henry Ford

Re: Week of January 20, 2013

Saturday, January 26, 2013


I'm coding as fast as I can to make sure that I get to show some cool stuff in the upcoming monthly update video!

The day started with hugely-improved asteroids. They look beautiful now (in my opinion)! I'm taking advantage of the power of the new field engine to make some very cool-looking rocks. Couple that with the new ambient occlusion, and you've got some awfully pretty places to land and hide from enemies :)

Speaking of ambient occlusion, I improved it a lot today. Using a smarter, stratified sampling pattern, I brought down the computational cost by about 8 fold. I then switched the radial sampling pattern to obtain much smoother, more-beautiful AO. Looks like the real deal! (well, I mean, it that makes sense...)

I then proceeded to replace the ship generator using the new field technology. Already, I am achieving more beautiful ships, even with a ridiculously-simple algorithm. As I've said before, I'm positively excited for the future of ships, space stations, and all the other procedural geometry, because it's all taking a huge leap forward in quality thanks to this week's work!!!

Right now, I'm in the middle of breaking...well, of breaking pretty much everything. The core engine needs to be cannibalized and generalized so that I can introduce these scalar field meshes seamlessly and naturally. But, as always, the process of ripping out and replacing code is only a good thing (if a bit painful). I hope I can fix everything as soon as possible, because I would really like to start unifying everything under this scalar field technology. Once I replace all of the pieces of the rendering engine that need to be replaced, I'm going to create a scheduling system for the GPU, and start working with incremental LOD streaming, so that the game will boot fast and the mesh quality will improve as higher-quality meshes are generated in the background. This will be the first step towards background generation of procedural assets, which is no doubt an important part of the LT technology.

Wish I had more time to inject excitement into this post, but, honestly, it always makes me feel a bit uneasy when I'm in the middle of breaking everything, and it makes me just want to get back to fixing so that I can stop seeing so much red in the compiler log. Gotta go! :geek:

Hour Tally

Coding: 6.95
Internet: 2.50
Testing: 2.89
Total Logged Time: 12.34
“Whether you think you can, or you think you can't--you're right.” ~ Henry Ford

Re: Week of January 20, 2013

Week Summary

General Sentiment

This was really an amazing week, and, although I didn't finish all the tasks that I listed on Sunday, I did way, way more than I ever would have expected to do in one week. LT's engine is now based around a beautiful, simple, and elegant technology that I'm completely in love with. Already, this technology is enabling massive leaps forward in graphical quality. But it's just the beginning. The technology will unlock a whole new realm of gameplay options, and will also unlock a new realm of technical possibilities. I couldn't be happier with this paradigm shift! In addition, I'm super-excited to have high-quality ambient occlusion already implemented, which is just one of the many technical possibilities that the scalar field technology enables. I'm also incredibly excited at how well all of the GPU computation is performing.

The future is looking amazing for LT!!! :)

Major Accomplishments
  • Shields implemented in game, including destruction effects
  • Implemented scalar field engine
  • Implemented GPU computation of fields
  • Implemented ambient occlusion + GPU generation thereof
  • Implemented symbolic differentiation engine for future use in analytic surface normal computation
  • Overhauled asteroids, in the process of overhauling ships
  • Improved ship texture generator
Combined Hour Tally

Coding: 40.36
Internet: 23.02
Testing: 14.00
Total Logged Time: 77.38
“Whether you think you can, or you think you can't--you're right.” ~ Henry Ford

Online Now

Users browsing this forum: No registered users and 1 guest