Wednesday, April 24, 2013

Game Graphics Assignment 13


Last assignment of the class and we were able to choose something cool to do.
I chose holograms as the cool thing I would try to make. Since I started learning game graphics I have been interested every time I have seen a hologram in a game. I often will stay there in the game and watch it, trying to figure out what they are doing.

So for this assignment I decided to look into it and see if I could make something like it. After a short time goggling hologram shader I found a nice post about how to implement one, step by step. Although the post was not about how to write it as a shader but was instead how to implement it in some specific GUI application. It still showed some specific steps that gave the effect I was looking for. From there I would look at it and try to see how to implement that effect in code.
For each of the parts I was able to figure out a way to implement it.
Link to post about a hologram shader

There are 5 major effects that I implemented to get the final look.

1. a very simple one, I used a solid color. So I started with setting the color to float3(0.05f, 0.84f, 0.33f). This was a simple first step.

2. I calculated the fresnel effect and used that to do transparency. This makes the edges not transparent and the parts facing you directly are transparent. You can see the effect doing this gives.
Before Fresnel transparency

After Fresnel transparency

3. I added static to the color to add in the randomness. I wasn’t sure whether I wanted to add the static to the color of the alpha. But I think it looked a bit better adding it to the color instead of the alpha. However as a programmer I wanted it to really show, if an actual artist had this they may want it to be using for the alpha because it was more subtle with the alpha.
For static I used code sent to me by JP, it worked well. Although I think if I were doing this for longer I would look at trying to get static with spatial dependency. This static is completely random. Where I think the static could look better if there were lines of static and areas of static rather than per pixel random static.
Here is the function I used for static.
0.5f + (0.5f * frac(sin(dot((i_texcoord + g_secondsElapsed), float2(12.9898, 78.233))) * 43758.5453));
I multiplied that output with the color.

4. For this I added lines that move through the hologram. For a long time I was multiplying the line by the color, so that the line was a dark line going through the mesh. However I realized that didn't make as much sense as doing it with the alpha. Once I tried that I liked it better. So these lines are lines of 0.0f alpha that move through the mesh.
I did a lot of things to get these lines. One thing that I did is that the line is based off of the pixel's world position. I weight each of the position values (x, y and z) and use the sum of them in the calculation. This way it is based off of the position, so the line will move along the mesh. I can also control how the line moves, although the x and z are fairly arbitrary, I can make sure lines are correctly moving up and down the mesh. And the x and z are then used for more random lines.
I ended up making a function to create these lines that would take in all the parameters needed. This way I was able to have multiple lines easily (I ended up with 5).
Here is the function
float CreateRandomLine(in float3 i_worldPosition, in float3 i_positionWeights, in float i_secondsElapsed,
  in float i_speed1, in float i_speed2, in float i_linePercent, in float i_thickness, in float i_randomNumber = 1.0f, in float i_percentOfTime = 1.0f)
{
  float l_randomLine = saturate(frac((abs(((i_worldPosition.y * i_positionWeights.y) + (i_worldPosition.x * i_positionWeights.x) + (i_worldPosition.z * i_positionWeights.z)) - ((i_secondsElapsed - 100000.0f) / i_speed1))) * i_speed2) / i_linePercent);
  l_randomLine = saturate(l_randomLine * i_thickness);
  return saturate(l_randomLine + PercentOfTime(i_secondsElapsed * i_randomNumber, i_percentOfTime));
}

I built the function up slowly. It ended up being quite complicated. But it wasn't too hard to make because I was just working with one part of it at a time.
Here is an example of me using the function.
l_positionWeights.x = -0.5f;
l_positionWeights.y = 0.0f;
l_positionWeights.z = 0.2f;
l_finalAlpha *=  CreateRandomLine(i_position, l_positionWeights, g_secondsElapsed, 0.5f, 0.2f, 0.2f, 20.0f, 1.66f, 0.4f);

5. This was the final thing that I did. I wasn't sure if I was going to try it, but I figured out a way to do it while at home and so I wanted to try it. This was adding position distortion lines to the hologram. So this would be in the vertex shader. This is much the same as the alpha lines, but instead they will move the position of the vertices. This gives the look of the hologram distorting and I think it really helped.
I used the same CreateRandomLine as before. But instead of multiplying it by the alpha I multiplied it by an offset and then added that to the position.
l_positionWeights.x = 1.3f;
l_positionWeights.y = 0.4f;
l_positionWeights.z = 0.2f;
l_positionOffset.x = 0.1f;
_positionOffset.y = -0.1f;
l_positionOffset.z = 0.0f;
l_positionOffset *= (1.0f - CreateRandomLine(i_position, l_positionWeights, g_secondsElapsed, 0.45f, 0.35f, 0.5f, 50.0f, 1.378f, 0.6f));
l_position += float4(l_positionOffset, 0.0f);

Again with the function I was able to more easily make more of these. I ended up with 4 of these distortion lines.

Overall I like how it turned out. I can tell a programmer did this because all of the effects are overemphasized. I feel like an artist would turn down a lot of what I did. But it looks good and it was fairly easy to manipulate.



1 comment: