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.