Archive

Posts Tagged ‘rendering’

May Have Been Driven Mad By Sparkles.

January 18th, 2010 Snut No comments

Source: The Oblong



OK, I deliberately pushed the particles way into HDR territory to get the bloom filter to explode. And there are too many particles to start with, this was supposed to be a collection of gently background fluff (fireflies, dust, magical plankton... that kinda thing).

I was playing with the property browser thing for the particle material and accidentally changed the wrong digit in a colour (0.9 -> 9.9, easy enough to do). At this point I think a bit of my mind snapped, so here we have CRAZY sparkles, whirling in madness.

Those not blinded by sparkles may note that the player now has a trail of arrows, showing the last ten moves. Although the final intention is to display only the actions of the current turn (thanks Jotaf! This idea is really growing on me), a possible extension to display a limited action history may also be useful. It might help in making the AI behaviour more transparent to the player, or maybe just as a hint as to where an entity might be if it dives out of line-of-sight.

::tap-tap:: Is this thing still on?

December 22nd, 2009 Snut No comments

Source: The Oblong

Oh! Hi there.

Amazingly, I have been working on this little project. It's been slow going.



The rendering system has been refactored considerably. It is very much still a nasty mass of imperative wrongness, but its also a bit more consistent and less fragile. I've been experimenting with different methods of generating the world geometry. I've tried half a dozen implementations of a game-entity framework, none of which seemed adequate. I added a quick random map generator (screenshot taken from one such random map), and worked on the water shader a little. It looks OK in motion, but definitely needs to be somewhat more obvious generally. Those little divots in the ground are shallow water, the light source being the player (who's mesh has temporarily elected to disappear).

Oh, and I gave Clojure a spin too. Experimenting with the property-bag approach in a Lisp is relatively joyous, especially with Clojure's explicit syntax for hash maps. I found it hard to scale projects up, though. I'm too used to arranging things in terms of objects and classes, both Haskell and Clojure befuddle me with a mass of functions. My failing entirely, the languages have much to recommend them.

I started using Mercurial SCM for source control on this little project. Although I do find myself wanting a P4Win-like GUI front end (which may well exist somewhere), the command-line tools are quite lovely and I refuse to give up on them before becoming at least somewhat proficient.


Now for some design babble. This idea surfaced recently when trying out a few entity and time-handling systems, and I think has some interesting gameplay connotations. Here's the gist:

  • Every turn, collect actions from all agents in the game world

  • Execute all actions, regardless of validity, to produce a new world state. Each agent also tracks the actions that changed it this turn.

  • Resolve the world state by resolving invalid conditions


The third step is obviously the tricky one, but also where the most interesting aspects spring from. The first two steps merely simplify some aspects of mutating the game world.

So this tricky 'resolve' stage... what happens here? Well, take a very simple set of verbs: agents can either stand still, or move one space each turn. More than one agent occupying a space is invalid. If two agents occupy the same space, do some basic conflict resolution and then generate a valid world state based on that. The losing agent could be displaced back to its original position (and also presumably lose some health, in a standard Roguelike game of HP and damage rolls...), whilst the winner occupies the contested space. In the case of a tie, both agents are returned to their starting positions. An agent who didn't move in this turn gets some manner of defensive bonus, but if it loses the conflict will be displaced away from the attacker.

There are immediate problems with this simple method. What happens if another agent occupies the starting position of the losing agent in a conflict? How do we handle three or more agents in a space? What about an agent surrounded by enemy agents, such that no position is valid after losing? Conflict in dead end corridors?

Some embellishments to the system should allow most of these to be resolved. For example, agents could be in a standing or prone state, and not occupy any space when prone. Losing agents with no valid moves can be knocked prone. And so on.

But what do we gain from this approach?
  • Most interestingly, this represents a gateway to yomi, as described in the linked post. As every action is essentially simultaneous, a suitable number of counter moves and counter-counter moves allow for much greater potential depth in conflict. There aren't enough in the simple example above, but it at least admits the possibility. In order to be really satisfying, either the AI behaviour needs to be tractable for the player, or multiplayer might be considered.

  • Strategic positioning - this is a big part of what I'd like to capture in combat. Being able to 'bull rush' opponents is crucial; several character development options suggest themselves to allow more tactical control over the way a battle evolves. This feels a lot easier to approach when all potential movement is handled in a single step.

  • I think this system is less predictable. As everything happens at once, actions are more likely to fail and rather harder to evaluate. Rather than just considering the success chance of a given action, the player must consider all the possible actions of relevant agents that could interfere with its execution. This is a good thing in general.


And what is lost...
  • Agents all move at a uniform speed, or at integer multiples of that speed. We lose the fine-grained ordering of agents based on some intrinsic properties and/or the execution time of actions. All actions take one turn. We can allow for slower agents by forcing them to take null actions except every N turns. In theory we can also allow faster agents by slowing down the rest of the world in much the same way, but that seems inelegant - as many actions will require a graphical representation and time to be displayed, doing this will slow the game for the player.

  • The system is less predictable. Players can no longer easily guess the outcome of an action, as it depends on the actions taken by other agents in the same turn. This could be a bad thing for transparency.


It needs more thought, and the implementation details could get very messy for the semi-mystical 'fix the world' step.

Even more deferred tentacles

September 8th, 2008 Snut No comments

Source: The Oblong

Just a quicky today.

These are lighting-only shots showing the same scene with and without screen-space ambient occlusion, the latest hacktastic post process to take the rendering world by storm. Unfortunately I have to concede that even my less than stellar implementation does add a lot to the rendering, for a moderate cost, so I guess I'll be jumping on the bandwagon. It's an especially useful technique when combined with deferred lighting, as attempting any real shadowing with a bucketload of small point lights is very bonkers, so the illusion that the faked ambient occlusion provides is doubly useful.

As an aside, I do like my dungeon fairy lights. They add such a nice ambience...

Before (no SSAO):



After (mit SSAO):

Deferred Tentacles

September 5th, 2008 Snut No comments

Source: The Oblong

Further work on the deferred rendering side. I finally found an example online using FBOs with a stencil buffer, and thereby discovered that despite using a combined depth-stencil renderbuffer it needs to be attached to the frame buffer object twice, once as a depth attachment and once as a stencil attachment. Sigh.

That done, efficient rendering of small lights via z-and-stencil-tested spheres works nicely!

Behold the scene, containing no less than fifty ickle lights, plus the large shadow-casting light from the player's avatar.


The majority of the screen is taken up by the final composite image. On the right, small sections show a sample of the buffers involved (yes, I don't even turn off my debugging chuffle before posting, I'm that lazy). Top is the SSAO term (very low intensity in the final image, as it looks pants). Below that are the lighting accumulation buffer, world-space normal, and finally unlit diffuse buffers.

Lastly, the image displays some filthy aliasing as the source render targets are only 512x512, violently scaled up to match the screen resolution. I should fix that.

Edit: here's a version using 1024x768 buffers throughout. Ouch, bye-bye framerate. Need to fix my absurd pixel shader usage methinks.

Hordes

September 2nd, 2008 Snut No comments

Source: The Oblong


Nothing important today, just been sounding out the pitfalls and quicksand that abound in OpenGL. This time it's so-called 'pseudo-instancing', providing more or less the equivalent of DX9's SetStreamSourceFreq-style instancing for geometry. I'm testing it with the anemone mesh, because I still have yet to get around to authoring more models. I'm lazy and emacs is more friendly than Blender.

Technical sorta-details: a position/scale and quaternion rotation are stuffed in a couple of spare texture coordinates using OpenGL's immediate mode, on a per instance basis. It's a bit of extra mucking about but seems viable in terms of performance. A per-instance colour should round out the system for maximum variation at a small overhead.

I think I'll be using this a lot for semi-dynamic clutter - rocks, vegetation, refuse and the like. Static objects will probably benefit more from being baked into world space in large batches, assuming memory is not a concern, but smaller things may need to be moved or animated.

Visual fluffs

August 27th, 2008 Snut No comments

Source: The Oblong


As my other post is waffly and dull, I thought I'd post some equally dull screenshots.

First, we have soft shadows and a general framerate improvement. I found I wasn't using buffer objects for my mesh streams (bad!), switched to position-only streams for shadow rendering when possible and changed the shadow buffer format to rgba16f. All this has reduced the frame time hugely, even after I started adding more crazy stuff. For comparison, a similar scene with blurred shadows was previously in the single-figure frame rate. Ouch. Still vastly too slow at the moment of course, but moving in the correct direction.

The soft shadows are done with a simple 3x3 guassian blur over the cube. It has errors on the cube edges for some reason, as can be seen in the nice black line across the lower right quarter of the image, but even with fairly low res maps and a small kernel the reduction in aliasing makes things look nicer. Hooray!


The second screenshot shows a half-finished unsmoothed SSAO post process. It's using a deferred rendering setup, with a few render targets for diffuse, normal, depth and lighting information at the moment, although for this screenshot only the depth info is used of course. Lots to do here, and I'd like to get a scene with more interesting visual fluff to show off the AO effect better...

Anyway, hopefully that helped balance up the wordiness of the previous post.

Baby Steps

August 15th, 2008 Snut No comments

Source: The Oblong


No big changes, but:
  • Hex floor generation cleaned up
  • Block-edge normals much less broken
  • Mipmap brokenness caused by discontinuous texture coordinates fixed
  • Shadow res bumped up (shadows are currently a huge rendering bottleneck, hence terrible frame rate)
  • Shadow acne removed with a teeny epsilon
The mipmap fixes have also introduced a LoD bias, but I quite like the way it looks. Textures do repeat too much at this scale though, and there's little to break up the tiling. Will be looking at potential fixes for this soon.

My big low-res chasm-filling geometry seems to have wandered off as well, not sure why. Eh, it'll come back when it's hungry...

Monsterous

August 7th, 2008 Snut No comments

Source: The Oblong

Many bugs to fix, but instead of fixing 'em I've been dithering between the best way to represent my world using immutable state (I suspect monads may be involved, and these horrors just won't fit in my brain) and... getting a model in game!

In this case, a very crappy monster has made the long and torturous transition from Blender to screen. Behold, the Cave Anemone (the five-tentacled starfish thingy):


It even casts shadows! Doesn't receive them yet, and frankly it needs better normal and diffuse textures than a few minutes in the GIMP can supply.

The screenshot also highlights the evil problems with normals at block boundaries (witness the horizontal and vertical smears visible to the left of the brave @dventurer) and the general horror that are the shadows. If you look closely, you can even see the wonderful mipmapping errors introduced by the sub-textures on the floor.

First goal will be to slap some more meshes in there, even if they're placeholders. I want one other monster type (Tentacle Mouse?), at least one inventory item and a player model. This will be enough to finally dispose of the glowing unlit spheres and @ model, and give a better clue as to scale issues.

Hexy texture madness

July 30th, 2008 Snut No comments

Source: The Oblong



Testing out the sub-texture stuff with normal maps and shadows. Right hand images apply textures on a per-hex basis, whereas the others just have random perlin smeariness.

Interpolation between hexes is still enborkinated, so the hex edges display some very rough geometry and there're no smooth variations. Also, the ugliness of the shadows is getting to me...