A Case of a Missing Square Root

Recently I started working on my ray tracer again. I took a lot of new things that I learned in software design and applied it to my ray tracer which in my mind produced a happy marriage. Over the years my ray tracer has grown in code size. It has also gone through quite a lot of testing. Therefore, I try to make good use of refactoring tools when I make code design changes. But in one instance, I decided to move some code by hand. Mind you, the code has a lot of dense math operations so it wasn’t exactly easy code to move. And as I later found out, I made a mistake.

I was going through rendered images when I discovered that on a particular image, the edge of the shadows were a lot shaper than I expected. Given that I use rather large area light sources in all my images this was surprising.

Please take a look at the following comparison. These are actually poor sample images because you can barely notice the difference and the light intensity and number of samples are different, but if you look at the full size image carefully, the soft shadow on the left image is angled wrong. It almost looks as if there are two different light sources casting two different shadows. You might also notice that the lighting looks off.

Because the problem is with shadows, I knew I could probably reproduce it using a direct illumination shader (which is much simpler and is a subset of a photon mapping shader) to narrow the problem. And, as expected, the problem persisted.

I then suspected the problem might lie in sampling because sampling an area light source is a straight forward closed formed evaluation of the rendering equation and that is where the problem likely was. I looked at the code where I randomly select a point within a triangle with a uniform distribution and sure enough, there was a missing square root. And this was one code which I foolishly decided to manually refactor.

Senior Engineer and Beyond

Given the title of the blog, I find my lack of posts on life as a developer embarrassing. If you sample my posts by category, it might seem that I spend more time hiking than thinking about software design. But I assure you that is not the case.

I was recently promoted to senior software development engineer, so I figure that is a good cause to reflect on software development. While I am tempted to give my take on what it means to be a more experienced developer, for now I will defer to Eric Brechner’s excellent column “Level Up.”

Now, assuming you are familiar with what makes a senior developer compared to, say, an entry level, let me continue on. Like many others that I know of, getting promoted to senior engineer felt like a relentless race. It seems a lot of people are compelled to be promoted to senior as soon as they can. But in some sense, I think that race is somewhat pointless. That’s because those who make it to senior at a reasonable pace get promoted to it within a year or two of each other. But the real drag starts there.

Some make it from senior to principle in four years or less. Some make it in ten. And some never do. Clearly, if you are thinking long term what matters most is how fast, if you can at all, get from senior to principle and beyond. So I got feedback from several established engineers on how to be a successful engineer. Here are the first pieces of advice that I got:

  • Switching to a managerial role too early is not a good idea. The general idea is that you want to be able to develop your technical and design skills as much as possible before having to worry about developing others. Of course, that does not mean you should shy away from leadership skills. But you should be patient about adding “lead” or “manager” to your title.
  • (From a distinguished engineer:) Nowadays breadth knowledge is more important than depth knowledge. Having knowledge and experience in a wide range of areas is important to be successful in any problem space. (Of course, when a DE says “breadth knowledge,” I interpret that to mean “be really good in a lot of areas and be super good in a few.”)
  • (From another distinguished engineer:) The fastest way to gain knowledge in a lot of areas and, more practically, get promoted faster, is to leave the company and join a startup. Venture funding is decent these days. The startup will probably fail but you will come out much stronger.
  • Try to join an organization where there are principle level people working as ICs so that you can work with them and learn from them. If most principle level people are development managers, chances are that you will not really learn design skills from them. You might get intimidated in a “stacked team” but that is a good thing.
  • (From the bench program:) When you get very good at a certain problem space, it might be time to switch to something radically different. Initially, your productivity and effectiveness might drop but overtime you will exceed where you were before in the previous problem space. Statistically, you need to make four such jumps to become truly successful.

I really need to chew on these and talk to more people. But it seems I really need to take my time and strategically think on how I want to improve upon myself.

Also, after reading through this post I realized that I sound as if I am bent on getting promoted fast. It is a bit more complicated than that. Of course, I do have ambition to get promoted. But with promotion comes increased responsibility and accountability. I do not wish to be promoted until I know I am comfortable with handling those. It might sound like the same thing, but I always tell my friends that getting a stellar review is much more important than getting a promotion.