Showing posts with label Game development. Show all posts
Showing posts with label Game development. Show all posts

Thursday, March 5, 2015

3D: film gimmick, gaming fantasy?

Occasionally I remember a conversation I had about games in which, on discussing how I'd tried out 3D glasses (imagine the old red/blue things) with some games, I was told "3D can stay the f*** out of my games. I was taken aback at the time, and it still seems odd to me now; enough that I've mulled it over sufficiently to want to rant about it.

It's popular these days to either love or hate 3D; however, I think that to do either of these things for all 3D media is misguided.

I can think of some compelling arguments for why 3D simply isn't a good fit for a lot of cinema. Much media has gotten used to being presented from one direction; cinematography and TV is filled with scenes where everything is essentially occurring well away from the camera (in TV shows, especially live ones, this is so prominent that I'd argue this is a significant reason for the relative lack of 3DTV adoption). Additionally, depth isn't a hugely important dimension in storytelling in most films.

As the technology becomes more familiar, I think this will change to some extent. Watching Lindy Beige (not necessarily a film expert, but he is a persuasive talker) in his video on the introduction of 48 fps (particularly his point near the end about zooming techniques), it seems to me that cinematography techniques will always take some time to adapt to new technology. By extension, I think cinema can adapt to 3D... When it feels it necessary. After all, there are numerous theatrical styles, but there are not all adopted all of the time.

The goal behind 3D, in my opinion, is to draw the viewer into the experience. If you were to think of this in theatrical terms it would similar to invisible theater, which brings the action right in front of you. It must be spectacularly difficult to produce a story that is spatially distinct, which you can navigate and interact with; however, games take such an idea and allow you to experience it at your leisure.

In most games, you become an actor in the theater. It thus makes sense to me that if you are an actor in the story then this story should be occurring all around you. What's more, gamers have had the freedom of exploring their game worlds in 3 dimensions (albeit via the 2D of their screens) for years, and while I think 3D is going to take time to mature in the cinema, games developers have been thinking in 3D constantly for years now. Even some existing games would work spectacularly well.

Yes, there will need to be adaptations, but mostly nothing that wasn't already on the to-do list: more detailed actors and props, better physics implementations, and more attention to details such as the placement of actors during important plot points (For example, in Skyrim you may sometimes find other actors or props obscuring your view of someone you're in conversation with). Very few things need to change in games that would be unnecessary if 3D didn't exist.

So, I still disagree that 3D screens/goggles are in any way bad for games. Luckily for those who think otherwise, implementing such technology requires almost no changes to the mechanics of a game, so we both get what we want.

But anyway, give it another 5 years, and no one will want to consume 3D games on a 2D screen any more.

Friday, April 26, 2013

Atmospheric effects in openGL

And now for some programming...

Long story short:

Here is a technique for drawing an atmosphere, which is especially useful if you want something that is quick but you're not planning on the camera moving around. Enjoy.




Anyway, some considerable time ago I wrote about making the world in 7 days using openGL and java. Of course, in reality, I'd only synthesised a tiny region, not even the size of an English county... What I'd really love is to have a whole planet to look down on.

Actually, this is a much, much simpler task, so long as you don't want to visit anywhere on the surface, as from 300km up, everything looks flat anyway (approximately).

The real trick to making a planet look lovely is the atmosphere (and bump mapping*).

Lately I've been using libGDX for my graphical work (I'm a softy for portability, and when I adopted it, it was probably the most portable graphics library around), but hopefully what I attempt here will be fairly universal.

The basic layout for me is like this:

1)Earth = sphere with earth texture in centre of screen
2)Starmap = sphere centred on camera with star texture
3)Clouds = sphere surrounding earth with cloud texture
4)Atmosphere = cone extending from the horizon of sphere (1) to behind the camera

And now for a pretty diagram:

... What can I say... I'm a biologist.

Long story short, the key is to have the cone completely transparent, but draw it with fog. You end up with something that looks a bit like this:



Which is (I think) a reasonable approximation of Earth from ~300 km up. OK, so this is a bit hacky, but it is really quick and conceptually simple**.

If you want more detail, here are the components in more detail:

1)Earth

Since I personally never plan to leave orbit, instead of using a sphere, I've cheated and used a convex shape to reduce the number of triangles rendered. Thus, instead of having a sphere rotating, I've had to move the texture coordinates instead. But honestly, that is simple enough. It also means that I don't need to have the whole earth texture loaded into memory, I only have a thin strip for a texture that corresponds to the area over which the viewpoint travels, assuming that I always pass the same terrain***.

I use a night (city lights) texture too, which is only visible when the sun starts sinking below the horizon.

2)Starmap

You can't see it so well in the screenshot, but at night I make the stars more vivid by increasing the brightness. The stars are another NASA freebie (I love NASA). There's not much else to say here

3)Clouds

Just a png texture of clouds mapped onto another convex shape with a slightly different speed of rotation, so that the same area isn't always covered by the same clouds.

4)Atmosphere

As mentioned earlier, the atmosphere is just a transparent cone that extends from behind the camera to the horizon. To make it appear as the atmosphere all you do is enable fog, then draw the cone. Finally, you draw the planet in front of all that.

The density of the atmosphere can be changed by modifying the opengl fog density/fog start parameters.

If I recall correctly, the draw order was important: stars, then atmosphere cone, then planet.

Of course there are major caveats with this method:
1) if the camera moves relative to the planet, the cone has to distort accordingly
2) if the camera moves, the fog density/fog start parameters must be adapted otherwise the atmosphere will appear to grow as you move away from the planet

Which is one reason why I haven't bothered allowing the camera to move! But it makes a lovely background ;)


*Sorry, I won't be discussing bump mapping as I don't use it yet. I have reasons for this, but I advise that you use bump mapping if you can, because it looks great! But anyway, bump mapping is a fairly standard practice nowadays (here's what google thinks is the best site on the matter, but because I'm too busy to see if it actually is, here is what it thinks is the second best site on the matter. In the very least I've used NeHe's site before, and liked it...)

**Bearing in mind this is all designed to run on mobile phones...

***Yes, I've cheated and have my viewpoint make the impossible orbit along a constant longitude in the Northern hemisphere. I should have put the orbit around the equator. Sorry about that. I like the Northern hemisphere.

Thursday, January 6, 2011

Making the world in 7 days?: An experience with JOGL

Last year I started learning Java, and had a lot of fun using its 2D graphics to procedurally generate a cartoon seal. Eventually I came across JOGL, a wrapper for OpenGL in Java. Its been a while since I did any serious 3D graphics programming, so I thought I'd see how easy it would be to program a 3D game in Java, and how well java would cope.

I started out making a grid comprised of regions, each subdivided into areas, further subdivided into terrain squares. I then made (a very inefficient) world generation class to iterate through all these terrain squares and assign them a different height (basically, I shove a load of sine waves onto the landscape with varying amplitudes, it looks very silly until the sine waves start overlapping, then the interactions between the sine waves start to produce something approaching believable.

Next came lighting, and I remembered (horror of horrors) that you need to specify normals at each vertex of the terrain, which is done by averaging the surface normals of all the quads surrounding a terrain vertex. Nonetheless, by the end of day one, I had a lit, hilly landscape. Albeit a blue one.


Most of day 2 was spent trying to find a simple way of adding terrain textures, it turns out that there is a very simple way, and I'm glad I took the time out to find it:


Texture tex ;
tex = TextureIO.newTexture(new File("Ground.png"), true);
tex.enable();
tex.bind();


Of course, I'm going to have to move this out of the init() function when I want to use more than one texture... But in any case it works. Finally, I added culling so any regions outside of the viewport aren't drawn, cutting down on rendering times. By the end of the second day, then, it was looking like this:



Remember I'm using a subdivided system of regions, areas and the rendered terrain squares. To further optimise, I added an algorithm to give the corner of each area its own vertex, and I moved the height of these vertices to match the height of the nearest terrain vertex. In effect I had created a low detail version of the rendered terrain. Then all that was required was to render the more detailed terrain closer to the camera, and render the less detailed areas further from the camera, reducing the number of triangles rendered overall. This effectively allowed me to greatly expand the size of the terrain, and still have it render at reasonable speed. Finally I added fog, which didn't take me too long at all, to get something looking a little more atmospheric:


Well... When I say atmospheric, perhaps depressing is a better word... To inject some new life into the world, I spent the 4th day adding the skybox (actually I spent most of the day adding model support). This is basically a textured sphere that I flattened into a pancake (not the most efficient method, but very quick), this way the fog doesn't obscure the sky above, but fades seamlessly into the sky. I also added a blue tint to the fog so it looks more like haze on a cloudless day than miserable English fog..



You might notice the sky has pixelation on a geographic scale, this is due to the fact I still haven't actually added support for multiple textures.. Yes, that's right, its the ground texture coloured blue!

So... 4 days into the creation, and just about everything is in place. Now I've hacked out the majority of the model loading code, vibrant tree'd (even inhabited) landscapes can't be far away...

To conclude... I've basically done this before in DirectX many years ago, but I'm quite impressed with how JOGL handles everything. Its a little more difficult for me to get my head around managing resources like models and images (something that DirectX manages quite well on its own), but performance wise its working like a charm, and creating it on my netbook has been very pleasing. Its the added portability of Java is the icing on the cake for me though, and I had my fledgling program running on linux with no troubles at all.