Friday, 22 July 2016

Jumpscare != scary - How horror games devolved into peek-a-boo simulators

The concept of genre is interesting, when you think about it.

It harkens back to the need within human psychology to label everything, to categorise and organise so we can better understand everything around us. In terms of genre (and especially video-game genre) these labels exist to help use sift through the literal millions of games released throughout the years. Action games, RPG games, adventure, puzzle, etc. You name it, we've got it. We even have hybridised combinations of genres, like puzzle adventure or action RPG. These are results of brilliant and innovative people who decided to experiment by combining established genres together in clever ways. As an aspiring developer myself, I salute these pioneers of our industry!

(Cue patriotic music and bugle flare)

The problem I find though, and the point of me writing this, is that there seems to be one genre that refuses to budge and evolve in any meaningful way: the horror game. In fact, it seems to have devolved; most 'horror' games nowadays consist of setting up a spooky environment (i.e. Haunted House, cursed mansion, 'it's all a nightmare dream', etc.), having the player wander around aimlessly for a few minutes, popping in a disfigured creature on the screen with a scream and insta-killing the player back to main menu.

To me, this is a clear step backwards in game design standards as far as horror goes. Especially considering how, over 10 years ago, we had far superior titles like Silent Hill and Resident Evil that actually scared players without needing such 'jump-scare' moments. These days, I hardly ever witness or hear about a horror game in years that manages to convey that vital feeling of trepidation and dread that should accompany you throughout gameplay.

These days it's all 'oh no there's gonna be a jump-scare... Ah! There it is! OMG that was so scary! xD'.

Sigh.

Let me clarify this right here and now: what you experienced was not scary. What you experienced was startled. A feeling of surprise that, while similar, is not the same as fear.
My primary point of concern and annoyance with this is that the the general public, and even the development industry itself, seems to have convinced themselves that this is what a horror game is. I won't even get into the indie horror scene, as that field is so full of generic jump-scare games that it feels like looking into a cloning factory. But even the latest Resident Evil teaser, while being generally well put together and intriguing, simply has the player wonder about for a few minutes before getting knocked out by a deranged-looking man. The player never feels tense, oppressed or otherwise fearful while meandering about the environment.

Now admittedly, this is a fairly petty argument in the first place. Not only is it arguing semantics, it seems somewhat preposterous when you consider that all things horror tend to go the jump-scare route. Look at any horror film, amusement park ride or even novel, what you'll find as the common theme of the reliance on jump-scares to entertain their audience. Does this mean that I'm wrong? Am I simply whining about nothing?

I say no. Because while novels have jump-scares, they often spend paragraphs or chapters building a ominous atmosphere beforehand. Also, most horror novels rely far more on descriptive the horror in detail to scare the readers, providing subtle and cerebral scares instead of sudden lights and noise.
Amusement park rides contain mostly jump-scares, with workers dressed as ghosts or monsters providing most of the interactive jumps. But this is largely due to park rides having a very small window to entertain you, much smaller than other mediums. As such, they use the quickest and easiest way to scare and startle people; namely, jump-scares.

Horror films are the easiest comparison to video-games, since they are both visual mediums using sight and sound. Looking at horror films, it does indeed seem like most of them rely on a repetition of 'silence -> tension -> jump-scare' to propel their plot.
That is, until you look at international films.
Many European horror films,and especially in the case of Asian films, use grotesque imagery and a constant threat of the villain to create an ominous, panicky atmosphere that is seldom imitated in western horror films. There may be some bias here, but having seen several Japanese horror films (considered by many to be masters of horror) I can guarantee you will never see a blonde woman scream as a monster slashes up her friends, buckets of blood splashing onto the screen. No, the horror seen in international films is one of subtlety, of implied terrors lurking beneath the surface and the audience being plagued by uncertainty and hesitation. If jump-scares are used, they are used sparingly, and the screen does not cut to black every time the monster pops up for an ambush.


Some rebuttal of other counter-arguments:

  • "What do you mean? I felt scared the whole time I was playing (insert jump-scare game here)!"
No, you didn't. This may sound condescending, but it's true.What you felt was the tenseness associated with the anticipation of the next jump-scare. This feeling is, while similar, different to the feeling of dread and trepidation that you would feel in actual horror games. Again this sounds condescending, but by actual horror games I refer to games that maintain the same feeling of tenseness and anticipation without completely relying on jump-scares.

  • "There's no point arguing about this, since 'horror' and 'scary' are subjective and everyone experiences it differently. You may not find it scary, but other people do."
Well yes, that's true; fear is a purely subjective emotional response, and what is or is not scary cannot be definitively determined as a single thing. But while true, this argument is irrelevant to the subject at hand. Why? Because it's clear from a game design perspective that all these jump-scare games, even the AAA ones, have a clear goal in mind; to startle you. Everything in its gameplay loop feeds back to that single moment of 'BOO!', which provides a momentary high of emotion. But, once that high moment ends the tension drops all the way back down to ground-level, to the monotony and tediousness of bumbling around in a room. this would be fine if the game escalated its high moments each time, if each jump-scare was somehow new and unexpected, but no. It's always the same animatronic monster / little girl ghost / disfigured creature, and the game doesn't even try to go anywhere beyond that.


The overall point with all this, or the TL;DR version, is that horror games are slowly turning into long, drawn-out games of 'peek-a-boo'. Horror games are not, or at least were not, about players being stuck in a purgatory of being startled and instantly killed by a cliched monster that shows on screen for a half-second while giving you hearing damage. You can use jump-scares occasionally, since they are a legitimate tool for tension and entertainment. But please developers, don't let that be the only party trick up your sleeve. Learn other techniques like creating an atmosphere, placing subtle scare details, and designing a game the propels itself forward rather than repetition.

If you want to make a horror game, make sure the game you make can stand on its own without needing jump-scares.
Because if it can't, you haven't really made a horror game.

Monday, 20 June 2016

Planetarian ~ The reverie of a little planet ~

Until recently, I was a game reviewing critic. Sort of.


I won't get into details, but I was let go from an online game review website similar to the likes of IGN or Gamespot. I'm not actually sure if I can claim I was fired, since it was a voluntary position with no salary; the site was founded by a friend-of-a-friend, and only recently so. But I digress.

The point is that this post is a review, and one that I would have submitted to the site if I hadn't been 'fired'. Coincidentally, I don't know if anyone actually bothers to read my blog. I highly doubt it to be honest. But if you do; firstly, thank you. Secondly, I apologise for the lack of content (I mostly write this for my own amusement and to record my musings). I do try to make the posts interesting in case anyone does read, so there's that. But again, I digress.

So yes, the review. At the time I wrote it, I had just finished a Visual Novel (aka kinetic novel, or VN) titled Planetarian ~ The reverie of a little planet ~ on Steam. VN games are an interesting topic on their own, and many have differing opinions on whether they count as video games. Personally I think it's more akin to a book that you read on a PC, so this review focuses entirely on the game's plot.


The plot, without spoiling, is essentially a small character drama. In the far future, humanity has ravaged Earth and themselves via drone warfare. Only the ruins, the automated killer drones, and a small population of survivors remain. Amidst this apocalypse, an unnamed male scavenger, the 'Junker', stumbles on a girl in the remains of a planetarium. The girl, Yumemi, is an android, and this meeting changes the Junker's fate forever, etc. etc.

Overall the story is about 2 or 3 hours long, and developed by a Japanese Development Studio know as Key. I'm familiar with their work (Clannad) and being Japanese myself, I read the entire story in its original Japanese writing; a small detail to note, since English translations may alter the tone or meaning of certain scenes.


So, did I like the story?

Ehhhhhhhhh.

I find myself in a difficult situation. On one hand, its a game developed by Key. If it's a game by Key, It's bound to have compelling story in it. To be fair the writing was actually pretty good (excepting the occasional over-reliance on exposition and unimaginative prose). So I really should like it and recommend. On the other hand.... I simply didn't. I didn't care about the characters, I didn't care about the situation they were in, and frankly I was more interested in the small flashback scenes fro the war.

Personally, the main problem for me lies with Yumemi's character. The problem being that she doesn't really have one. Her main character traits are that she's overly optimistic, innocent and chatters constantly. Unfortunately, these are immediately tied to her being a 'programming error' rather than any genuine personality. She's optimistic because she's programmed that way. She's innocent because her programming doesn't allow for any unnecessary learning. And it's explained that her talkativeness is an actual program bug that was deliberately left unchecked for 'cuteness'.

I was often left confused and frustrated by the story's attempts to characterise her, then immediately reminding us that her 'thoughts' are retelling of given knowledge stored in her data-banks. This implies Yumemi has no internal understanding of human concepts like happiness or sadness, these emotions are not original thoughts that she can experience. Instead, whenever she is 'happy' Yumemi is simply following programming routines telling her she is supposed to be happy.

I was particularly baffled by her apparent understanding of religion and heaven, having learned of the concept from the planetarium staff. Does Yumemi actually believe in heaven and prayer? Does she even understand the concept of religion? What about death, and mortality? The game writers seemingly attempt to display her understanding in the final scenes, but even that left me dubious as to whether she actually understood it or was just re-enacting expected behaviour based on prior knowledge.

All of this leads me to think that Yumemi is not human a character, or even a robot with the miracle of human thought or conscience. She's nothing like Robin Williams in Bicentennial Man. No, Yumemi is simply a machine following it's programmed directives. In short, Yumemi  is a 'thing', not a person we can relate to.

So if we can't relate to the heroine, that's just leaves the hero. Thankfully, The Junker is immediately more approachable on account of him being human, and dealing with the struggles of a post-apocalyptic future. I actually liked his recounts of his time in the war, having nightmares about being in combat and remembering his time as a war orphan. These little snippets help build both the character and the world around him, plus struggling against adversary is a very human and relatable topic.

However, that was it. And by that I mean those little snippets was all The Junker had going for him. All we, the reader, ever know about him is that he is an orphan, a war veteran and is generally cynical about everything. That's about as generic of a character archetype you can get without adding 'grizzled beard and voice to match'. True, his meeting with Yumemi and (spoiler-free!) the eventual catharsis of the events that follow are touching, but even those events are typical character arcs that haven't been explored before. The Junker just feels very flat and boring as a character, and if it weren't for the fact we know he's human I'd suspect him of being an android too.

Overall, all I can say is that an interesting concept and a theme of human connection do not a good story make. It did cause me to ponder on artificial intelligence, and at what point we consider a robot to be 'human', but I am fairly sure that Yumemi is not a that point. Add to that a protagonist of 'Cynical Survivor Category 29 Subtype A' and we have a narrative that is generally dull and colourless, despite the unique twist of AI; and let's face it, even the 'AI + human connection' concept isn't exactly original.

Perhaps my expectations were too high for this game. I had heard it was a KEY game, and having enjoyed his previous works I expected something of a similar quality. I will, therefore, say that if you are unfamiliar with KEY or visual novels in general and want to give it a try, be sure to start with Planetarian ~ The reverie of a little planet ~ . It's a very good example of the drama and emotion you can infuse into a video game, proof that it's not always about guns and killing. This is particularly with a genre like VN, where most VN titles involve more mature content (I'm currently reading one about a young man trying to succeed on the stock market).

However, for me this VN left me a little disappointed, and a little nonplussed that it tried to pull my heartstrings with a story about a broken-down robot.

Friday, 22 January 2016

Short story time!



 ( felt like writing it)



‘Ben’ is a young man living in the city. Ben is depressed, suicidal, and incredibly tired of the life he is living. He lives a monotonous life, filled with the same routine; get up in the morning, go to work, spend his day doing things he resents, and go home to sleep. every day he day dreams about 'ending it', giving it all up and just sleeping forever.  Because God knows, he is tired.

So very tired.

One day, he daydreams that he steps in front a speeding bus on his way to work. Another day, while getting dressed for work he imagines himself using his tie to hang from the ceiling. Finally, on his way home from work he picks up a gun he had purchased. Next day he goes to his office, the 17th floor of a large corporate building. Its floor to ceiling windows gleaming, cold and emotionless like the world it belongs to.
 Ben wastes no time. gripping a sharpened pencil, he calmly stabs his next-door neighbour, a co-worker crammed into his tiny cubicle. Before anyone has a chance to react, Ben removes the gun from his suitcase. Blood, screams, tears. This, Ben finds relaxing. He finds it invigorating. He finally feels free.

Sadly, reality does not agree with his view. Has it ever? When he hears the police arrive, sirens blaring, Ben knows he is doomed. He will be arrested, placed on trial, found guilty in a matter of minutes and sentenced to prison. Taken away from the glimpse of freedom he had just witnessed.
Unless. Yes. This is the prefect opportunity. Ben had always been too cowardly to actually kill himself. Too weak, too scared. But the arrival of the police give him the perfect excuse.

Reaching the elevator, he takes it for one last trip to the rooftop. Pressing the button, Ben closes his eyes and smiles. To be able to do all this, break away from the usual routine and do what you want, is all he could ever ask for. He wants nothing more from life. He is content.
The wind is defeaning, and he can still hear the sirens below. But all Ben can see, all he cares about, is the bed. That bed, floating mere inches from the edge, waiting for him. Calling to him. Begging him to just rest.

Because God knows, he is tired.
So very tired.

Tuesday, 1 September 2015

Master Reboot

So, for the record, I'm still alive.

I'm still here.
Not everyone would be happy to hear that, but to hell with them.

Opening this blog once again, I notice that the last post was on 7 May. It is now September. Where the HELL did the time go? I seem to vaguely remember July... and there was that one day in August... But honestly, I feel as though I got in to the passenger seat of a Delorian and took a nap.

Of course, none of what I just said(wrote) is true; I'm just being facetious in my trademark, lovable way. I recently was hired / volunteered to a position on a game news website as a journalist. Which reminded me that hey, I used to write a blog; hey, I should look at my blog; hey, I should talk about what I've been up to on my blog. So, what I've actually been doing recently is two things: thinking about my game, and thinking about Game Design in general.


1. The Game

By 'the game' I refer to that project I was working on, 'Haunted Within' a.k.a 'Project Zoe-trope'. At the moment, it is technically a finished product and is therefore a closed project. But the product I'm left with, unfortunately, is far from what I had imagined in my head and I really do want to keep working on it. Which is why I spend most days thinking up improvements, changes, little design additions that would flesh out the overall feel to it, etc.

There are, however, a couple of problems. One is that working on a customised c++ engine was really tiresome, let alone building a whole game based on that customised engine. So I thought to myself, "Let's port everything to Unity!" and installed Unity 5. the problem here is that porting to Unity means discarding everything I've worked on and, essentially, starting again from scratch. May I just say, as a solo developer relying on self-discipline for morale and time-management, doing such a thing is mighty disheartening.

So all my time is spent thinking about doing it and never actually doing it. This is one my major flaws, in that I find it difficult to start anything. Once I get going I'm prepared to march on, but taking that first step is, for some reason, very challenging. I'm sure I'll eventually get around to it; I usually reach a point where I become fed up with deliberating and just jump-start myself into action. I just worry that when I do get started, I won't be celebrating my retirement as well.

2. Game Design

This is more of a nebulous, back-of-my-head thought more than anything, but it is something that has been weighing heavily on my mind for a while now. See, I know a lot about making games. Or more specifically, how to develop games. The problem is, I'm not too sure on how to design them. I have the hammer, saw, nails, and I know how to use them; but designing a house so it looks nice and stays upright? No clue.

Which is why I've been trying to learn more about Game Design in general; the philosphies, the princinples, the techniques and tricks often used, that kind of thing. This is another reason I've held off on working on a project; instead of making another game that functions well but is shoddy in design, I'd rather learn about the pontential pitfalls first so I can avoid them.

Because let's be honest, Haunted Within as it is right now is... well, it's not the prettiest to look at. I figure it's better to take a step back, re-examine all its facets and point out all the bits and pieces that may not be so great.

Thursday, 7 May 2015

Self-Reflection Sit-Rep

It's been almost 2 months since I began this blog, and I've evolved from feeling blue to feeling introspective. We've had some fun, we've had some laughs, and we've o so much ranting. But now, it's time to sit back, gaze upon our work and think to ourselves "...What was I thinking...?"

Let the introspection and self-reflection commence!

Disclaimer

Let me start off by saying that any praise I give for myself, is tempered by the fact that I made mistakes more often than I succeeded. I like to consider myself a genius, coding savant, but the truth is that I'm really... not. I've only been at this for a few years and I'm full aware I'm not the best. I have a lot more to learn, and so many areas I need to improve in. So if I come across as arrogant and smug, just know that I'm being facetious. Every good point I raise should be taken with a fistful of salt.


AI

So the first task I tackled was AI programming. This was an aspect of coding that I was always interested in, and it's actually the reason I began programming in the first place. Trying to simulate thinking, breathing human behaviour inside a computer fascinated me. That being said, I had never actually tried to program a proper behaviour algorithm before. So trying my hand at programming AI for bots in a fully-automated tournament seemed like an exciting challenge.

Having said that, however, I think I handled this particular discipline of coding rather well. Although I had never programmed a specific AI system before, I had tried my hand at basic behavior algorithms; collision avoidance, chasing targets, Finite State Machines and the like. In particular, the actual mechanics behind the high concept of 'Heuristics-based pathfinding' was much easier than I had first thought. I was worried that this would be the most difficult aspect of AI, but the dynamic list creation and iterating thorough multiple custom objects was something I was very familiar with. Overall, I believe that having prior understanding and knowledge in how to achieve these algorithms allowed me to progress in my code much more smoothly than I would have otherwise fared.

The downside was, as always, over-scoping and poor time management. I had originally planned to do so much more in the field of AI, including the implementation of a fairly complex finite state machine that enabled / disabled specific AI sub-routines. This concept came from my research into GOAP, and I had planned to create a simplified system that still followed the same basic principles of GOAP. Unfortunately by the time I had managed to perfect my A* pathfinding, my time had run out. I was forced to quickly cobble together a basic FSM that selected the next pathfind destination, and that was all; a farcry from my original vision.

The silver lining here is that this error was not very significant in the grand scheme of things, and only occurred in the first place due to my relative inexperience with AI. Now that I have a much better understanding of what I'm doing and how to get the code working, the time it takes to complete each individual task should be considerably shorter. If I was to try something like this again, I'm confident that I can get more done within the same timeframe.

Game Dev

The other major task I must ruminate upon is the Game Development Project, in which I and several others collaborated to create a game. I was in charge of basic game-play code (movement, collision handling, items, etc), as well as graphical effects; namely the god ray shader. I had originally assumed that developing the scripts in Unity, seeing as how I was familiar with c# and had used Unity's system before. This would have been true had I opted to develop things properly, and not half-heartedly decide to use the Rigidbody physics in conjunction with everything else.

Oh boy, what a mistake that was. In hindsight, I have no idea why I decided to develop ALL game-play related code based in the physics simulation. I seem to recall thinking that since 2D platformers involve gravity, using physics within the code was the logical choice. Of course I realise now that this was definitely not the right way to go, and in future I'll be sure to take note of this valuable lesson.

Now, he shader part of my involvement in the project was very good. As I've stated before, I'm rather proud of what I've managed to achieve with the limitations of Unity Free. I don't think I need to reiterate the positive aspects of my work, and if you, o reader, require a memory refresher you can refer to my earlier blog posts.

However, this is not a self-reflection of the work I did; this is a self-reflection of how I approached the work I did. And i this regard, I may have made yet another mistake. You see, because I was so enveloped in my own work, I sort of uh... neglected, my other duties. I worked on the code within the shader for 4 days straight, barely sleeping or eating. This attitude and style of work was fine in previous projects; since they were solo undertakings, the only consequence was the delay in schedule. Howe3ver, as part of a team I was responsible for keeping in communication, remaining update on current progress, and being available for assistance in various other tasks.

Obviously I failed to tick off any of these requirements, and this I can only attribute to may lack of experience working in a group. Because I am usually only involved in solo projects, I am not accustomed to contantly communicating with others whilst developing. This is something I can only improve on with experience, and I can only attain this epxerience by participating in more group-related projects. However, I will try to keep this aspect of teamwork in mind when a similar opportunity arises once again.



The End

So there we have it, my thoughts on how I behaved during the past 2 months. Overall, I'd say my work ethics and attitude was up to standard, despite the occasional slip-ups. I will make it clear that whatever the mistake was, it was not made intentionally. I approached things with the appropriate attitude, I worked on my tasks diligently, and attempted to assist my development team in any way I could. So  I suppose all the errors, at the end of the day, can be chalked up to inexperience and naivety; I arrive on scene with the right mindset, but I simply do not know enough and have not experienced enough, to get the job done perfectly. It will take time to get it right, but I think that being able to recognise 'I am inexperienced' shows I'm on my way to improving already.

Monday, 4 May 2015

Good News or Bad News?



The past week has been... tumultuous.

On a scale of 1 ~10, I've had a really good moment that brought the week up to 8, only to be followed really bad things that drop it down to 2. At the end of it all, I am currently sitting on a solid 5, a very half-hearted "meh". If you'd be willing, o reader, I shall regail to you the sad sorry tale that is my life so far. Starting with the good news, since I'm such a cheerful optimist.



The Good News

I finally managed to get a God Rays post-processing shader working in Unity, using nothing but the tools and functions available in Unity 4 Free Edition. In the beginning I thought it would be a simple task; simply render the scene to a render texture (a feature that very much exists in Unity), apply a hand-written shader effect to it using Unity's built-in custom shaders, and voila! Pretty visual effects! Of course, I'd failed to read the fine print that stated all this was only possible in Unity Pro. Therefore, I had to get creative.


1. Capture the entire screen display into a texture

 This process is, conceptually, identical to rendering the scene into a texture. The key difference is in the method; 'capture the screen display', not 'render the scene'. Because render textures were unavailable, I was forced to perform another function that produced similar results: ReadPixels. I talked about how this functions works previously, and how expensive it is... No kidding, I'm forcing an extra draw call to be performed entirely by the CPU. I managed to optimise it by running the function in a sub-routine thread, but using this technique still dropped the FPS from 120 to about 50. It pained me, but it was necessary.


The worst part is nothing has seemingly changed (-____-)


2. Run Shader Pass A: 'Occlusion'

Once I'd managed to somehow cobble together an image I could work with, I began my work on actually writing a shader to edit this screenshot texture. The good news here is that Unity's shader language, Shader Lab, supports multiple render passes in a single draw call. This made it much easier for me to layer the separate effects I needed to achieve my end goal of God Rays. Now, the first thing one needs to create a God Ray shader is to create an occlusion pass; essentially, draw every object in the scene as solid black. this allows us to represent everything that will be blocking (occluding) the light as it shines through.

Achieving this in a shader is, to be honest, a cakewalk. Simply sample the base texture, and for every pixel that has an alpha value, render black.


Finally, some visible changes!


This method relies on the fact that the screenshot / render texture will, when drawing the scene, only modify a pixel if it sees that an object occupies that pixel space. If an object exists, it will be rendered to the texture (alpha = 1.0); if not, the render texture will not edit the pixel in any way and leaves it blank (alpha = 0.0). Therefore, if the sampled pixel has an alpha value it must mean there is an occluding object occupying that pixel space.


3. Run Shader Pass B: 'Lighting'

Once the occlusion pass was in, I wrote the next block of shader code: lighting. This is just the simple 3D directional lighting technique used in all languages, so I won't go into too much detail about it here.It should be noted though, that I wrote the standard vertex-based lighting model from scratch. Since Unity already has the phong shading and blinn shading models built-in, it may have been easier to use those instead of writing a model myself. However, as with all pre-built code I dislike not knowing how the logic flows internally. As such, I felt more comfortable writing one I knew would work than trusting Unity.


I see the light! Hallelujah! 


4. Run Shader Pass C: 'Blur'

Last but not least, the radial blur. In order for to simulate the God Rays effect, a radial blur is applied to the whole texture with the blur originating from the light source. Or more accurately, where the light's position is in screen space.  This involves passing in the light's position in-game and translating that into screen space, disregarding the z-pos since we are working with 2D textures. Once the light position is found, we set that as the origin for a radial blur that decays in strength the further from the origin. Something along the lines of:

void main()
{
 pixel_position = texCoord[0];
 delta_pixel_position = pixel_position - light position;
 color = renderTexture.sample(pixel_position);
 
 for(int i=0; i < NUM_SAMPLES ; i++)
 {
    pixel_position -= delta_pixel_position;
    new_sample = renderTexture.sample(pixel_position);
    sample *= godray_strength_decay;
    color += sample;
 }
 
 color out 
}

This site also helped.

 ...It's... it's so pretty...!


I'm rather proud of the results to be honest, and I'll more than likely use the technique again in future.... Actually, no I won't. In future I'll just use an engine that has render textures to begin with, save myself the numerous headaches. I briefly talked about some of these headaches previously, so I won't devolve into another rant here. Needless to say, I still very mush dislike working with Unity. if it weren't for its layout and the relatively intuitive component system, I'd never look at it again.



The Bad News

...Aaaand here comes the downside. So as you can imagine, when I had completed this wonderful project of mine I was ecstatic. I was cheering, I was laughing, I even did a little dance. Best of all, this tech that I had managed to complete was to be displayed to the public in a Games Exhibit! I could see my work proudly displayed, and people would see me for the genius, coding savant that I am!

"This calls for celebration!" I thought, "break out the liquor!"


...Yeah.

Two shots of Tequila and half a bottle of Whiskey later, I awoke to find that the whole world was constantly spinning and my legs had transformed to jelly overnight. I could barely walk without feeling nauseated, let alone making it to an exhibit on the other side of town.

Sigh.

It really is my own stupid fault, and that's why I'm feeling rather blue at the moment. I had a wonderful opportunity to see my own work on display, and I miss out on it being a drunken idiot. I can only hope that the exhibit went well and I didn't screw everyone else over by not being present for the preparations. My apologies if I did.


I think I'll quit drinking.

Monday, 20 April 2015

"That's not right. It looks pretty, but it's not right."

Oh shaders. How I love you so. And I mean that in 'the abused housewife still loves her husband' kind of way. I think this, once again, confirms my suspicions that I am a masochist.

So last week I began my journey into the perilous realms of Terra Unity Morte, specifically in the aspect of custom shaders. My plan was to create a God Ray Post-Processing shader, and it was a fairly straightforward one.

The Plan

Step 1. Create a new render texture, render the scene onto it
Step 2. Iterate through each pixel. If the pixel alpha is larger than 0 (ie. object exists) then draw the pixel as black (Occlusion Pass)

Step 3. Draw lighting shade onto every other pixel, ignoring the occludes. (Lighting Pass)

Step 4. Apply a God Ray effect (Effect Pass)
Step 5. display the material with render texture on a screen sized quad, placed in front of the scene with alpha blending (Scene Render)

Step 6. Pretty!



Unfortunately, at this point old man Unity came along and looked over my plan.
"Nice plan you've got here," it noted, "It'd be a shame if.."

Unity's answer to my plan

Step 1. Disable render textures in Unity 4's free version (what I am using)
Step 2. Set shaders to outright ignore alpha values by default, drawing to RGB channels only
Step 3. Allow multiple passes in a single shader, but texture samples for preceeding passes will refer to the newly rendered texture with previous pass effects

Step 4. Most (if not all) Post-Processing effects, including God Rays, require the use of multiple render textures, not just one

Step 5. updating a quad's position every update to remain in front of the camera will cause issues with physics (for some reason)


Satisfied with its work Unity wandered away, leaving me to weep over what remained of my plan.



So yes, there were issues.

Render textures not being available was the biggest one, since that is the core ingredient of any Post-Processing effect. I eventually settled on a CPU-based alternative, ReadPixels(), which uses the CPU to read every pixel currently on screen and dump the data into a 2D texture. If that sounds like an extremely expensive operation to you, that's because it is. I am essentially performing a screenshot after every frame, manipulating the screenshot, then re-rendering the edited screenshot into the game. Good God.

The second biggest one is the frankly labyrinthine system that is ShaderLab. In the spirit of all things Unity, this system attempts to be 'User Friendly' by automatically performing several functions for you. That's great, except that I now have no idea what is actually happening when the scene is rendered. It was only after hours of researching that I discovered shaders only render RGB by default, completely ignoring the alpha channel. Any transparency can only be done via alpha blending, and alpha-inclusive renders can only be performed under certain settings with the right flags declared. Overall the thing is so unintuitive I feel like Theseus wandering the Minotaur's Maze. Except I don't have Ariadne guiding me with a piece of string.


Still, I have managed to get somewhere. It's far from what I want, but I am currently up to step 4 in my once-foolproof plan. It's very slow going since I have no idea what will actually be rendered 90% of the time, but that's less to do with Unity and more to do with shader coding in general. I'm hoping that I can get to at least a passable rendition of the effect I want, at which point I will declare victory and look the other way.

And to think, all this could have been void if we had used Unity 5.



Some very incorrect (but nonetheless pretty) render results