Saturday, February 4, 2012

Lighting with Shaders

So in the blog post I mentioned last week, I talked about how my computer was dying so I couldn't shader. Well on Monday I got my computer re-imaged, so I went immediately back to shaders. This is going to be a blog post dedicated to my shadering adventures during the week, as well as additional thoughts and comments on lighting in shaders.

Intermediate Computer Graphics - INFR 2350

Immediatly after I got my computer back on Monday, I jumped right back into shaders. I knew a lot of people wanted to show Dr. Hogue their homework questions Tuesday night, so I really had to pump out some questions since I didn't have any done due to my computer dying.

The first thing I decided to do was lighting. Lighting is a vital part of any game. Without lighting, everything would look incredibly flat and have no definition, therefore I really wanted to get lighting done because last semester, my group member Mack did the lighting for the game so I had no experience with lighting. I figured that learning how to do lighting with shaders was the best opportunity to do so, so I started to work on the question that dealt with comparing vertex and fragment lighting.

The light source.

Lighting in programming is actually pretty straightforward. It's not actually "light". When we calculate lighting, we pretty much just define an object as a light source and then we calculate how much light is shone on the other objects in the scene. This light amount is just outputted as a colour. So in essence, lighting in games are really just the program faking light by changing the colours of an object.

The math behind is also pretty straightforward too. In basic lighting, there are four main attributes that contribute to the overall lighting effect, the emissive factor, the diffuse factor, the specularity factor and the ambient factor. The emissive factor deals with how much light the object "emits". The ambient factor is how much ambient light is in the scene. I normally think of it as a direction-less light source that illuminates every side of the object. The diffuse factor is how much the light is spread out over the object and the specularity factor is kinda weird. I normally see it as the amount of light that is directly reflected by the light to you, it's essentially that super bright spot on an object.

Fragment lighting so smooth.

In order to calculate how much light actually is reflected off the surface, you just have to do some math which includes the normal of the surface, the position of the light, object and eye as well as coefficients that you plug in that relates to the material of the object. The math can be found in the textbook and the lecture slides so I won't go into it, but it's pretty simple and not too hard to understand.

The difference between vertex and fragment lighting on the other hand is a pretty cool topic. Vertex lighting only calculates the amount of light per pixel, and then the computer essentially just fills in the rest of the face by interpolating those three points for each fragment within the triangle. This makes it so that vertex lighted objects often look a lot more chunky and unrealistic since all the fragments that are being interpolated within the faces often don't represent that actual result. It also is prone to random artifacts too. Fragment lighting however calculates each pixel's colour, therefore it results in a smoother gradient since every pixel has a unique calculation and we don't have any face interpolation going on.

Vertex on left, fragment on right. Ignore that ugly line.

So that question was pretty straight forward to do. Afterwards I decided to tackle my first medium question and try normal mapping. Normal mapping is actually really, really, really easy to do once you get lighting set up. It's really easy because our video cards actually just allow you to sample directly from textures, so we don't have to figure out a way to circumvent that restriction. Naturally it means that older GPUs wont be able to run our normal map though.

Speaking of which, I messed up really bad when handing these questions in. We could only show Dr. Hogue one question at a time and then you had to go to the back of the line. I figured that more people would show Dr. Hogue the lighting comparison one since it was an easy question, so since I was first in line I showed that to him first. I got an awesome four points for it. Later on, I found out that three other people showed him normal mapping, so when I showed that to him on my second pass, I got jipped three points. I misplayed pretty hard there; should've just showed him my normal map first so I got the full ten, especially since everyone seemed to be showing him their medium questions first.

Almost as embarrassing as destroying your own command center on stage. But not as embarrassing as leaving a won game.

Well regardless, those two questions pushed me up to a whopping 18 points. In my quest for the 65, I decided that I needed to do more so that I could show some to him during his office hours too. The next question I would get done would be another lighting related one, toon shading.

Well, it's related, but not really hugely related. Essentially toon shading is when you clamp certain ranges of colours on your object to a constant amount. So say 0 - 0.5 is now 0.2, and 0.51 - 1 is now 0.8. Something like that. Once you do that and throw up a black outline, it makes the object look cartoony. At least it's supposed to. I just rendered a pink and purple cloud in Photoshop and textured a sphere for mine, and it looked kinda cool.

I cheated the black outline.

I managed to get toon shading done on Thursday night. I really wanted another question done before I showed them to Dr. Hogue, so I decided that I was going to wake up at 8 and just power through another question before I talked to him. Continuing with my lighting streak, I figured I would try to get the medium lighting one, the one where you can toggle diffuse and specular lighting and then add distance attenuation and multiple lights.

I didn't think it was that hard, so when I got to Dr. Hogue's hallway at 9 I pulled out my laptop and started to power code. I ended up messing up pretty bad though, since there were a lot of variables that needed to be changed and created. I ended up copy and pasting a lot of code, which is really bad when rushing since afterwards I ended up spending like half an hour just debugging copy and paste errors. I hate those errors.

I still love these guys though.

In the end, I managed to get it working. Toggling specularity and diffuse is pretty straight forward; it's just a Boolean toggle. I had some issues with distance attenuation since having the modifier as distance * distance ended up making my light too weak, but after making it distance * distance * 0.1, it ended up being pretty reasonable, so I kept that.

Adding additional lights wasn't too bad either, I just had to pass in additional information and ran the lighting calculation once for every light source. Overall the question was pretty easy once you get basic lighting done and understand how it works. With those questions handed in, I shot up to a pretty solid 34 points.

The blue one doesn't really cast a light though for some reason.

Well, 31 more to go.

No comments:

Post a Comment