OwenTheProgrammer

I love programming computers and every JSP in between.

Hello, my name is Owen and I have been studying interesting topics over the entire course of my life. I love learning new things as long as I know they will be useful, since learning things that are pointless is pointless in itself. I've been studying topics such as Apple's watch pairing system, Huffman trees, alpha hulls, MPEG-4 codecs, PNG codecs, MLS fluid simulations and other topics I needed to learn as either preliminary foundations or something that was part of a project.

switch ( *(Showcase*) &InterestingProjects ) {
case "A VR demo game":


I made everything in this game within a couple of hours. All the lighting is baked and everything is interactive. When I updated the Unity project, things with collision broke but I think I've remedied those issues.

break;
case "Turning Tables":


I'm working on a Steam game at the moment! It's a co-op multiplayer game where each of the moveable objects are controlled by different players, but it doesn't tell you who has what piece bound to their controls. I would give more info, but a lot still isn't fleshed out yet and I want to finish it more before I release anything major here.

break;
case "InOut: A simple factory game":


One thing I love to do is take a trivial game idea and make it scalable to the point where people look at it and wonder how it still runs. Having several thousand things going on in front of you within a fraction of a second. One of the first games of mine to use this style of development was InOut. There are 100 items that you can make with machines called "Operatives". The real computational issues that are usually overlooked come in when you start implementing things like track systems. I had a few tricks up my sleeve for keeping the game performant and interesting and I wanted to show you them!

A simple clock right?

Not really. I wanted each clock to work efficiently since it's one of the items, and there could be thousands of them on screen. The same goal goes for all of the items in InOut, but what makes the clock so different? Let's start with the model. Since each submesh I add would make another draw call or make the existing draw call exponentially slower, I wanted to make each of the item models a single mesh.

The model has a vertex colour map used as a flat colour image similar to an albedo map. The rest is in the two UV channels: "DisplayUV" for the time display and "ShadeUV" for baked ambient occlusion to add some shadows.

Since all of the items are GPU instanced with Unity's Graphics.DrawMeshInstancedIndirect, I made all instances reference that one texture. All the models were a bit static and invariant coming out from the buy tracks. having no rotational randomness was boring until I made some attributes to the shaders so I could rotate them randomly from the vertex shader. This loads the mapping tables from "ClockData.bin". If it's 12:00, array 1 will use index 0, {0,2, 0,3} which are four byte indexes for the display colours which are in array 0. Assets here

            struct InputData {
                float4 vertex : POSITION;
                float4 color : COLOR; //Vertex Color
                float2 uvd : TEXCOORD0; //DisplayUV
                float2 uvs : TEXCOORD1; //ShadeUV
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };
            
            struct v2f {
                //SV so the Console devs don't complain lol
                float4 vertex : SV_POSITION;
                float4 color : COLOR;
                float2 uvd : TEXCOORD0;
                float2 uvs : TEXCOORD1;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };
            
            v2f vert(InputData i) {
                v2f o;
                //Use vertex program indexed for this object
                UNITY_SETUP_INSTANCE_ID(i);
                //Get all instanced variables
                float irot = UNITY_ACCESS_INSTANCED_PROP(Props, _ItemRot);
                float ipx = UNITY_ACCESS_INSTANCED_PROP(Props, _ItemPosX);
                float ipy = UNITY_ACCESS_INSTANCED_PROP(Props, _ItemPosY);
                float iscl = UNITY_ACCESS_INSTANCED_PROP(Props, _ItemScale);
                //transfer info from host to GPU as instance
                UNITY_TRANSFER_INSTANCE_ID(i, o);
                float r = radians(irot);
                float s = sin(r);
                float c = cos(r);
                //Rotation matrix (y)
                float3x3 vmat = { c,0,s,0,1,0,-s,0,c };
                i.vertex.xyz = mul(vmat, i.vertex.xyz);
                //Animation offset
                i.vertex.xz += float2(ipx, ipy) - 0.5;
                o.vertex = UnityObjectToClipPos(i.vertex * iscl);
                o.uvd = TRANSFORM_TEX(i.uvd, _DispTex);
                o.uvs = TRANSFORM_TEX(i.uvs, _ShadeTex);
                o.color = i.color;
                return o;
            }

Even with all these complexities and custom tools,
I'm still very excited for the day I get to press "Release"

break;
case "Same output, faster code":


Sometimes when I don't know which function or code block is faster, I go to Compiler Explorer and compare assembly wise which is the faster function. For instance:

if(rotation >= 360) rotation -= 360;

(runs faster)

rotation %= 360;

(more readable, runs slower)

It's really useful when used in something like microcontrollers or for VR games running on lower level ARM CPUs found in headsets like the Quest and Quest 2. It might not be visible, but it makes my heart happy knowing someone can play VR with frame times milliseconds faster because that random code block took thirty clock cycles instead of fourty :)

break;
case "TrophyTheElephant: Stretching the GPUs incomprehensive power":


(Who needs a CPU anyways?)

This project is the hardest computational project I have worked on so far. There is so much that can happen but I want it to run at a solid 60+FPS. Just the trees alone broke the game, which means I started to think about moving it to C++ to try and remove some of the issues I was having. When making the trees, a tiny bug where the whole game does not run at 60+FPS came around. Some of the implementations I tried were "Impossible" -Unity developer (really gives me hope!) when bringing in some new ways to implement what I wanted to do.

One tree is fine, ten-thousand wasn't. It would do this funny little jig any time I'd try to make it move my camera, run the game, etc. Task manager always has a sawtooth wave in the GPU usage, right?

break;
case "Vulkan; The post mortem to going insane":


Most of my issues turned out to be from 110% (yes 110%) usage on my graphics card, but that usage wasn't stable. (It looked more like my sleeping schedule over summer break.) Unity is great, but I wanted to be able to control every little buffer since what I was asking for was difficult. I also wanted to know what was possible when you go through the lengths to write everything yourself from scratch. Since InOut was the most compatible project to convert to Vulkan C++, that's what I targeted the project towards. Here is that project that took three days just to get a window running. was worth it. Tens of thousands of FPS sounds good to me.

Of course it's roughly a year later and I'm still working on InOut. I have restarted three times as of now and moved the engine to C instead of C++. I want the game to be the best I can make it, that's what I strive for.

break;
default:

So... Now what?

My life is in a funny little local plateau. I want to work on my projects equally, since they are all really cool, but when I saw some of the game companies I loved were hiring, I dropped everything and started making this. I have plenty more where this all came from (after my nap that is, I have been working on this for roughly a month). update: it's been five months. Of course these aren't all the projects I have made, but they are a good mix of what I have done in the past while.

break;
}

Like my work? email me at: OwenTheGameDev@gmail.com