Jump to content
  • entries
    99
  • comments
    279
  • views
    154442

The Poor Man's 3D Camera

Sign in to follow this  
evanofsky

1331 views

Each of us have our own giants to face. This is a story about one of my giants. Something I never imagined could make a grown man cry, until it did.

A 3D camera.

No one can face your giants for you. This is a story, not a walkthrough. Expect no useful information. For that I recommend 50 Game Camera Mistakes by thatgamecompany's John Nesky. His job title is literally "camera designer".

The story starts in 2014 with a seemingly harmless seven-day game jam.

7DFPS 2014

Exhausted from crunching on my first game, I decide it would be good to take a break and make a first-person shooter for 7DFPS. This is a terrible decision.

The idea is simple: an FPS where you are the bullet. Click to jump from wall to wall. If someone's head happens to be between you and the next wall, sucks for them.

DampBleakFoal-size_restricted.gif

The main problem is that, when you shoot to a new surface, the game necessarily buries your face directly into that surface, filling the whole screen with a solid blue color.

You can see my first solution above. After landing, the game "reflects" your direction off the surface you landed on, and tweens the camera to face the new direction. So when you shoot into a wall head-on, the camera does a complete 180.

Of course, I can't place the camera directly on the surface, or there would be clipping artifacts. So I space the camera a bit out from the wall, which leads to another problem:

aY7cZO7.png

Here the extra space between the camera and the surface allows you to aim at any location on the surface and launch there. In theory, your "character" is actually flush with the surface, which should make this physically impossible.

I throw a band-aid on this problem by clamping the camera so that it can't aim at or behind the surface it's attached to.

1U8bJaY.png

I end up working 96 hours in a week to finish this masterpiece that will surely take the world by storm. Two YouTubers play it for a grand total of 10,000 views. Like every good vacation, the experience leaves me exhausted and depressed on Monday morning.

Over the next 8 months, I finish my other game, take an actual vacation, then, instead of throwing away the Unity prototype like any sane person would, I start rebuilding it in a brand new custom C++ engine.

The new game is an expansion of the prototype, which means more features, more gameplay, more pain and suffering! One of the first new features is the ability to crawl along walls, floors, and ceilings:

2d5U09X.gif

A couple months later, camera problems start to manifest. As players crawl around different surfaces, I have to forcefully nudge the camera to keep it from staring straight into a wall. I use spherical linear interpolation (slerp) to smooth out the transition between angled surfaces, but it's still not great.

In the gif below, the player on the right does not manually move their camera at all; the wall forces them to look up automatically.

biuBGod.gif

At this point, everything is completely unreadable and confusing. The first-person view prevents players from seeing their character, and they often take several minutes to realize they're playing as a creepy crawly spider bot. Once they finally get it, they can't figure out why the camera keeps getting forced around, and why they can't aim at the surface they're attached to.

I slap on another band-aid in the form of a shader that blacks out everything "behind" you, everything that's physically impossible to reach. I also have it darken out of range areas.

I4jJmfjl.png

Now the game is not only unreadable and confusing, but also ugly!

By sheer chance, I happen to turn on a debug flag that moves the camera back from the player two units. Literally the poor man's third-person camera. And behold, it was not the worst thing in the world.

V3RFMbH.gif

I finally realize I'm making a third-person game, and so set about implementing it for real.

The Culling Saga

One of the deadliest scourges of humanity, right after Facebook and taxes, is a third-person camera that constantly zooms and bumps around to avoid in-game geometry.

Rather than move the camera, I decide to just cull anything that blocks the camera's view. Half of the job is done right out the gate because my game engine, like most engines, automatically culls triangles that face away from the camera (also known as "back-faces").

I write a shader to handle the rest. It culls everything within a certain distance of the camera.

aMLFI5K.gif

What's that you say? My screenshots look weird with spider bots floating in empty space because the wall got culled?

nkmN4zwl.png

It'll be fine. It's fine. Don't worry about it. What, what now? You can catch glimpses of stuff you're not supposed to see, including the skybox? Look, I'm sure it's just a minor thing.

s3TxXItl.png

Okay. That's pretty bad.

What if instead of carving spheres around the player and camera, I use a cylinder instead? And what if I actually render a solid black cylinder whenever the camera is inside a wall?

eaMvrsS.gif

So close, yet so far. The cylinder blocks out most of the ugly geometry it needs to, but sometimes you can still see through things. I could extend the cylinder to block more, but I would have to clip it so it stays inside the level geometry.

Even now, the cylinder sometimes blocks too much, because I only clip it against the player's current wall.

r1aIcmt.gif

Here I only want the cylinder to block the ugly insides of the ledge. Instead it blocks everything behind the player.

I would have to query all the geometry surrounding the player and clip the cylinder against all those planes. And that's assuming I can figure out what's "inside" and "outside" the level geometry, which is not air-tight. There are overlapping faces, shapes that clip into each other, and plenty of other lazy hacks— I mean, clever tricks.

What if I just turn off back-face culling? Use the same culling shader, and instead of the cylinder, rely on the back-faces to block anything you're not supposed to see. This works perfectly in some cases:

enhQ7kSl.png

Other times it does a great job of showing off my lazy hacks, like this ramp that simply extends into the floor rather than meeting it cleanly:

jQWSryN.png

It doesn't help that the back-faces still receive accurate lighting. Feels like the level is a hollow shell.

Fine. I'll spend a couple weeks welding level geometry together, and I'll render the back-faces in solid black. How about now?

jOQodci.gif

Getting less terrible all the time. With a little depth buffer bias, a special tag in the G-buffer for back-faces, and a few extra texture taps in the composite shader, I can filter out those pesky lines too:

kRTNADh.gif

The gifs above also show off the new culling shape. Instead of a cylinder, which indiscriminately carves out an uncouth shape much larger than necessary:

Oe3SDU5.png

I switch to a cone, to ensure I only cull things what need culling.

5gPG07g.png

But the cone has problems too. It's possible for the player to back up so close to a wall that the cone intersects the wall in an incredibly narrow circle, leaving a tiny hole for the player to peer through.

From somewhere deep inside my repressed memories of Calc II springs an exotic mathematical creature known as a paraboloid:

Lekbh9b.png

A quick trip to the grimoire to remind myself of the formula, a few incantations in a darkened room with a mirror, and the creature is summoned into GLSL form. The culled circle still tapers a little, but it's enough to see fairly well.

WhZH365.gif

Good enough for government work. Ship it!

UX

UX is, like, super important. Take it from me, a full-stack growth-hacking happiness engineer co-founder. Let me tell you about Our Incredible Journey. At first, the game had a terrible retention rate. I did some A/B testing, streamlined the user onboarding, pivoted to clickbait, bought some fraudulent traffic, and now I'm at $10k MRR. I'm also taking cold showers every morning and learning Farsi on Duolingo.

If you can keep your eyes from rolling back completely and irreparably inside your head, "User Experience" is a decent descriptor for the interactive aspects of game development, the other contender being "Game Feel". It's the thing you can only get by interacting with the software yourself. It's the thing that makes you smile with surprise when you pick up the controller for the first time, even though you've spent the last hour watching someone else play.

It's also basically impossible for me to get right on the first ten tries.

Here's an example of my terrible camera UX. When you hit an enemy player without killing them, you bounce off. The camera instantly snaps around to follow your new trajectory. Of course I slerp the rotation a little, but still, you can barely see it happen.

9YWsk30.gif

I have no reason to lock the camera like this, it's just a carry-over from when the game was first-person, when it made sense to always point the camera where the player was headed next.

It takes someone at a convention telling me what an idiot I am to make me finally unlock the camera. A one-line change that takes a whole year.

oPIJaCk.gif

Later, someone on Twitch yells out a self-evidently brilliant suggestion: let the camera lag behind the player a little when they launch. This also takes only a handful of lines to test out, although the numbers don't feel good until a week or two of tweaking.

QFDlU7R.gif

So many of my design decisions are simply carried over from old and outdated assumptions, even though they stopped making sense several versions ago.

Here's an example. Remember how I clamp the camera rotation to keep the player from aiming at the surface they're currently attached to?

1U8bJaY.png

Turns out this gets old after a while, especially in third-person. People want freedom, they don't want you shoving their camera around. I grudgingly loosen the shackles a bit by clamping the rotation against a cone instead of a plane.

RxbMNDO.png

I use spherical interpolation again to smoothly swing the cone around and nudge the camera away from the wall.

7o6LH1W.gif

Unfortunately, slerp doesn't always rotate the way you want it to. Sometimes the cone pushes the camera in a completely different direction as it rotates to match the surface.

TQ0r4j9.gif

Instead of rotating the cone, I decide to instantly snap it to the surface, but scale it up slowly. So it starts as a thin sliver and slowly expands into a fat cone, pushing the camera out as it grows.

ZsSA78q.gif

Everything's going just swimmingly until Momin Khan asks me... is it even necessary to clamp the camera any more? It made sense when the game was first-person, but that was two years ago.

I immediately get defensive. How else can I keep the camera from staring straight at the wall for 90% of the game? But I slowly realize he's right.

I compromise in the end. I nudge the camera for a split second after landing, then shrink the cone back down to zero to allow glorious unfettered camera freedom.

Rri1dz1.gif Full range of motion, baybee

Now that the player can aim at their currently attached surface, what happens when they try to launch there?

aY7cZO7.png

I eventually solve this problem by allowing spider bots to "dash" along the surface.

gMBdh0h.gif

I have no physical explanation for how they do it. It's a video game.

There's another problem, however. Normally, the game does a raycast starting at the third-person camera and continuing straight through the reticle. When the spider bot launches, it compensates and launches where the player wants it to go, like this:

qnfyOJ1.png

However, sometimes the camera can see and aim at a point the spider bot can't reach.

iyVB9As.png

I solve this by ruling everything behind the player's current surface "out of bounds". I even have a shader to darken the forbidden areas.

7vq39WZl.png Look, Simba. Everything the light touches is our kingdom.

This is really frustrating and confusing to people. Finally Nathan Fouts from Mommy's Best Games tells me to just cheat and let the player go there even if it doesn't make physical sense.

I don't like the idea of breaking my game physics so I compromise by having the spider bot dash to the edge and then fly the rest of the way.

z9JGqOZ.png

It all happens so fast, you don't even notice it. Here it is in slow motion:

lukFBBM.gif

Conclusion

Some tasks cannot be sped up. If I had put "make 3D camera" on a Gantt chart, I would have stopped 10% of the way through this article and called it good.

The point is, most of these ideas are simple and obvious in hindsight, but I had to make a lot of mistakes to find them. It's nearly impossible to coalesce good design decisions straight from the ether. The only reliable method is iteration and trial and error.

Thanks for reading. What embarrassingly obvious design improvements have you been slapped in the face with?

Deceiver is set to launch on Kickstarter in early February 2018. Join the mail list to be notified of its release, or check out the source code on GitHub.

Sign in to follow this  


2 Comments


Recommended Comments

This was an interesting read. I love to read about other people solving their problems. It always sorta nudges my own thinking around about my own stuff.

Share this comment


Link to comment

Yes, thanks for sharing that.  Makes me (and probably a lot of other people) feel a little less stupid for getting stuck in similar design screw-ups.  Although it's nice to get the design right the first time, I suspect everyone needs to do a certain amount of refactoring, redesigning and iterating before finally settling on the 'correct' answer.  And those who get it right first time have either learned from experience with other problems or are just smart-ass geniuses!  ;-)

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
  • Advertisement
  • Blog Entries

  • Similar Content

    • By trapazza
      I'm trying to add some details like grass, rocks, trees, etc. to my little procedurally-generated planet. The meshes for the terrain are created from a spherified cube which is split in chunks (chunked LOD).
      To do this I've wrote a geometry shader that takes a mesh as input and uses its vertex positions as locations where the patches of grass will be placed (as textured quads).
      For an infinite flat world (not spherical) I'd use the terrain mesh as input to the geometry shader, but I've found that this won't work well on a sphere, since the vertex density is not homogeneous across the surface.
      So the main question would be: How to create a point cloud for each terrain chunk whose points were equally distributed across the chunk?
      Note: I've seen some examples where these points are calculated from intersecting a massive rain of totally random perpendicular rays from above... but I found this solution overkill, to say the least.
      Another related question would be: Is there something better/faster than the geometry shader approach, maybe using compute shaders and instancing?
    • By FedGuard
      Hello all,
       
      I would like to start off with thanking you all for this community. Without fora like these to assist people the already hard journey to making an own game would be exponentially more difficult. Next I would like to apologize for the long post, in advance...
      I am contemplating making a game. There, now that's out of the way, maybe some further details might be handy.
      I am not some youngster (no offence) with dreams of breaking into the industry, I am 38, have a full-time job, a wife, kid and dog so I think I am not even considered indie? However I recently found myself with additional time on my hands and decided I would try my hand at making a game.Why? Well mostly because I would like to contribute something, also because I think I have a project worth making (and of course some extra income wouldn't hurt either to be honest). The first thing I realized was, I have absolutely no relevant skill or experience. Hmm; ok, never mind, we can overcome that, right?
      I have spent a few months "researching",meaning looking at YouTube channels, reading articles and fora. Needless to say, I am more confused now than when I started. I also bought some courses (Blender, Unity, C#) and set out to make my ideas more concrete.
      I quickly discovered, I am definitely not an artist... So I decided, though I do plan to continue learning the art side eventually, I would focus on the design and development phase first. The idea being, if it takes me a year or more solely learning stuff and taking courses without actually working on my game, I would become demoralized and the risk of quitting would increase.
      So I thought I would:
      1: Keep following the courses Unity and C# while starting on the actual game development as the courses and my knowledge progress.
      2: Acquire some artwork to help me get a connection with the game and main character, and have something to helm keep me motivated. (I already did some contacting and realized this will not be cheap...). Also try to have the main character model so I can use it to start testing the initial character and game mechanics. For this I have my first concrete question. I already learned that outsourcing this will easily run up in the high hundreds or thousands of dollars... (lowest offer so far being 220 USD) I am therefore playing with the idea of purchasing https://assetstore.unity.com/packages/3d/animations/medieval-animations-mega-pack-12141 with the intention of then have an artist alter and/or add to the animations (it is for a Roman character so some shield animations are not going to work the same way.). This way I could start  with the basic character mechanics. Is this a good idea, waste of money,...? Any suggestions? I then have a related but separate question. Is it a good idea to buy Playmaker (or some other similar software I haven't yet heard of like RPGAIO), and using this for initial build, then changing/adding code as the need arises?
      3.Get a playable initial level ready as a rough demo and then starting to look for artist for level design and character/prop creation.
      ...
       
      I would really appreciate some input from more experienced people, and especially answers to my questions. Of course any advice is extremely welcome.
    • By william.equal
      Hey, I just finished a new episode of "Game Audio Lookout"! This time it's about musical sound effects in the Super Mario series. Here's the link to the video on YouTube:
      --
      Musical Sound Effects in the Super Mario Series | Game Audio Lookout
      https://www.youtube.com/watch?v=6hHbTVloizU
      We’ll have a deeper look at musical sound effects in the Super Mario series in this episode of "Game Audio Lookout".
      I guess everybody has heard the sounds of the Super Mario series before. But I believe most of us don’t exactly know how these were constructed and what efforts were taken in later instalments of the series to produce sound effects that even harmonise with the game’s music.
      --
      Feel free to let me know what you think
      Alex
    • By Jordan Winslow
      Hey guys, my name is Jordan Winslow and I am a professional electronic music producer & composer who also happens to be a talented story writer and has a ton of experience with VNMaker, Tyrannobuilder, Renpy, and RPG Maker tools and I am looking for talented artists who want to make a horror game together!
      Last Horror Project I Composed Music For: 
       
      My last game I created: "The Watchers"  https://jordanwinslow.itch.io/the-watchers
      My Music: https://jordanwinslow.me/showcase
      I am open to plot ideas but, based on your artwork, I would like to create an original story that matches our music and art so we can play on both of our strengths. Up until now I have only been able to create visual novels with the use of stock photography and stock videos, but with the use of original art, we should be able to come up with a story that is far more specific to the art on screen.
      My favorite horror games (For reference)
      Saya no Uta (Horror Visual Novel Originally in Japanese)
      The Crooked Man 
      SOMA
      Corpse Party
       
      I have a few pretty awesome ideas for sci-fi or extra-dimensional horror games, I also know of a great real-life story about aliens we could make a game about and I could easily come up with something new if I am inspired by your art!
       
      So let's create something awesome together! Send me a message along with some examples of your art and we will either create a team of multiple people together or just the two of us if you are capable of coming up with a decent amount of original artwork! I've got the music, the story and the programming handled unless you want to do the programming and help with the story.
    • By Sergio Ronchetti
      Continuing to work on “Eldest Souls” (first article here!), I’ve begun familiarising myself with the workflow between Fmod and Unity, and the integration system. I know much of this will be pretty obvious to most, but I thought I’d share my thoughts as a complete beginner learning the ropes of sound designing. 
      The library of sounds that Fmod provides has been very useful, at least as reference points. I’ve still kept to my ethos of producing the sounds myself as much as possible. Having said that, Fmod gives you 50 free sounds with your download, and I’ve used a wooden crate smash, a drawbridge and electricity sound you can hear in the foley video below.
       
       
      The thing i found most useful was witnessing changes i made in Fmod being realised instantly in Unity. If a volume needed changing, or the timing of one of my effects was off, i can literally switch to Fmod and then back to Unity and immediately see the result of my alterations. It also seems apparent that using middleware such as this (or i've heard Wwise is also equally intuitive) grants the developer, and myself included, a great deal more flexibility and opportunity to edit sounds without going all the way back to a DAW, and bouncing down again. Needless to say, my workflow is so much faster because of it.
      I've also loved the randomised feature of Fmod, whereby any sound can be made to sound slightly different each time it is heard. Taking a footstep recording i made for example, I was able to add further authenticity of uneven footsteps by randomising the pitch and volume of each playback. 
       

       
      I used this technique when creating footsteps for the first major boss in the game called "The Guardian". A big, over-encumbered husk of a monster. I also had fun rummaging through the garage for old tools and metal components for the “Guardian” (the first boss) footsteps. See below!
       
       
      I also created a sword attack for our player, trying to sound different from the generic “woosh” I see in so many video games. I used a very “sharp” and abrasive sound to differentiate him from any enemies.
       
       
      On another note, I recently upgraded my microphone to a Rode NTG2 shotgun, which has been phenomenal. I haven’t had to worry about noise interfering with the clarity of my objects, whereas before with the sm58 I had to be clever with my EQ and noise reduction plugins.
      Important to note again that this still a “cheap” mic in comparison to most other products on the market, and all in all my entire setup is still very simple and affordable which I’m quite proud of. I’ve seen many musicians spend heaps of money on gear they don’t necessarily need. I much prefer being resourceful with less equipment, than to have more than I can understand or remember how to use.
      It’s forced me to understand every aspect and capability of my tools, which I believe is a principal that can be applied to any discipline.
       
      I have more fun little sound effect videos on my Instagram for those interested, where I post regular updates. Thanks for reading! (if you’ve made it this far)
       
      www.sergioronchetti.com
      INSTAGRAM
      fallenflagstudio.com
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!